Render buildings and resources

- create LuaJsonList to handle empty Lua JSON lists being sent as empty objects
- fix exporting of resources and entities
- split up map tiles into different layer directories
- add 'chunk size' to MapChunkPosition
- move tests to correct packages
- bump tstl
- decrease tstl logging
- remove some defined, but unused, kafka topics
- syslog, rest, websocket servers & web-map: decrease logging
- webmap: add additional layers for buildings and resources
This commit is contained in:
Adam 2022-07-16 23:10:32 +02:00
parent a805d2ad63
commit b507081eac
72 changed files with 2167 additions and 1068 deletions

View file

@ -68,7 +68,11 @@ dependencies {
val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) {
dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson)
dependsOn(
tasks.npmInstall,
installEventsTsSchema,
tasks.updatePackageJson,
)
inputs.file(tasks.updatePackageJson.map { it.packageJsonFile })

View file

@ -85,9 +85,9 @@
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ=="
},
"typescript-to-lua": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.2.tgz",
"integrity": "sha512-m0TZ2RqL6BPy3/TNIjbVDTr9N6M45Qyb2/VJpBz0qnS3zTXxhAOugc+PaILSVwvCb1vent8ateWDt2fcEtcsRw==",
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz",
"integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==",
"requires": {
"enhanced-resolve": "^5.8.2",
"resolve": "^1.15.1",

View file

@ -12,7 +12,7 @@
"devDependencies": {},
"dependencies": {
"lua-types": "^2.11.0",
"typescript-to-lua": "1.6.2",
"typescript-to-lua": "1.6.3",
"typed-factorio": "1.3.2",
"typescript": "4.7.4"
},

View file

@ -10,6 +10,7 @@ do
KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate"
KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate"
KafkatorioPacketData.Type.MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate"
KafkatorioPacketData.Type.MapChunkResourceUpdate = "kafkatorio.packet.keyed.MapChunkResourceUpdate"
KafkatorioPacketData.Type.MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate"
KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate"
KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error"
@ -21,57 +22,12 @@ do
FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity"
FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile"
end
____exports.FactorioEntityData = {}
local FactorioEntityData = ____exports.FactorioEntityData
do
FactorioEntityData.Type = Type or ({})
FactorioEntityData.Type.Resource = "kafkatorio.entity.FactorioEntityData.Resource"
FactorioEntityData.Type.Standard = "kafkatorio.entity.FactorioEntityData.Standard"
end
____exports.EntityStatus = EntityStatus or ({})
____exports.EntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS"
____exports.EntityStatus.CHARGING = "CHARGING"
____exports.EntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK"
____exports.EntityStatus.DISABLED = "DISABLED"
____exports.EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR"
____exports.EntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT"
____exports.EntityStatus.DISCHARGING = "DISCHARGING"
____exports.EntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE"
____exports.EntityStatus.FULLY_CHARGED = "FULLY_CHARGED"
____exports.EntityStatus.FULL_OUTPUT = "FULL_OUTPUT"
____exports.EntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE"
____exports.EntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET"
____exports.EntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID"
____exports.EntityStatus.LOW_POWER = "LOW_POWER"
____exports.EntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE"
____exports.EntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION"
____exports.EntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID"
____exports.EntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS"
____exports.EntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED"
____exports.EntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED"
____exports.EntityStatus.NORMAL = "NORMAL"
____exports.EntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL"
____exports.EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK"
____exports.EntityStatus.NO_AMMO = "NO_AMMO"
____exports.EntityStatus.NO_FUEL = "NO_FUEL"
____exports.EntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS"
____exports.EntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID"
____exports.EntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES"
____exports.EntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT"
____exports.EntityStatus.NO_POWER = "NO_POWER"
____exports.EntityStatus.NO_RECIPE = "NO_RECIPE"
____exports.EntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS"
____exports.EntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK"
____exports.EntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK"
____exports.EntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH"
____exports.EntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE"
____exports.EntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME"
____exports.EntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS"
____exports.EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION"
____exports.EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT"
____exports.EntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN"
____exports.EntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET"
____exports.EntityStatus.WORKING = "WORKING"
____exports.ChunkSize = ChunkSize or ({})
____exports.ChunkSize.CHUNK_512 = "CHUNK_512"
____exports.ChunkSize.CHUNK_256 = "CHUNK_256"
____exports.ChunkSize.CHUNK_128 = "CHUNK_128"
____exports.ChunkSize.CHUNK_064 = "CHUNK_064"
____exports.ChunkSize.CHUNK_032 = "CHUNK_032"
____exports.MinedProduct = {}
local MinedProduct = ____exports.MinedProduct
do
@ -79,4 +35,48 @@ do
MinedProduct.Type.MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid"
MinedProduct.Type.MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem"
end
____exports.FactorioEntityStatus = FactorioEntityStatus or ({})
____exports.FactorioEntityStatus.WORKING = "WORKING"
____exports.FactorioEntityStatus.NORMAL = "NORMAL"
____exports.FactorioEntityStatus.NO_POWER = "NO_POWER"
____exports.FactorioEntityStatus.LOW_POWER = "LOW_POWER"
____exports.FactorioEntityStatus.NO_FUEL = "NO_FUEL"
____exports.FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR"
____exports.FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK"
____exports.FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK"
____exports.FactorioEntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT"
____exports.FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION"
____exports.FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK"
____exports.FactorioEntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED"
____exports.FactorioEntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED"
____exports.FactorioEntityStatus.CHARGING = "CHARGING"
____exports.FactorioEntityStatus.DISCHARGING = "DISCHARGING"
____exports.FactorioEntityStatus.FULLY_CHARGED = "FULLY_CHARGED"
____exports.FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK"
____exports.FactorioEntityStatus.NO_RECIPE = "NO_RECIPE"
____exports.FactorioEntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS"
____exports.FactorioEntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID"
____exports.FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS"
____exports.FactorioEntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES"
____exports.FactorioEntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID"
____exports.FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE"
____exports.FactorioEntityStatus.FULL_OUTPUT = "FULL_OUTPUT"
____exports.FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE"
____exports.FactorioEntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID"
____exports.FactorioEntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS"
____exports.FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS"
____exports.FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION"
____exports.FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH"
____exports.FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET"
____exports.FactorioEntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET"
____exports.FactorioEntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT"
____exports.FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE"
____exports.FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT"
____exports.FactorioEntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN"
____exports.FactorioEntityStatus.NO_AMMO = "NO_AMMO"
____exports.FactorioEntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE"
____exports.FactorioEntityStatus.DISABLED = "DISABLED"
____exports.FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME"
____exports.FactorioEntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL"
____exports.FactorioEntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS"
return ____exports

View file

@ -7,8 +7,8 @@ local ____global_2Dinit = require("main.global-init")
local initGlobal = ____global_2Dinit.initGlobal
local ____prototypeUpdates = require("main.events.prototypeUpdates")
local emitPrototypes = ____prototypeUpdates.emitPrototypes
local ____queue = require("main.queue.queue")
local EventDataQueue = ____queue.default
local ____EventDataQueue = require("main.emitting.EventDataQueue")
local EventDataQueue = ____EventDataQueue.default
commands.add_command(
"kafkatorio",
"kafkatorio innit bruv",

View file

@ -3,6 +3,10 @@ local __TS__Class = ____lualib.__TS__Class
local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
local __TS__New = ____lualib.__TS__New
local ____exports = {}
--- Simple ordered queue for {@link KafkatorioPacketData}.
--
-- Implemented so printing multiple packets won't flood the output log, causing messages to be
-- missed or garbled.
____exports.KafkatorioPacketQueueManager = __TS__Class()
local KafkatorioPacketQueueManager = ____exports.KafkatorioPacketQueueManager
KafkatorioPacketQueueManager.name = "KafkatorioPacketQueueManager"

View file

@ -1,19 +1,12 @@
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local EntityStatus = ____kafkatorio_2Dschema.EntityStatus
local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
local ChunkSize = ____kafkatorio_2Dschema.ChunkSize
local FactorioEntityStatus = ____kafkatorio_2Dschema.FactorioEntityStatus
local MinedProduct = ____kafkatorio_2Dschema.MinedProduct
____exports.Converters = {}
local Converters = ____exports.Converters
do
local convertEntityStatus, EntityStatusRecord
function convertEntityStatus(status)
if status == nil then
return nil
else
return EntityStatusRecord[status]
end
end
local EntityStatusRecord
function Converters.prototypeId(____type, name)
return (____type .. "/") .. name
end
@ -42,9 +35,6 @@ do
end
return converted
end
function Converters.convertMapTablePosition(position)
return {position.x, position.y}
end
function Converters.convertCollisionMaskToNames(cm)
local masks = {}
for name in pairs(cm) do
@ -56,14 +46,14 @@ do
if entity.type ~= "resource" then
return nil
else
return {
type = FactorioEntityData.Type.Resource,
protoId = Converters.prototypeId(entity.type, entity.name),
status = convertEntityStatus(entity.status),
amount = entity.amount,
initialAmount = entity.initial_amount,
position = Converters.convertMapTablePosition(entity.position)
}
return {amount = entity.amount, initialAmount = entity.initial_amount}
end
end
local function convertEntityStatus(status)
if status == nil then
return nil
else
return EntityStatusRecord[status]
end
end
function Converters.prototypeIdEntity(entity)
@ -72,15 +62,23 @@ do
function Converters.tilePositionToChunkPosition(mapPosition)
return {
floor(mapPosition.x / 32),
floor(mapPosition.y)
floor(mapPosition.y / 32),
ChunkSize.CHUNK_032
}
end
function Converters.mapPositionToChunkPosition(mapPosition)
return {
floor(mapPosition.x / 32),
floor(mapPosition.y)
floor(mapPosition.y / 32),
ChunkSize.CHUNK_032
}
end
function Converters.entityPosition(position)
return {position.x, position.y}
end
function Converters.chunkPosition(position)
return {position.x, position.y, ChunkSize.CHUNK_032}
end
function Converters.entityStatus(status)
if status == nil then
return nil
@ -116,50 +114,56 @@ do
data.afkTime = player.afk_time
data.isConnected = player.connected
end
function Converters.collisionBox(collision_box)
return {
leftTop = ____exports.Converters.entityPosition(collision_box.left_top),
rightBottom = ____exports.Converters.entityPosition(collision_box.right_bottom)
}
end
EntityStatusRecord = {
[defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS,
[defines.entity_status.charging] = EntityStatus.CHARGING,
[defines.entity_status.closed_by_circuit_network] = EntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
[defines.entity_status.disabled] = EntityStatus.DISABLED,
[defines.entity_status.disabled_by_control_behavior] = EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
[defines.entity_status.disabled_by_script] = EntityStatus.DISABLED_BY_SCRIPT,
[defines.entity_status.discharging] = EntityStatus.DISCHARGING,
[defines.entity_status.fluid_ingredient_shortage] = EntityStatus.FLUID_INGREDIENT_SHORTAGE,
[defines.entity_status.fully_charged] = EntityStatus.FULLY_CHARGED,
[defines.entity_status.full_output] = EntityStatus.FULL_OUTPUT,
[defines.entity_status.item_ingredient_shortage] = EntityStatus.ITEM_INGREDIENT_SHORTAGE,
[defines.entity_status.launching_rocket] = EntityStatus.LAUNCHING_ROCKET,
[defines.entity_status.low_input_fluid] = EntityStatus.LOW_INPUT_FLUID,
[defines.entity_status.low_power] = EntityStatus.LOW_POWER,
[defines.entity_status.low_temperature] = EntityStatus.LOW_TEMPERATURE,
[defines.entity_status.marked_for_deconstruction] = EntityStatus.MARKED_FOR_DECONSTRUCTION,
[defines.entity_status.missing_required_fluid] = EntityStatus.MISSING_REQUIRED_FLUID,
[defines.entity_status.missing_science_packs] = EntityStatus.MISSING_SCIENCE_PACKS,
[defines.entity_status.networks_connected] = EntityStatus.NETWORKS_CONNECTED,
[defines.entity_status.networks_disconnected] = EntityStatus.NETWORKS_DISCONNECTED,
[defines.entity_status.normal] = EntityStatus.NORMAL,
[defines.entity_status.not_connected_to_rail] = EntityStatus.NOT_CONNECTED_TO_RAIL,
[defines.entity_status.not_plugged_in_electric_network] = EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
[defines.entity_status.no_ammo] = EntityStatus.NO_AMMO,
[defines.entity_status.no_fuel] = EntityStatus.NO_FUEL,
[defines.entity_status.no_ingredients] = EntityStatus.NO_INGREDIENTS,
[defines.entity_status.no_input_fluid] = EntityStatus.NO_INPUT_FLUID,
[defines.entity_status.no_minable_resources] = EntityStatus.NO_MINABLE_RESOURCES,
[defines.entity_status.no_modules_to_transmit] = EntityStatus.NO_MODULES_TO_TRANSMIT,
[defines.entity_status.no_power] = EntityStatus.NO_POWER,
[defines.entity_status.no_recipe] = EntityStatus.NO_RECIPE,
[defines.entity_status.no_research_in_progress] = EntityStatus.NO_RESEARCH_IN_PROGRESS,
[defines.entity_status.opened_by_circuit_network] = EntityStatus.OPENED_BY_CIRCUIT_NETWORK,
[defines.entity_status.out_of_logistic_network] = EntityStatus.OUT_OF_LOGISTIC_NETWORK,
[defines.entity_status.preparing_rocket_for_launch] = EntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
[defines.entity_status.recharging_after_power_outage] = EntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
[defines.entity_status.turned_off_during_daytime] = EntityStatus.TURNED_OFF_DURING_DAYTIME,
[defines.entity_status.waiting_for_source_items] = EntityStatus.WAITING_FOR_SOURCE_ITEMS,
[defines.entity_status.waiting_for_space_in_destination] = EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
[defines.entity_status.waiting_for_target_to_be_built] = EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
[defines.entity_status.waiting_for_train] = EntityStatus.WAITING_FOR_TRAIN,
[defines.entity_status.waiting_to_launch_rocket] = EntityStatus.WAITING_TO_LAUNCH_ROCKET,
[defines.entity_status.working] = EntityStatus.WORKING
[defines.entity_status.cant_divide_segments] = FactorioEntityStatus.CANT_DIVIDE_SEGMENTS,
[defines.entity_status.charging] = FactorioEntityStatus.CHARGING,
[defines.entity_status.closed_by_circuit_network] = FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
[defines.entity_status.disabled] = FactorioEntityStatus.DISABLED,
[defines.entity_status.disabled_by_control_behavior] = FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
[defines.entity_status.disabled_by_script] = FactorioEntityStatus.DISABLED_BY_SCRIPT,
[defines.entity_status.discharging] = FactorioEntityStatus.DISCHARGING,
[defines.entity_status.fluid_ingredient_shortage] = FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE,
[defines.entity_status.fully_charged] = FactorioEntityStatus.FULLY_CHARGED,
[defines.entity_status.full_output] = FactorioEntityStatus.FULL_OUTPUT,
[defines.entity_status.item_ingredient_shortage] = FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE,
[defines.entity_status.launching_rocket] = FactorioEntityStatus.LAUNCHING_ROCKET,
[defines.entity_status.low_input_fluid] = FactorioEntityStatus.LOW_INPUT_FLUID,
[defines.entity_status.low_power] = FactorioEntityStatus.LOW_POWER,
[defines.entity_status.low_temperature] = FactorioEntityStatus.LOW_TEMPERATURE,
[defines.entity_status.marked_for_deconstruction] = FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION,
[defines.entity_status.missing_required_fluid] = FactorioEntityStatus.MISSING_REQUIRED_FLUID,
[defines.entity_status.missing_science_packs] = FactorioEntityStatus.MISSING_SCIENCE_PACKS,
[defines.entity_status.networks_connected] = FactorioEntityStatus.NETWORKS_CONNECTED,
[defines.entity_status.networks_disconnected] = FactorioEntityStatus.NETWORKS_DISCONNECTED,
[defines.entity_status.normal] = FactorioEntityStatus.NORMAL,
[defines.entity_status.not_connected_to_rail] = FactorioEntityStatus.NOT_CONNECTED_TO_RAIL,
[defines.entity_status.not_plugged_in_electric_network] = FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
[defines.entity_status.no_ammo] = FactorioEntityStatus.NO_AMMO,
[defines.entity_status.no_fuel] = FactorioEntityStatus.NO_FUEL,
[defines.entity_status.no_ingredients] = FactorioEntityStatus.NO_INGREDIENTS,
[defines.entity_status.no_input_fluid] = FactorioEntityStatus.NO_INPUT_FLUID,
[defines.entity_status.no_minable_resources] = FactorioEntityStatus.NO_MINABLE_RESOURCES,
[defines.entity_status.no_modules_to_transmit] = FactorioEntityStatus.NO_MODULES_TO_TRANSMIT,
[defines.entity_status.no_power] = FactorioEntityStatus.NO_POWER,
[defines.entity_status.no_recipe] = FactorioEntityStatus.NO_RECIPE,
[defines.entity_status.no_research_in_progress] = FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS,
[defines.entity_status.opened_by_circuit_network] = FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK,
[defines.entity_status.out_of_logistic_network] = FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK,
[defines.entity_status.preparing_rocket_for_launch] = FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
[defines.entity_status.recharging_after_power_outage] = FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
[defines.entity_status.turned_off_during_daytime] = FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME,
[defines.entity_status.waiting_for_source_items] = FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS,
[defines.entity_status.waiting_for_space_in_destination] = FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
[defines.entity_status.waiting_for_target_to_be_built] = FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
[defines.entity_status.waiting_for_train] = FactorioEntityStatus.WAITING_FOR_TRAIN,
[defines.entity_status.waiting_to_launch_rocket] = FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET,
[defines.entity_status.working] = FactorioEntityStatus.WORKING
}
end
return ____exports

View file

@ -3,7 +3,6 @@ local __TS__Class = ____lualib.__TS__Class
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
@ -22,21 +21,26 @@ function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event)
local tilesByChunk = {}
for ____, tile in ipairs(event.tiles) do
local chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
tilesByChunk[chunkPosition] = tile
if not (tilesByChunk[chunkPosition] ~= nil) then
tilesByChunk[chunkPosition] = {}
end
local tiles = tilesByChunk[chunkPosition]
tiles[#tiles + 1] = tile
tilesByChunk[chunkPosition] = tiles
end
for chunkPos, tiles in pairs(tilesByChunk) do
local entities = {}
for tile in pairs(tiles) do
local resources = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, chunkPos)
for ____, resource in ipairs(resources) do
for ____, tile in ipairs(tiles) do
local tileEntities = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, tile.position)
for ____, resource in ipairs(tileEntities) do
entities[#entities + 1] = resource
end
end
____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate(
____exports.EntityUpdatesHandler:throttleResourcesUpdate(
Converters.eventNameString(event.name),
event.tick,
event.surface_index,
{chunkPos[1], chunkPos[2]},
chunkPos,
entities
)
end
@ -49,11 +53,11 @@ function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event)
end
function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event)
local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area)
____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate(
____exports.EntityUpdatesHandler:throttleResourcesUpdate(
Converters.eventNameString(event.name),
event.tick,
event.surface.index,
{event.position.x, event.position.y},
Converters.chunkPosition(event.position),
entities
)
end
@ -67,30 +71,24 @@ function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity)
surfaceIndex = entity.surface.index,
chunkPosition = Converters.mapPositionToChunkPosition(entity.position)
}
local ____FactorioEntityData_Type_Standard_2 = FactorioEntityData.Type.Standard
local ____Converters_prototypeIdEntity_result_3 = Converters.prototypeIdEntity(entity)
local ____entity_graphics_variation_4 = entity.graphics_variation
local ____entity_health_5 = entity.health
local ____entity_active_6 = entity.active
local ____entity_rotatable_7 = entity.rotatable
local ____entity_unit_number_2 = entity.unit_number
local ____entity_graphics_variation_3 = entity.graphics_variation
local ____entity_health_4 = entity.health
local ____entity_active_5 = entity.active
local ____entity_rotatable_6 = entity.rotatable
local ____entity_last_user_index_0 = entity.last_user
if ____entity_last_user_index_0 ~= nil then
____entity_last_user_index_0 = ____entity_last_user_index_0.index
end
local entityUpdate = {
type = ____FactorioEntityData_Type_Standard_2,
protoId = ____Converters_prototypeIdEntity_result_3,
graphicsVariation = ____entity_graphics_variation_4,
health = ____entity_health_5,
isActive = ____entity_active_6,
isRotatable = ____entity_rotatable_7,
unitNumber = ____entity_unit_number_2,
graphicsVariation = ____entity_graphics_variation_3,
health = ____entity_health_4,
isActive = ____entity_active_5,
isRotatable = ____entity_rotatable_6,
lastUser = ____entity_last_user_index_0,
localisedDescription = nil,
localisedName = nil,
position = {entity.position.x, entity.position.y},
status = Converters.entityStatus(entity.status)
}
local entityKey = tostring(entity.unit_number)
EventDataCache:throttle(
entityUpdateKey,
KafkatorioPacketData.Type.MapChunkEntityUpdate,
@ -98,77 +96,73 @@ function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity)
if data.events == nil then
data.events = {}
end
local ____data_events_8, ____eventName_9 = data.events, eventName
if ____data_events_8[____eventName_9] == nil then
____data_events_8[____eventName_9] = {}
local ____data_events_7, ____eventName_8 = data.events, eventName
if ____data_events_7[____eventName_8] == nil then
____data_events_7[____eventName_8] = {}
end
local ____data_events_eventName_10 = data.events[eventName]
____data_events_eventName_10[#____data_events_eventName_10 + 1] = event.tick
if data.distinctEntities == nil then
data.distinctEntities = {}
local ____data_events_eventName_9 = data.events[eventName]
____data_events_eventName_9[#____data_events_eventName_9 + 1] = event.tick
if data.entitiesXY == nil then
data.entitiesXY = {}
end
local ____data_entitiesXY_10, ____tostring_result_11 = data.entitiesXY, tostring(entity.position.x)
if ____data_entitiesXY_10[____tostring_result_11] == nil then
____data_entitiesXY_10[____tostring_result_11] = {}
end
local ____data_entitiesXY_tostring_result_12, ____tostring_result_13 = data.entitiesXY[tostring(entity.position.x)], tostring(entity.position.y)
if ____data_entitiesXY_tostring_result_12[____tostring_result_13] == nil then
____data_entitiesXY_tostring_result_12[____tostring_result_13] = entityUpdate
end
data.distinctEntities[entityKey] = entityUpdate
end
)
end
function EntityUpdatesHandler.throttleResourceEntitiesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities)
function EntityUpdatesHandler.throttleResourcesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities)
local entitiesByProtoId = {}
for ____, entity in ipairs(entities) do
local ____entitiesByProtoId_11, ____entity_protoId_12 = entitiesByProtoId, entity.protoId
if ____entitiesByProtoId_11[____entity_protoId_12] == nil then
____entitiesByProtoId_11[____entity_protoId_12] = {}
local protoId = Converters.prototypeIdEntity(entity)
if entitiesByProtoId[protoId] == nil then
entitiesByProtoId[protoId] = {}
end
local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId]
____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity
local ____entitiesByProtoId_protoId_14 = entitiesByProtoId[protoId]
____entitiesByProtoId_protoId_14[#____entitiesByProtoId_protoId_14 + 1] = entity
end
for protoId, resourceEntities in pairs(entitiesByProtoId) do
local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}}
local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = chunkPosition}
EventDataCache:throttle(
entityUpdateKey,
KafkatorioPacketData.Type.MapChunkEntityUpdate,
KafkatorioPacketData.Type.MapChunkResourceUpdate,
function(data)
if data.events == nil then
data.events = {}
end
local ____data_events_14, ____eventName_15 = data.events, eventName
if ____data_events_14[____eventName_15] == nil then
____data_events_14[____eventName_15] = {}
local ____data_events_15, ____eventName_16 = data.events, eventName
if ____data_events_15[____eventName_16] == nil then
____data_events_15[____eventName_16] = {}
end
local ____data_events_eventName_16 = data.events[eventName]
____data_events_eventName_16[#____data_events_eventName_16 + 1] = eventTick
local ____data_events_eventName_17 = data.events[eventName]
____data_events_eventName_17[#____data_events_eventName_17 + 1] = eventTick
for ____, entity in ipairs(resourceEntities) do
local x, y = table.unpack(entity.position)
local entityKey = (tostring(x) .. ",") .. tostring(y)
if data.distinctEntities == nil then
data.distinctEntities = {}
local resourceUpdate = Converters.convertResourceEntity(entity)
if resourceUpdate ~= nil then
if data.resourcesXY == nil then
data.resourcesXY = {}
end
local ____data_resourcesXY_18, ____tostring_result_19 = data.resourcesXY, tostring(entity.position.x)
if ____data_resourcesXY_18[____tostring_result_19] == nil then
____data_resourcesXY_18[____tostring_result_19] = {}
end
data.resourcesXY[tostring(entity.position.x)][tostring(entity.position.y)] = resourceUpdate
end
data.distinctEntities[entityKey] = entity
end
end
)
end
end
function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition)
local rawEntities = surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"})
local resources = {}
for ____, rawEntity in ipairs(rawEntities) do
local entity = Converters.convertResourceEntity(rawEntity)
if entity ~= nil then
resources[#resources + 1] = entity
end
end
return resources
return surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"})
end
function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area)
local rawEntities = surface.find_entities_filtered({area = area, collision_mask = "resource-layer"})
local resources = {}
for ____, rawEntity in ipairs(rawEntities) do
local entity = Converters.convertResourceEntity(rawEntity)
if entity ~= nil then
resources[#resources + 1] = entity
end
end
return resources
return surface.find_entities_filtered({area = area, collision_mask = "resource-layer"})
end
local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler)
____exports.default = EntityUpdates

View file

@ -20,7 +20,7 @@ function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event,
local tiles = event.surface.find_tiles_filtered({area = event.area})
MapChunkUpdateHandler:mapTilesUpdateDebounce(
event.surface,
Converters.convertMapTablePosition(event.position),
Converters.chunkPosition(event.position),
tiles,
event,
nil,
@ -123,7 +123,10 @@ function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event)
return
end
for ____, position in ipairs(event.positions) do
local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}}
local key = {
surfaceIndex = surface.index,
chunkPosition = Converters.chunkPosition(position)
}
EventUpdates:debounce(
key,
KafkatorioPacketData.Type.MapChunkTileUpdate,
@ -187,10 +190,7 @@ end
function MapChunkUpdateHandler.groupTiles(self, tiles)
local mapChunkPositionToTiles = __TS__New(Map)
for ____, tile in ipairs(tiles) do
local chunkPosition = {
math.floor(tile.position.x / 32),
math.floor(tile.position.y / 32)
}
local chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
if not mapChunkPositionToTiles:has(chunkPosition) then
mapChunkPositionToTiles:set(chunkPosition, {})
end

View file

@ -30,7 +30,7 @@ end
function getEntityPrototypes()
local protos = {}
for ____, entity in pairs(game.entity_prototypes) do
local key = (entity.group.name .. "/") .. entity.subgroup.name
local key = (((entity.group.name .. "/") .. entity.subgroup.name) .. "/") .. entity.type
if protos[key] == nil then
protos[key] = {}
end
@ -42,8 +42,10 @@ function getEntityPrototypes()
isBuilding = entity.is_building,
isEntityWithOwner = entity.is_entity_with_owner,
isMilitaryTarget = entity.is_military_target,
maxHealth = entity.max_health
maxHealth = entity.max_health,
collisionBox = Converters.collisionBox(entity.collision_box)
}
local ____ = entity.infinite_resource
if entity.map_color ~= nil then
entityProto.mapColour = Converters.mapColour(entity.map_color)
end

View file

@ -9,12 +9,12 @@ local ____EventDataCache = require("main.emitting.EventDataCache")
local EventCacheService = ____EventDataCache.default
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
local MapChunkUpdate = ____MapChunkUpdateHandler.default
local ____queue = require("main.queue.queue")
local EventDataQueue = ____queue.default
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
local ____PacketEmitter = require("main.emitting.PacketEmitter")
local PacketEmitter = ____PacketEmitter.default
local ____EventDataQueue = require("main.emitting.EventDataQueue")
local EventDataQueue = ____EventDataQueue.default
script.on_event(
defines.events.on_tick,
function(event)

View file

@ -1,8 +1,8 @@
local ____exports = {}
local ____EventDataCache = require("main.emitting.EventDataCache")
local EventUpdates = ____EventDataCache.default
local ____queue = require("main.queue.queue")
local EventDataQueueManager = ____queue.EventDataQueueManager
local ____EventDataQueue = require("main.emitting.EventDataQueue")
local EventDataQueueManager = ____EventDataQueue.EventDataQueueManager
function ____exports.initGlobal(force)
if force == nil then
force = false

View file

@ -34,7 +34,13 @@ end
function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type)
return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-")
end
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30, ["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5}
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {
["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5,
["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30,
["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30,
["kafkatorio.packet.keyed.MapChunkResourceUpdate"] = 30,
["kafkatorio.packet.keyed.EntityUpdate"] = 5
}
local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig)
____exports.default = KafkatorioSettings
return ____exports

View file

@ -2,15 +2,17 @@
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds)
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=Map tile update rate (seconds)
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=Entity update rate (seconds)
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=Map entity update rate (seconds)
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkResourceUpdate=Map resource update rate (seconds)
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds)
[mod-setting-description]
kafkatorio:cache-expiration-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:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=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:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=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 (30 seconds) is probably fine!
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=How frequently map-tile 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:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=How frequently map-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 (30 seconds) is probably fine!
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkResourceUpdate=How frequently map-resource 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:cache-expiration-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!

View file

@ -15,6 +15,7 @@ export type KafkatorioPacketData =
| KafkatorioPacketData.EntityUpdate
| KafkatorioPacketData.Error
| KafkatorioPacketData.MapChunkEntityUpdate
| KafkatorioPacketData.MapChunkResourceUpdate
| KafkatorioPacketData.MapChunkTileUpdate
| KafkatorioPacketData.PlayerUpdate
| KafkatorioPacketData.PrototypesUpdate
@ -29,6 +30,7 @@ export namespace KafkatorioPacketData {
SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate",
EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate",
MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate",
MapChunkResourceUpdate = "kafkatorio.packet.keyed.MapChunkResourceUpdate",
MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate",
PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate",
Error = "kafkatorio.packet.KafkatorioPacketData.Error",
@ -74,8 +76,8 @@ export namespace KafkatorioPacketData {
chunkPosition?: MapEntityPosition | null;
graphicsVariation?: UByte | null;
health?: Float | null;
isActive?: boolean | null;
isRotatable?: boolean | null;
isActive?: boolean;
isRotatable?: boolean;
lastUser?: UInt | null;
localisedDescription?: string | null;
localisedName?: string | null;
@ -85,7 +87,14 @@ export namespace KafkatorioPacketData {
type: KafkatorioPacketData.Type.MapChunkEntityUpdate;
key: MapChunkEntityUpdateKey;
events?: { [key: EventName]: Tick[] } | null;
distinctEntities?: { [key: string]: FactorioEntityData } | null;
entitiesXY: FactorioEntityUpdateEntityDictionary;
}
export interface MapChunkResourceUpdate {
type: KafkatorioPacketData.Type.MapChunkResourceUpdate;
key: MapChunkResourceUpdateKey;
events?: { [key: EventName]: Tick[] } | null;
resourcesXY: FactorioEntityUpdateResourceDictionary;
}
export interface MapChunkTileUpdate {
@ -96,7 +105,7 @@ export namespace KafkatorioPacketData {
robot?: EntityIdentifiersData | null;
force?: ForceIndex | null;
tileDictionary?: MapTileDictionary | null;
isDeleted?: boolean | null;
isDeleted?: boolean;
}
export interface PlayerUpdate {
@ -110,10 +119,10 @@ export namespace KafkatorioPacketData {
afkTime?: Tick | null;
ticksToRespawn?: Tick | null;
forceIndex?: ForceIndex | null;
isAdmin?: boolean | null;
isConnected?: boolean | null;
isShowOnMap?: boolean | null;
isSpectator?: boolean | null;
isAdmin?: boolean;
isConnected?: boolean;
isShowOnMap?: boolean;
isSpectator?: boolean;
lastOnline?: Tick | null;
onlineTime?: Tick | null;
position?: MapEntityPosition | null;
@ -162,6 +171,16 @@ export interface MapChunkEntityUpdateKey {
chunkPosition: MapChunkPosition;
}
export type FactorioEntityUpdateEntityDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateEntity } };
export interface MapChunkResourceUpdateKey {
protoId: PrototypeId;
surfaceIndex: SurfaceIndex;
chunkPosition: MapChunkPosition;
}
export type FactorioEntityUpdateResourceDictionary = { [key: string]: { [key: string]: FactorioEntityUpdateResource } };
export interface MapChunkTileUpdateKey {
chunkPosition: MapChunkPosition;
surfaceIndex: SurfaceIndex;
@ -218,10 +237,11 @@ export namespace FactorioPrototype {
mapColourFriend?: Colour | null;
mapColourEnemy?: Colour | null;
maxHealth: Float;
isBuilding: boolean;
isEntityWithOwner: boolean;
isMilitaryTarget: boolean;
isBuilding?: boolean;
isEntityWithOwner?: boolean;
isMilitaryTarget?: boolean;
miningProperties?: EntityMiningProperties | null;
collisionBox?: MapBoundingBox | null;
}
export interface MapTile {
@ -229,7 +249,7 @@ export namespace FactorioPrototype {
protoId: PrototypeId;
mapColour: Colour;
layer: UInt;
collisionMasks: List;
collisionMasks: string[];
order: string;
canBeMined: boolean;
}
@ -244,42 +264,9 @@ export type Byte = int8;
export type MapChunkPosition = [
x: Int,
y: Int,
chunkSize: ChunkSize,
];
export type FactorioEntityData =
| FactorioEntityData.Resource
| FactorioEntityData.Standard;
export namespace FactorioEntityData {
export enum Type {
Resource = "kafkatorio.entity.FactorioEntityData.Resource",
Standard = "kafkatorio.entity.FactorioEntityData.Standard",
}
export interface Resource {
type: FactorioEntityData.Type.Resource;
protoId: PrototypeId;
status?: EntityStatus | null;
position: MapEntityPosition;
amount: UInt;
initialAmount?: UInt | null;
}
export interface Standard {
type: FactorioEntityData.Type.Standard;
protoId: PrototypeId;
status?: EntityStatus | null;
position: MapEntityPosition;
graphicsVariation?: UByte | null;
health?: Float | null;
isActive?: boolean | null;
isRotatable?: boolean | null;
lastUser?: UInt | null;
localisedDescription?: string | null;
localisedName?: string | null;
}
}
export interface EntityItemGroup {
name: string;
type: string;
@ -291,56 +278,36 @@ export interface EntityMiningProperties {
products: MinedProduct[] | null;
}
export type List = any & { __List__: void };
export interface MapBoundingBox {
leftTop: MapEntityPosition;
rightBottom: MapEntityPosition;
}
export enum EntityStatus {
CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS",
CHARGING = "CHARGING",
CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK",
DISABLED = "DISABLED",
DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR",
DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT",
DISCHARGING = "DISCHARGING",
FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE",
FULLY_CHARGED = "FULLY_CHARGED",
FULL_OUTPUT = "FULL_OUTPUT",
ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE",
LAUNCHING_ROCKET = "LAUNCHING_ROCKET",
LOW_INPUT_FLUID = "LOW_INPUT_FLUID",
LOW_POWER = "LOW_POWER",
LOW_TEMPERATURE = "LOW_TEMPERATURE",
MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION",
MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID",
MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS",
NETWORKS_CONNECTED = "NETWORKS_CONNECTED",
NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED",
NORMAL = "NORMAL",
NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL",
NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK",
NO_AMMO = "NO_AMMO",
NO_FUEL = "NO_FUEL",
NO_INGREDIENTS = "NO_INGREDIENTS",
NO_INPUT_FLUID = "NO_INPUT_FLUID",
NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES",
NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT",
NO_POWER = "NO_POWER",
NO_RECIPE = "NO_RECIPE",
NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS",
OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK",
OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK",
PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH",
RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE",
TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME",
WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS",
WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION",
WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT",
WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN",
WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET",
WORKING = "WORKING",
export enum ChunkSize {
CHUNK_512 = "CHUNK_512",
CHUNK_256 = "CHUNK_256",
CHUNK_128 = "CHUNK_128",
CHUNK_064 = "CHUNK_064",
CHUNK_032 = "CHUNK_032",
}
export type PrototypeKey = Int & { __PrototypeKey__: void };
export interface FactorioEntityUpdateEntity {
status?: FactorioEntityStatus | null;
unitNumber?: UnitNumber | null;
graphicsVariation?: UByte | null;
health?: Float | null;
isActive?: boolean | null;
isRotatable?: boolean | null;
lastUser?: UInt | null;
}
export interface FactorioEntityUpdateResource {
amount: UInt;
initialAmount?: UInt | null;
}
export type MinedProduct =
| MinedProduct.MinedProductFluid
| MinedProduct.MinedProductItem;
@ -362,4 +329,50 @@ export namespace MinedProduct {
amount?: Double | null;
resultProtoId: PrototypeId;
}
}
export enum FactorioEntityStatus {
WORKING = "WORKING",
NORMAL = "NORMAL",
NO_POWER = "NO_POWER",
LOW_POWER = "LOW_POWER",
NO_FUEL = "NO_FUEL",
DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR",
OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK",
CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK",
DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT",
MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION",
NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK",
NETWORKS_CONNECTED = "NETWORKS_CONNECTED",
NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED",
CHARGING = "CHARGING",
DISCHARGING = "DISCHARGING",
FULLY_CHARGED = "FULLY_CHARGED",
OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK",
NO_RECIPE = "NO_RECIPE",
NO_INGREDIENTS = "NO_INGREDIENTS",
NO_INPUT_FLUID = "NO_INPUT_FLUID",
NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS",
NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES",
LOW_INPUT_FLUID = "LOW_INPUT_FLUID",
FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE",
FULL_OUTPUT = "FULL_OUTPUT",
ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE",
MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID",
MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS",
WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS",
WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION",
PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH",
WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET",
LAUNCHING_ROCKET = "LAUNCHING_ROCKET",
NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT",
RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE",
WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT",
WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN",
NO_AMMO = "NO_AMMO",
LOW_TEMPERATURE = "LOW_TEMPERATURE",
DISABLED = "DISABLED",
TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME",
NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL",
CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS",
}

View file

@ -1,6 +1,6 @@
import {initGlobal} from "../global-init";
import {emitPrototypes} from "../events/prototypeUpdates";
import EventDataQueue from "../queue/queue";
import EventDataQueue from "../emitting/EventDataQueue";
commands.add_command(

View file

@ -1,5 +1,12 @@
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
/**
* Simple ordered queue for {@link KafkatorioPacketData}.
*
* Implemented so printing multiple packets won't flood the output log, causing messages to be
* missed or garbled.
*/
export class KafkatorioPacketQueueManager {
private size: int = 0

View file

@ -1,16 +1,20 @@
import {DefinedEventName} from "../types";
import {
ChunkSize,
Colour,
EntityMiningProperties,
EntityStatus,
EventName,
FactorioEntityData,
FactorioEntityStatus,
FactorioEntityUpdateResource,
KafkatorioPacketData,
MapBoundingBox,
MapChunkPosition,
MapEntityPosition,
MinedProduct,
PrototypeId,
} from "../../generated/kafkatorio-schema";
export namespace Converters {
@ -63,13 +67,6 @@ export namespace Converters {
}
export function convertMapTablePosition(
position: MapPositionTable,
): MapChunkPosition {
return [position.x, position.y]
}
export function convertCollisionMaskToNames(cm: CollisionMask): string[] {
let masks: string[] = []
for (const [name] of pairs(cm)) {
@ -81,17 +78,13 @@ export namespace Converters {
export function convertResourceEntity(
entity: LuaEntity
): FactorioEntityData.Resource | null {
): FactorioEntityUpdateResource | null {
if (entity.type != "resource") {
return null
} else {
return {
type: FactorioEntityData.Type.Resource,
protoId: prototypeId(entity.type, entity.name),
status: convertEntityStatus(entity.status),
amount: entity.amount,
initialAmount: entity.initial_amount,
position: convertMapTablePosition(entity.position),
}
}
}
@ -99,7 +92,7 @@ export namespace Converters {
function convertEntityStatus(
status: defines.entity_status | undefined
): EntityStatus | null {
): FactorioEntityStatus | null {
if (status == undefined) {
return null
} else {
@ -119,15 +112,26 @@ export namespace Converters {
export function tilePositionToChunkPosition(mapPosition: TilePositionTable): MapChunkPosition {
return [floor(mapPosition.x / 32), floor(mapPosition.y)]
return [floor(mapPosition.x / 32), floor(mapPosition.y / 32), ChunkSize.CHUNK_032]
}
export function mapPositionToChunkPosition(mapPosition: MapPositionTable): MapChunkPosition {
return [floor(mapPosition.x / 32), floor(mapPosition.y)]
return [floor(mapPosition.x / 32), floor(mapPosition.y / 32), ChunkSize.CHUNK_032]
}
export function entityStatus(status: defines.entity_status | undefined): EntityStatus | undefined {
export function entityPosition(position: MapPositionTable): MapEntityPosition {
return [position.x, position.y];
}
export function chunkPosition(position: ChunkPositionTable): MapChunkPosition {
return [position.x, position.y, ChunkSize.CHUNK_032]
}
export function entityStatus(status: defines.entity_status | undefined): FactorioEntityStatus | undefined {
if (status == undefined) {
return undefined
} else {
@ -176,51 +180,59 @@ export namespace Converters {
}
const EntityStatusRecord: Record<defines.entity_status, EntityStatus> = {
export function collisionBox(collision_box: BoundingBoxRead): MapBoundingBox {
return {
leftTop: Converters.entityPosition(collision_box.left_top),
rightBottom: Converters.entityPosition(collision_box.right_bottom),
}
}
const EntityStatusRecord: Record<defines.entity_status, FactorioEntityStatus> = {
//@formatter:off
[ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS,
[ defines.entity_status.charging ]: EntityStatus.CHARGING,
[ defines.entity_status.closed_by_circuit_network ]: EntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
[ defines.entity_status.disabled ]: EntityStatus.DISABLED,
[ defines.entity_status.disabled_by_control_behavior ]: EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
[ defines.entity_status.disabled_by_script ]: EntityStatus.DISABLED_BY_SCRIPT,
[ defines.entity_status.discharging ]: EntityStatus.DISCHARGING,
[ defines.entity_status.fluid_ingredient_shortage ]: EntityStatus.FLUID_INGREDIENT_SHORTAGE,
[ defines.entity_status.fully_charged ]: EntityStatus.FULLY_CHARGED,
[ defines.entity_status.full_output ]: EntityStatus.FULL_OUTPUT,
[ defines.entity_status.item_ingredient_shortage ]: EntityStatus.ITEM_INGREDIENT_SHORTAGE,
[ defines.entity_status.launching_rocket ]: EntityStatus.LAUNCHING_ROCKET,
[ defines.entity_status.low_input_fluid ]: EntityStatus.LOW_INPUT_FLUID,
[ defines.entity_status.low_power ]: EntityStatus.LOW_POWER,
[ defines.entity_status.low_temperature ]: EntityStatus.LOW_TEMPERATURE,
[ defines.entity_status.marked_for_deconstruction ]: EntityStatus.MARKED_FOR_DECONSTRUCTION,
[ defines.entity_status.missing_required_fluid ]: EntityStatus.MISSING_REQUIRED_FLUID,
[ defines.entity_status.missing_science_packs ]: EntityStatus.MISSING_SCIENCE_PACKS,
[ defines.entity_status.networks_connected ]: EntityStatus.NETWORKS_CONNECTED,
[ defines.entity_status.networks_disconnected ]: EntityStatus.NETWORKS_DISCONNECTED,
[ defines.entity_status.normal ]: EntityStatus.NORMAL,
[ defines.entity_status.not_connected_to_rail ]: EntityStatus.NOT_CONNECTED_TO_RAIL,
[ defines.entity_status.not_plugged_in_electric_network ]: EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
[ defines.entity_status.no_ammo ]: EntityStatus.NO_AMMO,
[ defines.entity_status.no_fuel ]: EntityStatus.NO_FUEL,
[ defines.entity_status.no_ingredients ]: EntityStatus.NO_INGREDIENTS,
[ defines.entity_status.no_input_fluid ]: EntityStatus.NO_INPUT_FLUID,
[ defines.entity_status.no_minable_resources ]: EntityStatus.NO_MINABLE_RESOURCES,
[ defines.entity_status.no_modules_to_transmit ]: EntityStatus.NO_MODULES_TO_TRANSMIT,
[ defines.entity_status.no_power ]: EntityStatus.NO_POWER,
[ defines.entity_status.no_recipe ]: EntityStatus.NO_RECIPE,
[ defines.entity_status.no_research_in_progress ]: EntityStatus.NO_RESEARCH_IN_PROGRESS,
[ defines.entity_status.opened_by_circuit_network ]: EntityStatus.OPENED_BY_CIRCUIT_NETWORK,
[ defines.entity_status.out_of_logistic_network ]: EntityStatus.OUT_OF_LOGISTIC_NETWORK,
[ defines.entity_status.preparing_rocket_for_launch ]: EntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
[ defines.entity_status.recharging_after_power_outage ]: EntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
[ defines.entity_status.turned_off_during_daytime ]: EntityStatus.TURNED_OFF_DURING_DAYTIME,
[ defines.entity_status.waiting_for_source_items ]: EntityStatus.WAITING_FOR_SOURCE_ITEMS,
[ defines.entity_status.waiting_for_space_in_destination ]: EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
[ defines.entity_status.waiting_for_target_to_be_built ]: EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
[ defines.entity_status.waiting_for_train ]: EntityStatus.WAITING_FOR_TRAIN,
[ defines.entity_status.waiting_to_launch_rocket ]: EntityStatus.WAITING_TO_LAUNCH_ROCKET,
[ defines.entity_status.working ]: EntityStatus.WORKING,
[ defines.entity_status.cant_divide_segments ]: FactorioEntityStatus.CANT_DIVIDE_SEGMENTS,
[ defines.entity_status.charging ]: FactorioEntityStatus.CHARGING,
[ defines.entity_status.closed_by_circuit_network ]: FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
[ defines.entity_status.disabled ]: FactorioEntityStatus.DISABLED,
[ defines.entity_status.disabled_by_control_behavior ]: FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
[ defines.entity_status.disabled_by_script ]: FactorioEntityStatus.DISABLED_BY_SCRIPT,
[ defines.entity_status.discharging ]: FactorioEntityStatus.DISCHARGING,
[ defines.entity_status.fluid_ingredient_shortage ]: FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE,
[ defines.entity_status.fully_charged ]: FactorioEntityStatus.FULLY_CHARGED,
[ defines.entity_status.full_output ]: FactorioEntityStatus.FULL_OUTPUT,
[ defines.entity_status.item_ingredient_shortage ]: FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE,
[ defines.entity_status.launching_rocket ]: FactorioEntityStatus.LAUNCHING_ROCKET,
[ defines.entity_status.low_input_fluid ]: FactorioEntityStatus.LOW_INPUT_FLUID,
[ defines.entity_status.low_power ]: FactorioEntityStatus.LOW_POWER,
[ defines.entity_status.low_temperature ]: FactorioEntityStatus.LOW_TEMPERATURE,
[ defines.entity_status.marked_for_deconstruction ]: FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION,
[ defines.entity_status.missing_required_fluid ]: FactorioEntityStatus.MISSING_REQUIRED_FLUID,
[ defines.entity_status.missing_science_packs ]: FactorioEntityStatus.MISSING_SCIENCE_PACKS,
[ defines.entity_status.networks_connected ]: FactorioEntityStatus.NETWORKS_CONNECTED,
[ defines.entity_status.networks_disconnected ]: FactorioEntityStatus.NETWORKS_DISCONNECTED,
[ defines.entity_status.normal ]: FactorioEntityStatus.NORMAL,
[ defines.entity_status.not_connected_to_rail ]: FactorioEntityStatus.NOT_CONNECTED_TO_RAIL,
[ defines.entity_status.not_plugged_in_electric_network ]: FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
[ defines.entity_status.no_ammo ]: FactorioEntityStatus.NO_AMMO,
[ defines.entity_status.no_fuel ]: FactorioEntityStatus.NO_FUEL,
[ defines.entity_status.no_ingredients ]: FactorioEntityStatus.NO_INGREDIENTS,
[ defines.entity_status.no_input_fluid ]: FactorioEntityStatus.NO_INPUT_FLUID,
[ defines.entity_status.no_minable_resources ]: FactorioEntityStatus.NO_MINABLE_RESOURCES,
[ defines.entity_status.no_modules_to_transmit ]: FactorioEntityStatus.NO_MODULES_TO_TRANSMIT,
[ defines.entity_status.no_power ]: FactorioEntityStatus.NO_POWER,
[ defines.entity_status.no_recipe ]: FactorioEntityStatus.NO_RECIPE,
[ defines.entity_status.no_research_in_progress ]: FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS,
[ defines.entity_status.opened_by_circuit_network ]: FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK,
[ defines.entity_status.out_of_logistic_network ]: FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK,
[ defines.entity_status.preparing_rocket_for_launch ]: FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
[ defines.entity_status.recharging_after_power_outage ]: FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
[ defines.entity_status.turned_off_during_daytime ]: FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME,
[ defines.entity_status.waiting_for_source_items ]: FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS,
[ defines.entity_status.waiting_for_space_in_destination ]: FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
[ defines.entity_status.waiting_for_target_to_be_built ]: FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
[ defines.entity_status.waiting_for_train ]: FactorioEntityStatus.WAITING_FOR_TRAIN,
[ defines.entity_status.waiting_to_launch_rocket ]: FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET,
[ defines.entity_status.working ]: FactorioEntityStatus.WORKING,
//@formatter:on
}
}

View file

@ -1,8 +1,9 @@
import {
EventName,
FactorioEntityData,
FactorioEntityUpdateEntity,
KafkatorioPacketData,
MapChunkPosition, PrototypeId,
MapChunkPosition,
PrototypeId,
Tick
} from "../../../generated/kafkatorio-schema";
import {Converters} from "../converters";
@ -19,29 +20,34 @@ export class EntityUpdatesHandler {
return
}
const tilesByChunk: LuaTable<MapChunkPosition, OldTileAndPosition> = new LuaTable<MapChunkPosition, OldTileAndPosition>()
const tilesByChunk: LuaTable<MapChunkPosition, OldTileAndPosition[]> = new LuaTable<MapChunkPosition, OldTileAndPosition[]>()
for (const tile of event.tiles) {
const chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
tilesByChunk.set(chunkPosition, tile)
if (!tilesByChunk.has(chunkPosition)) {
tilesByChunk.set(chunkPosition, [])
}
const tiles = tilesByChunk.get(chunkPosition)
tiles[tiles.length] = tile
tilesByChunk.set(chunkPosition, tiles)
}
for (const [chunkPos, tiles] of pairs(tilesByChunk)) {
const entities: FactorioEntityData.Resource[] = []
const entities: LuaEntity[] = []
for (const tile in tiles) {
const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos)
for (const resource of resources) {
for (const tile of tiles) {
const tileEntities = EntityUpdatesHandler.getTileResourceEntities(surface, tile.position)
for (const resource of tileEntities) {
entities[entities.length] = resource
}
}
EntityUpdatesHandler.throttleResourceEntitiesUpdate(
EntityUpdatesHandler.throttleResourcesUpdate(
Converters.eventNameString(event.name),
event.tick as Tick,
event.surface_index,
[chunkPos[0], chunkPos[1]],
chunkPos,
entities,
)
}
@ -64,11 +70,11 @@ export class EntityUpdatesHandler {
handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) {
const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area)
EntityUpdatesHandler.throttleResourceEntitiesUpdate(
EntityUpdatesHandler.throttleResourcesUpdate(
Converters.eventNameString(event.name),
event.tick as Tick,
event.surface.index,
[event.position.x, event.position.y],
Converters.chunkPosition(event.position),
entities,
)
}
@ -88,22 +94,16 @@ export class EntityUpdatesHandler {
chunkPosition: Converters.mapPositionToChunkPosition(entity.position)
}
const entityUpdate: FactorioEntityData.Standard = {
type: FactorioEntityData.Type.Standard,
protoId: Converters.prototypeIdEntity(entity),
const entityUpdate: FactorioEntityUpdateEntity = {
unitNumber: entity.unit_number,
graphicsVariation: entity.graphics_variation,
health: entity.health,
isActive: entity.active,
isRotatable: entity.rotatable,
lastUser: entity.last_user?.index,
localisedDescription: null,
localisedName: null,
position: [entity.position.x, entity.position.y],
status: Converters.entityStatus(entity.status),
}
const entityKey: string = `${entity.unit_number}`
EventDataCache.throttle<KafkatorioPacketData.MapChunkEntityUpdate>(
entityUpdateKey,
KafkatorioPacketData.Type.MapChunkEntityUpdate,
@ -113,42 +113,44 @@ export class EntityUpdatesHandler {
data.events[eventName] ??= []
data.events[eventName].push(event.tick)
data.distinctEntities ??= {}
data.distinctEntities[entityKey] = entityUpdate
data.entitiesXY ??= {}
data.entitiesXY[`${entity.position.x}`] ??= {}
data.entitiesXY[`${entity.position.x}`][`${entity.position.y}`] ??= entityUpdate
}
)
}
private static throttleResourceEntitiesUpdate(
private static throttleResourcesUpdate(
eventName: EventName,
eventTick: Tick,
surfaceIndex: SurfaceIndex,
chunkPosition: MapChunkPosition,
entities: FactorioEntityData.Resource[],
entities: LuaEntity[],
) {
// first group by prototype ID
const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {}
const entitiesByProtoId: { [protoId: PrototypeId]: LuaEntity[] } = {}
for (const entity of entities) {
entitiesByProtoId[entity.protoId] ??= []
entitiesByProtoId[entity.protoId].push(entity)
const protoId = Converters.prototypeIdEntity(entity)
entitiesByProtoId[protoId] ??= []
entitiesByProtoId[protoId].push(entity)
}
for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) {
// create an update for each prototype
// create an update for each prototype ID
const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = {
const entityUpdateKey: KafkatorioPacketData.MapChunkResourceUpdate["key"] = {
protoId: protoId,
surfaceIndex: surfaceIndex,
chunkPosition: [chunkPosition[0], chunkPosition[1]],
chunkPosition: chunkPosition,
}
EventDataCache.throttle<KafkatorioPacketData.MapChunkEntityUpdate>(
EventDataCache.throttle<KafkatorioPacketData.MapChunkResourceUpdate>(
entityUpdateKey,
KafkatorioPacketData.Type.MapChunkEntityUpdate,
KafkatorioPacketData.Type.MapChunkResourceUpdate,
data => {
data.events ??= {}
@ -156,11 +158,13 @@ export class EntityUpdatesHandler {
data.events[eventName].push(eventTick)
for (const entity of resourceEntities) {
const [x, y] = entity.position
const entityKey: string = `${x},${y}`
const resourceUpdate = Converters.convertResourceEntity(entity)
data.distinctEntities ??= {}
data.distinctEntities[entityKey] = entity
if (resourceUpdate != null) {
data.resourcesXY ??= {}
data.resourcesXY[`${entity.position.x}`] ??= {}
data.resourcesXY[`${entity.position.x}`][`${entity.position.y}`] = resourceUpdate
}
}
}
)
@ -173,24 +177,12 @@ export class EntityUpdatesHandler {
private static getTileResourceEntities(
surface: LuaSurface,
mapPosition: MapPosition,
): FactorioEntityData.Resource[] {
const rawEntities = surface.find_entities_filtered({
): LuaEntity[] {
return surface.find_entities_filtered({
position: mapPosition,
collision_mask: "resource-layer",
}
)
const resources: FactorioEntityData.Resource[] = []
for (const rawEntity of rawEntities) {
const entity = Converters.convertResourceEntity(rawEntity)
if (entity != null) {
resources[resources.length] = entity
}
}
return resources
}
@ -198,24 +190,12 @@ export class EntityUpdatesHandler {
private static getAreaResourceEntities(
surface: LuaSurface,
area: BoundingBoxTable,
): FactorioEntityData.Resource[] {
const rawEntities = surface.find_entities_filtered({
): LuaEntity[] {
return surface.find_entities_filtered({
area: area,
collision_mask: "resource-layer",
}
)
const resources: FactorioEntityData.Resource[] = []
for (const rawEntity of rawEntities) {
const entity = Converters.convertResourceEntity(rawEntity)
if (entity != null) {
resources[resources.length] = entity
}
}
return resources
}
}

View file

@ -22,7 +22,7 @@ class MapChunkUpdateHandler {
MapChunkUpdateHandler.mapTilesUpdateDebounce(
event.surface,
Converters.convertMapTablePosition(event.position),
Converters.chunkPosition(event.position),
tiles,
event,
undefined,
@ -136,7 +136,7 @@ class MapChunkUpdateHandler {
for (const position of event.positions) {
const key: PacketKey<KafkatorioPacketData.MapChunkTileUpdate> = {
surfaceIndex: surface.index,
chunkPosition: [position.x, position.y],
chunkPosition: Converters.chunkPosition(position),
}
EventUpdates.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
@ -219,10 +219,7 @@ class MapChunkUpdateHandler {
const mapChunkPositionToTiles = new Map<MapChunkPosition, TileRead[]>()
for (const tile of tiles) {
const chunkPosition: MapChunkPosition = [
math.floor((tile.position.x / 32)),
math.floor((tile.position.y / 32)),
]
const chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
if (!mapChunkPositionToTiles.has(chunkPosition)) {
mapChunkPositionToTiles.set(chunkPosition, [])
}

View file

@ -1,4 +1,3 @@
import PacketEmitter from "../emitting/PacketEmitter";
import {
EntityItemGroup,
FactorioPrototype,
@ -16,7 +15,6 @@ export function emitPrototypes() {
const mapTileProtos: PrototypesByType<FactorioPrototype.MapTile> = getMapTilePrototypes()
emit(mapTileProtos)
const entityProtos: PrototypesByType<FactorioPrototype.Entity> = getEntityPrototypes()
emit(entityProtos)
}
@ -58,7 +56,7 @@ function getEntityPrototypes(): PrototypesByType<FactorioPrototype.Entity> {
const protos: PrototypesByType<FactorioPrototype.Entity> = {}
for (const [, entity] of game.entity_prototypes) {
const key: string = `${entity.group.name}/${entity.subgroup.name}`
const key: string = `${entity.group.name}/${entity.subgroup.name}/${entity.type}`
protos[key] ??= []
@ -73,7 +71,9 @@ function getEntityPrototypes(): PrototypesByType<FactorioPrototype.Entity> {
isEntityWithOwner: entity.is_entity_with_owner,
isMilitaryTarget: entity.is_military_target,
maxHealth: entity.max_health,
collisionBox: Converters.collisionBox(entity.collision_box),
}
entity.infinite_resource
if (entity.map_color != undefined) {
entityProto.mapColour = Converters.mapColour(entity.map_color)

View file

@ -3,10 +3,10 @@ import {Converters} from "./converters";
import {handleSurfaceUpdate} from "./surfaceUpdates";
import EventCacheService from "../emitting/EventDataCache";
import MapChunkUpdate from "./handlers/MapChunkUpdateHandler";
import EventDataQueue from "../queue/queue";
import KafkatorioPacketQueue from "../emitting/KafkatorioPacketQueue";
import PacketEmitter from "../emitting/PacketEmitter";
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema";
import EventDataQueue from "../emitting/EventDataQueue";
script.on_event(defines.events.on_tick, (event: OnTickEvent) => {

View file

@ -1,5 +1,5 @@
import EventUpdates from "./emitting/EventDataCache";
import {EventDataQueueManager} from "./queue/queue";
import {EventDataQueueManager} from "./emitting/EventDataQueue";
export function initGlobal(force: boolean = false) {

View file

@ -8,6 +8,7 @@ export class KafkatorioSettingsConfig {
"kafkatorio.packet.keyed.PlayerUpdate": 0.5,
"kafkatorio.packet.keyed.MapChunkTileUpdate": 30,
"kafkatorio.packet.keyed.MapChunkEntityUpdate": 30,
"kafkatorio.packet.keyed.MapChunkResourceUpdate": 30,
"kafkatorio.packet.keyed.EntityUpdate": 5,
}

View file

@ -24,20 +24,20 @@
"forceConsistentCasingInFileNames": true,
"listEmittedFiles": true,
"listFiles": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"sourceMap": false,
"strict": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"traceResolution": true,
"noImplicitReturns": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true
"traceResolution": false
},
"tstl": {
"luaTarget": "5.2",
"tstlVerbose": true,
"tstlVerbose": false,
"noHeader": true,
"noImplicitSelf": true,
"sourceMapTraceback": false,