emit entity prototypes
- mod: refactor event handlers to separate files - lib: update models for prototypes
This commit is contained in:
parent
4510ec4a6e
commit
80eb001bbf
27 changed files with 1570 additions and 1437 deletions
|
|
@ -8,15 +8,16 @@ import kotlinx.serialization.Serializable
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("kafkatorio.prototype.FactorioPrototype")
|
@SerialName("kafkatorio.prototype.FactorioPrototype")
|
||||||
sealed interface FactorioPrototype {
|
sealed interface FactorioPrototype {
|
||||||
|
|
||||||
val protoId: PrototypeId
|
val protoId: PrototypeId
|
||||||
val mapColour: Colour
|
|
||||||
|
|
||||||
|
|
||||||
@SerialName("kafkatorio.prototype.MapTile")
|
@SerialName("kafkatorio.prototype.MapTile")
|
||||||
@Serializable
|
@Serializable
|
||||||
data class MapTile(
|
data class MapTile(
|
||||||
override val protoId: PrototypeId,
|
override val protoId: PrototypeId,
|
||||||
override val mapColour: Colour,
|
|
||||||
|
val mapColour: Colour,
|
||||||
|
|
||||||
val layer: UInt,
|
val layer: UInt,
|
||||||
@Contextual
|
@Contextual
|
||||||
|
|
@ -27,27 +28,47 @@ sealed interface FactorioPrototype {
|
||||||
) : FactorioPrototype
|
) : FactorioPrototype
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param[colour] The colour of the prototype, or `null` if the prototype doesn't have colour.
|
||||||
|
* @param[mapColour] The map colour used when charting this entity if a
|
||||||
|
* [friendly][mapColourFriend] or [enemy][mapColourEnemy] colour isn't defined or `null`.
|
||||||
|
* @param[mapColourFriend] The friendly map colour used when charting this entity.
|
||||||
|
* @param[mapColourEnemy] The enemy map colour used when charting this entity.
|
||||||
|
*/
|
||||||
@SerialName("kafkatorio.prototype.Entity")
|
@SerialName("kafkatorio.prototype.Entity")
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Entity(
|
data class Entity(
|
||||||
override val protoId: PrototypeId,
|
override val protoId: PrototypeId,
|
||||||
override val mapColour: Colour,
|
|
||||||
|
|
||||||
val protoType: String,
|
val group: ItemGroup,
|
||||||
val objectName: String,
|
val subgroup: ItemGroup,
|
||||||
val colour: Colour,
|
|
||||||
|
val colour: Colour? = null,
|
||||||
|
val mapColour: Colour? = null,
|
||||||
|
val mapColourFriend: Colour? = null,
|
||||||
|
val mapColourEnemy: Colour? = null,
|
||||||
|
|
||||||
val maxHealth: Float,
|
val maxHealth: Float,
|
||||||
val isBuilding: Boolean,
|
val isBuilding: Boolean,
|
||||||
val isEntityWithOwner: Boolean,
|
val isEntityWithOwner: Boolean,
|
||||||
val isMilitaryTarget: Boolean,
|
val isMilitaryTarget: Boolean,
|
||||||
val miningProperties: MiningProperties
|
val miningProperties: MiningProperties? = null,
|
||||||
) : FactorioPrototype {
|
) : FactorioPrototype {
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@SerialName("kafkatorio.prototype.EntityMiningProperties")
|
||||||
data class MiningProperties(
|
data class MiningProperties(
|
||||||
val canBeMined: Boolean,
|
val canBeMined: Boolean,
|
||||||
val products: List<MinedProduct>?,
|
val products: List<MinedProduct>?,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("kafkatorio.prototype.EntityItemGroup")
|
||||||
|
data class ItemGroup(
|
||||||
|
val name: String,
|
||||||
|
val type: String,
|
||||||
|
val parentName: String? = null,
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,13 @@
|
||||||
local ____lualib = require("lualib_bundle")
|
|
||||||
local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys
|
|
||||||
local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat
|
|
||||||
local Set = ____lualib.Set
|
|
||||||
local __TS__New = ____lualib.__TS__New
|
|
||||||
local __TS__Spread = ____lualib.__TS__Spread
|
|
||||||
local __TS__ArrayMap = ____lualib.__TS__ArrayMap
|
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local emitConfigurationUpdate, factorioData, allMods, Type
|
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
|
||||||
local PacketEmitter = ____PacketEmitter.default
|
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
|
||||||
local ____global_2Dinit = require("main.global-init")
|
local ____global_2Dinit = require("main.global-init")
|
||||||
local initGlobal = ____global_2Dinit.initGlobal
|
local initGlobal = ____global_2Dinit.initGlobal
|
||||||
local ____prototypeUpdates = require("main.events.prototypeUpdates")
|
local ____prototypeUpdates = require("main.events.prototypeUpdates")
|
||||||
local emitPrototypes = ____prototypeUpdates.emitPrototypes
|
local emitPrototypes = ____prototypeUpdates.emitPrototypes
|
||||||
function emitConfigurationUpdate(changeData)
|
local ____ConfigurationUpdateHandler = require("main.events.handlers.ConfigurationUpdateHandler")
|
||||||
local configUpdateData = {
|
local ConfigurationUpdates = ____ConfigurationUpdateHandler.default
|
||||||
type = Type.ConfigurationUpdate,
|
|
||||||
migrationApplied = changeData.migration_applied,
|
|
||||||
modStartupSettingsChange = changeData.mod_startup_settings_changed,
|
|
||||||
allMods = allMods(changeData),
|
|
||||||
factorioData = factorioData(changeData)
|
|
||||||
}
|
|
||||||
PacketEmitter:emitInstantPacket(configUpdateData)
|
|
||||||
end
|
|
||||||
function factorioData(changeData)
|
|
||||||
return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil}
|
|
||||||
end
|
|
||||||
function allMods(e)
|
|
||||||
local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes)
|
|
||||||
local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods)
|
|
||||||
local modNames = {__TS__Spread(__TS__New(
|
|
||||||
Set,
|
|
||||||
__TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods)
|
|
||||||
))}
|
|
||||||
return __TS__ArrayMap(
|
|
||||||
modNames,
|
|
||||||
function(____, modName)
|
|
||||||
local ____script_active_mods_modName_2 = script.active_mods[modName]
|
|
||||||
if ____script_active_mods_modName_2 == nil then
|
|
||||||
local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName]
|
|
||||||
if ____e_mod_changes_modName_new_version_0 ~= nil then
|
|
||||||
____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version
|
|
||||||
end
|
|
||||||
____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0
|
|
||||||
end
|
|
||||||
local currentVer = ____script_active_mods_modName_2 or nil
|
|
||||||
local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName]
|
|
||||||
if ____e_mod_changes_modName_old_version_3 ~= nil then
|
|
||||||
____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version
|
|
||||||
end
|
|
||||||
local previousVer = ____e_mod_changes_modName_old_version_3 or nil
|
|
||||||
return {modName = modName, currentVersion = currentVer, previousVersion = previousVer}
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
Type = KafkatorioPacketData.Type
|
|
||||||
script.on_configuration_changed(function(data)
|
script.on_configuration_changed(function(data)
|
||||||
initGlobal(true)
|
initGlobal(true)
|
||||||
emitConfigurationUpdate(data)
|
ConfigurationUpdates:emitConfigurationUpdate(data)
|
||||||
emitPrototypes()
|
emitPrototypes()
|
||||||
end)
|
end)
|
||||||
return ____exports
|
return ____exports
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ local ____exports = {}
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local EntityStatus = ____kafkatorio_2Dschema.EntityStatus
|
local EntityStatus = ____kafkatorio_2Dschema.EntityStatus
|
||||||
local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
|
local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
|
||||||
|
local MinedProduct = ____kafkatorio_2Dschema.MinedProduct
|
||||||
____exports.Converters = {}
|
____exports.Converters = {}
|
||||||
local Converters = ____exports.Converters
|
local Converters = ____exports.Converters
|
||||||
do
|
do
|
||||||
|
|
@ -87,6 +88,34 @@ do
|
||||||
return EntityStatusRecord[status]
|
return EntityStatusRecord[status]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
function Converters.miningProperties(properties)
|
||||||
|
local products = {}
|
||||||
|
if properties.products ~= nil then
|
||||||
|
for ____, product in ipairs(properties.products) do
|
||||||
|
if product.type == "fluid" then
|
||||||
|
products[#products + 1] = {
|
||||||
|
type = MinedProduct.Type.MinedProductFluid,
|
||||||
|
amount = product.amount,
|
||||||
|
resultProtoId = ____exports.Converters.prototypeId(product.type, product.name)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if product.type == "item" then
|
||||||
|
products[#products + 1] = {
|
||||||
|
type = MinedProduct.Type.MinedProductItem,
|
||||||
|
amount = product.amount,
|
||||||
|
resultProtoId = ____exports.Converters.prototypeId(product.type, product.name)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return {canBeMined = properties.minable, products = products}
|
||||||
|
end
|
||||||
|
function Converters.playerOnlineInfo(player, data)
|
||||||
|
data.lastOnline = player.last_online
|
||||||
|
data.onlineTime = player.online_time
|
||||||
|
data.afkTime = player.afk_time
|
||||||
|
data.isConnected = player.connected
|
||||||
|
end
|
||||||
EntityStatusRecord = {
|
EntityStatusRecord = {
|
||||||
[defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS,
|
[defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS,
|
||||||
[defines.entity_status.charging] = EntityStatus.CHARGING,
|
[defines.entity_status.charging] = EntityStatus.CHARGING,
|
||||||
|
|
|
||||||
|
|
@ -1,177 +1,6 @@
|
||||||
local ____lualib = require("lualib_bundle")
|
|
||||||
local __TS__Class = ____lualib.__TS__Class
|
|
||||||
local __TS__New = ____lualib.__TS__New
|
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____converters = require("main.events.converters")
|
local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler")
|
||||||
local Converters = ____converters.Converters
|
local EntityUpdates = ____EntityUpdateHandler.default
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
|
||||||
local EventDataCache = ____EventDataCache.default
|
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
|
||||||
local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
|
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
|
||||||
____exports.EntityUpdatesHandler = __TS__Class()
|
|
||||||
local EntityUpdatesHandler = ____exports.EntityUpdatesHandler
|
|
||||||
EntityUpdatesHandler.name = "EntityUpdatesHandler"
|
|
||||||
function EntityUpdatesHandler.prototype.____constructor(self)
|
|
||||||
end
|
|
||||||
function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event)
|
|
||||||
local surface = game.get_surface(event.surface_index)
|
|
||||||
if surface == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local tilesByChunk = {}
|
|
||||||
for ____, tile in ipairs(event.tiles) do
|
|
||||||
local chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
|
|
||||||
tilesByChunk[chunkPosition] = tile
|
|
||||||
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
|
|
||||||
entities[#entities + 1] = resource
|
|
||||||
end
|
|
||||||
end
|
|
||||||
____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate(
|
|
||||||
Converters.eventNameString(event.name),
|
|
||||||
event.tick,
|
|
||||||
event.surface_index,
|
|
||||||
{chunkPos[1], chunkPos[2]},
|
|
||||||
entities
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event)
|
|
||||||
____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity)
|
|
||||||
end
|
|
||||||
function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event)
|
|
||||||
____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity)
|
|
||||||
end
|
|
||||||
function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event)
|
|
||||||
local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area)
|
|
||||||
____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate(
|
|
||||||
Converters.eventNameString(event.name),
|
|
||||||
event.tick,
|
|
||||||
event.surface.index,
|
|
||||||
{event.position.x, event.position.y},
|
|
||||||
entities
|
|
||||||
)
|
|
||||||
end
|
|
||||||
function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity)
|
|
||||||
if entity.unit_number == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local eventName = Converters.eventNameString(event.name)
|
|
||||||
local entityUpdateKey = {
|
|
||||||
protoId = Converters.prototypeIdEntity(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_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,
|
|
||||||
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,
|
|
||||||
function(data)
|
|
||||||
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] = {}
|
|
||||||
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 = {}
|
|
||||||
end
|
|
||||||
data.distinctEntities[entityKey] = entityUpdate
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
function EntityUpdatesHandler.throttleResourceEntitiesUpdate(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] = {}
|
|
||||||
end
|
|
||||||
local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId]
|
|
||||||
____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity
|
|
||||||
end
|
|
||||||
for protoId, resourceEntities in pairs(entitiesByProtoId) do
|
|
||||||
local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}}
|
|
||||||
EventDataCache:throttle(
|
|
||||||
entityUpdateKey,
|
|
||||||
KafkatorioPacketData.Type.MapChunkEntityUpdate,
|
|
||||||
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] = {}
|
|
||||||
end
|
|
||||||
local ____data_events_eventName_16 = data.events[eventName]
|
|
||||||
____data_events_eventName_16[#____data_events_eventName_16 + 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 = {}
|
|
||||||
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
|
|
||||||
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
|
|
||||||
end
|
|
||||||
local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler)
|
|
||||||
____exports.default = EntityUpdates
|
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_built_entity,
|
defines.events.on_built_entity,
|
||||||
function(e)
|
function(e)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
local ____lualib = require("lualib_bundle")
|
||||||
|
local __TS__Class = ____lualib.__TS__Class
|
||||||
|
local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys
|
||||||
|
local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat
|
||||||
|
local Set = ____lualib.Set
|
||||||
|
local __TS__New = ____lualib.__TS__New
|
||||||
|
local __TS__Spread = ____lualib.__TS__Spread
|
||||||
|
local __TS__ArrayMap = ____lualib.__TS__ArrayMap
|
||||||
|
local ____exports = {}
|
||||||
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
|
local ____PacketEmitter = require("main.PacketEmitter")
|
||||||
|
local PacketEmitter = ____PacketEmitter.default
|
||||||
|
____exports.ConfigurationUpdateHandler = __TS__Class()
|
||||||
|
local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler
|
||||||
|
ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler"
|
||||||
|
function ConfigurationUpdateHandler.prototype.____constructor(self)
|
||||||
|
end
|
||||||
|
function ConfigurationUpdateHandler.prototype.emitConfigurationUpdate(self, changeData)
|
||||||
|
local configUpdateData = {
|
||||||
|
type = KafkatorioPacketData.Type.ConfigurationUpdate,
|
||||||
|
migrationApplied = changeData.migration_applied,
|
||||||
|
modStartupSettingsChange = changeData.mod_startup_settings_changed,
|
||||||
|
allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData),
|
||||||
|
factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData)
|
||||||
|
}
|
||||||
|
PacketEmitter:emitInstantPacket(configUpdateData)
|
||||||
|
end
|
||||||
|
function ConfigurationUpdateHandler.factorioData(self, changeData)
|
||||||
|
return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil}
|
||||||
|
end
|
||||||
|
function ConfigurationUpdateHandler.allMods(self, e)
|
||||||
|
local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes)
|
||||||
|
local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods)
|
||||||
|
local modNames = {__TS__Spread(__TS__New(
|
||||||
|
Set,
|
||||||
|
__TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods)
|
||||||
|
))}
|
||||||
|
return __TS__ArrayMap(
|
||||||
|
modNames,
|
||||||
|
function(____, modName)
|
||||||
|
local ____script_active_mods_modName_2 = script.active_mods[modName]
|
||||||
|
if ____script_active_mods_modName_2 == nil then
|
||||||
|
local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName]
|
||||||
|
if ____e_mod_changes_modName_new_version_0 ~= nil then
|
||||||
|
____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version
|
||||||
|
end
|
||||||
|
____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0
|
||||||
|
end
|
||||||
|
local currentVer = ____script_active_mods_modName_2 or nil
|
||||||
|
local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName]
|
||||||
|
if ____e_mod_changes_modName_old_version_3 ~= nil then
|
||||||
|
____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version
|
||||||
|
end
|
||||||
|
local previousVer = ____e_mod_changes_modName_old_version_3 or nil
|
||||||
|
return {modName = modName, currentVersion = currentVer, previousVersion = previousVer}
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
local ConfigurationUpdates = __TS__New(____exports.ConfigurationUpdateHandler)
|
||||||
|
____exports.default = ConfigurationUpdates
|
||||||
|
return ____exports
|
||||||
|
|
@ -0,0 +1,175 @@
|
||||||
|
local ____lualib = require("lualib_bundle")
|
||||||
|
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
|
||||||
|
local ____EventDataCache = require("main.cache.EventDataCache")
|
||||||
|
local EventDataCache = ____EventDataCache.default
|
||||||
|
____exports.EntityUpdatesHandler = __TS__Class()
|
||||||
|
local EntityUpdatesHandler = ____exports.EntityUpdatesHandler
|
||||||
|
EntityUpdatesHandler.name = "EntityUpdatesHandler"
|
||||||
|
function EntityUpdatesHandler.prototype.____constructor(self)
|
||||||
|
end
|
||||||
|
function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event)
|
||||||
|
local surface = game.get_surface(event.surface_index)
|
||||||
|
if surface == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local tilesByChunk = {}
|
||||||
|
for ____, tile in ipairs(event.tiles) do
|
||||||
|
local chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
|
||||||
|
tilesByChunk[chunkPosition] = tile
|
||||||
|
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
|
||||||
|
entities[#entities + 1] = resource
|
||||||
|
end
|
||||||
|
end
|
||||||
|
____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate(
|
||||||
|
Converters.eventNameString(event.name),
|
||||||
|
event.tick,
|
||||||
|
event.surface_index,
|
||||||
|
{chunkPos[1], chunkPos[2]},
|
||||||
|
entities
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event)
|
||||||
|
____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity)
|
||||||
|
end
|
||||||
|
function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event)
|
||||||
|
____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity)
|
||||||
|
end
|
||||||
|
function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event)
|
||||||
|
local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area)
|
||||||
|
____exports.EntityUpdatesHandler:throttleResourceEntitiesUpdate(
|
||||||
|
Converters.eventNameString(event.name),
|
||||||
|
event.tick,
|
||||||
|
event.surface.index,
|
||||||
|
{event.position.x, event.position.y},
|
||||||
|
entities
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity)
|
||||||
|
if entity.unit_number == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local eventName = Converters.eventNameString(event.name)
|
||||||
|
local entityUpdateKey = {
|
||||||
|
protoId = Converters.prototypeIdEntity(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_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,
|
||||||
|
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,
|
||||||
|
function(data)
|
||||||
|
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] = {}
|
||||||
|
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 = {}
|
||||||
|
end
|
||||||
|
data.distinctEntities[entityKey] = entityUpdate
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function EntityUpdatesHandler.throttleResourceEntitiesUpdate(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] = {}
|
||||||
|
end
|
||||||
|
local ____entitiesByProtoId_entity_protoId_13 = entitiesByProtoId[entity.protoId]
|
||||||
|
____entitiesByProtoId_entity_protoId_13[#____entitiesByProtoId_entity_protoId_13 + 1] = entity
|
||||||
|
end
|
||||||
|
for protoId, resourceEntities in pairs(entitiesByProtoId) do
|
||||||
|
local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = {chunkPosition[1], chunkPosition[2]}}
|
||||||
|
EventDataCache:throttle(
|
||||||
|
entityUpdateKey,
|
||||||
|
KafkatorioPacketData.Type.MapChunkEntityUpdate,
|
||||||
|
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] = {}
|
||||||
|
end
|
||||||
|
local ____data_events_eventName_16 = data.events[eventName]
|
||||||
|
____data_events_eventName_16[#____data_events_eventName_16 + 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 = {}
|
||||||
|
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
|
||||||
|
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
|
||||||
|
end
|
||||||
|
local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler)
|
||||||
|
____exports.default = EntityUpdates
|
||||||
|
return ____exports
|
||||||
|
|
@ -0,0 +1,208 @@
|
||||||
|
local ____lualib = require("lualib_bundle")
|
||||||
|
local __TS__Class = ____lualib.__TS__Class
|
||||||
|
local Map = ____lualib.Map
|
||||||
|
local __TS__Iterator = ____lualib.__TS__Iterator
|
||||||
|
local __TS__New = ____lualib.__TS__New
|
||||||
|
local ____exports = {}
|
||||||
|
local ____converters = require("main.events.converters")
|
||||||
|
local Converters = ____converters.Converters
|
||||||
|
local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
||||||
|
local isEventType = ____eventTypeCheck.isEventType
|
||||||
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
|
local ____EventDataCache = require("main.cache.EventDataCache")
|
||||||
|
local EventUpdatesManager = ____EventDataCache.default
|
||||||
|
local MapChunkUpdateHandler = __TS__Class()
|
||||||
|
MapChunkUpdateHandler.name = "MapChunkUpdateHandler"
|
||||||
|
function MapChunkUpdateHandler.prototype.____constructor(self)
|
||||||
|
end
|
||||||
|
function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks)
|
||||||
|
local tiles = event.surface.find_tiles_filtered({area = event.area})
|
||||||
|
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
||||||
|
event.surface,
|
||||||
|
Converters.convertMapTablePosition(event.position),
|
||||||
|
tiles,
|
||||||
|
event,
|
||||||
|
nil,
|
||||||
|
expirationDurationTicks
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event)
|
||||||
|
local surface = game.get_surface(event.surface_index)
|
||||||
|
if surface == nil then
|
||||||
|
local eventName = Converters.eventNameString(event.name)
|
||||||
|
log("[handleBuiltTileEvent] undefined surface " .. eventName)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local tiles = Converters.convertPlacedTiles(event.tile, event.tiles)
|
||||||
|
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
|
||||||
|
for ____, ____value in __TS__Iterator(groupedTiles) do
|
||||||
|
local chunkPos = ____value[1]
|
||||||
|
local tiles = ____value[2]
|
||||||
|
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
||||||
|
surface,
|
||||||
|
chunkPos,
|
||||||
|
tiles,
|
||||||
|
event,
|
||||||
|
function(data)
|
||||||
|
if isEventType(event, defines.events.on_player_built_tile) then
|
||||||
|
data.player = event.player_index
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if isEventType(event, defines.events.on_robot_built_tile) then
|
||||||
|
local ____data_2 = data
|
||||||
|
local ____event_robot_unit_number_0 = event.robot
|
||||||
|
if ____event_robot_unit_number_0 ~= nil then
|
||||||
|
____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number
|
||||||
|
end
|
||||||
|
____data_2.robot = {
|
||||||
|
unitNumber = ____event_robot_unit_number_0 or nil,
|
||||||
|
protoId = Converters.prototypeId(event.robot.type, event.robot.name)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local exhaustiveCheck = event
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event)
|
||||||
|
local surface = game.get_surface(event.surface_index)
|
||||||
|
if surface == nil then
|
||||||
|
local eventName = Converters.eventNameString(event.name)
|
||||||
|
log("[handleMinedTileEvent] undefined surface " .. eventName)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local tiles = Converters.convertRemovedTiles(surface, event.tiles)
|
||||||
|
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
|
||||||
|
for ____, ____value in __TS__Iterator(groupedTiles) do
|
||||||
|
local chunkPos = ____value[1]
|
||||||
|
local tiles = ____value[2]
|
||||||
|
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
||||||
|
surface,
|
||||||
|
chunkPos,
|
||||||
|
tiles,
|
||||||
|
event,
|
||||||
|
function(data)
|
||||||
|
if isEventType(event, defines.events.on_player_mined_tile) then
|
||||||
|
data.player = event.player_index
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if isEventType(event, defines.events.on_robot_mined_tile) then
|
||||||
|
local ____data_5 = data
|
||||||
|
local ____event_robot_unit_number_3 = event.robot
|
||||||
|
if ____event_robot_unit_number_3 ~= nil then
|
||||||
|
____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number
|
||||||
|
end
|
||||||
|
____data_5.robot = {
|
||||||
|
unitNumber = ____event_robot_unit_number_3 or nil,
|
||||||
|
protoId = Converters.prototypeId(event.robot.type, event.robot.name)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local exhaustiveCheck = event
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event)
|
||||||
|
local surface = game.get_surface(event.surface_index)
|
||||||
|
if surface == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles)
|
||||||
|
for ____, ____value in __TS__Iterator(groupedTiles) do
|
||||||
|
local chunkPos = ____value[1]
|
||||||
|
local tiles = ____value[2]
|
||||||
|
MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event)
|
||||||
|
local surface = game.get_surface(event.surface_index)
|
||||||
|
if surface == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for ____, position in ipairs(event.positions) do
|
||||||
|
local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}}
|
||||||
|
EventUpdatesManager:debounce(
|
||||||
|
key,
|
||||||
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
|
function(data)
|
||||||
|
data.isDeleted = true
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks)
|
||||||
|
if surface == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local eventName = Converters.eventNameString(event.name)
|
||||||
|
local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition}
|
||||||
|
EventUpdatesManager:debounce(
|
||||||
|
key,
|
||||||
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
|
function(data)
|
||||||
|
if data.tileDictionary == nil then
|
||||||
|
data.tileDictionary = {tilesXY = {}, protos = {}}
|
||||||
|
end
|
||||||
|
local protosCount = table_size(data.tileDictionary.protos)
|
||||||
|
for ____, tile in ipairs(tiles) do
|
||||||
|
local protoId = Converters.prototypeId("tile", tile.name)
|
||||||
|
if data.tileDictionary.protos[protoId] == nil then
|
||||||
|
end
|
||||||
|
local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId
|
||||||
|
if ____data_tileDictionary_protos_7[____protoId_8] == nil then
|
||||||
|
local ____protosCount_6 = protosCount
|
||||||
|
protosCount = ____protosCount_6 + 1
|
||||||
|
____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6
|
||||||
|
end
|
||||||
|
local protoKey = data.tileDictionary.protos[protoId]
|
||||||
|
local xString = tostring(tile.position.x)
|
||||||
|
local yString = tostring(tile.position.y)
|
||||||
|
local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString
|
||||||
|
if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then
|
||||||
|
____data_tileDictionary_tilesXY_9[____xString_10] = {}
|
||||||
|
end
|
||||||
|
data.tileDictionary.tilesXY[xString][yString] = protoKey
|
||||||
|
end
|
||||||
|
if data.events == nil then
|
||||||
|
data.events = {}
|
||||||
|
end
|
||||||
|
local ____data_events_11, ____eventName_12 = data.events, eventName
|
||||||
|
if ____data_events_11[____eventName_12] == nil then
|
||||||
|
____data_events_11[____eventName_12] = {}
|
||||||
|
end
|
||||||
|
local ____data_events_eventName_13 = data.events[eventName]
|
||||||
|
____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick
|
||||||
|
if updater ~= nil then
|
||||||
|
updater(data)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
expirationDurationTicks
|
||||||
|
)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
if not mapChunkPositionToTiles:has(chunkPosition) then
|
||||||
|
mapChunkPositionToTiles:set(chunkPosition, {})
|
||||||
|
end
|
||||||
|
local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition)
|
||||||
|
if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then
|
||||||
|
local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition)
|
||||||
|
____temp_15[#____temp_15 + 1] = tile
|
||||||
|
____mapChunkPositionToTiles_get_result_push_result_14 = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return mapChunkPositionToTiles
|
||||||
|
end
|
||||||
|
local MapChunkUpdate = __TS__New(MapChunkUpdateHandler)
|
||||||
|
____exports.default = MapChunkUpdate
|
||||||
|
return ____exports
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
local ____lualib = require("lualib_bundle")
|
||||||
|
local __TS__Class = ____lualib.__TS__Class
|
||||||
|
local __TS__New = ____lualib.__TS__New
|
||||||
|
local ____exports = {}
|
||||||
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
|
local ____converters = require("main.events.converters")
|
||||||
|
local Converters = ____converters.Converters
|
||||||
|
local ____EventDataCache = require("main.cache.EventDataCache")
|
||||||
|
local EventUpdatesManager = ____EventDataCache.default
|
||||||
|
____exports.PlayerUpdateHandler = __TS__Class()
|
||||||
|
local PlayerUpdateHandler = ____exports.PlayerUpdateHandler
|
||||||
|
PlayerUpdateHandler.name = "PlayerUpdateHandler"
|
||||||
|
function PlayerUpdateHandler.prototype.____constructor(self)
|
||||||
|
end
|
||||||
|
function PlayerUpdateHandler.prototype.handleBannedEvent(self, event)
|
||||||
|
self:playerUpdateThrottle(
|
||||||
|
event,
|
||||||
|
function(player, data)
|
||||||
|
data.bannedReason = event.reason or nil
|
||||||
|
Converters.playerOnlineInfo(player, data)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function PlayerUpdateHandler.prototype.playerUpdateThrottle(self, event, mutate, expirationDurationTicks)
|
||||||
|
if expirationDurationTicks == nil then
|
||||||
|
expirationDurationTicks = nil
|
||||||
|
end
|
||||||
|
local playerIndex = event.player_index
|
||||||
|
if playerIndex == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local eventName = Converters.eventNameString(event.name)
|
||||||
|
EventUpdatesManager:throttle(
|
||||||
|
{index = playerIndex},
|
||||||
|
KafkatorioPacketData.Type.PlayerUpdate,
|
||||||
|
function(data)
|
||||||
|
local player = game.players[playerIndex]
|
||||||
|
if player ~= nil then
|
||||||
|
mutate(player, data)
|
||||||
|
end
|
||||||
|
if data.events == nil then
|
||||||
|
data.events = {}
|
||||||
|
end
|
||||||
|
local ____data_events_0, ____eventName_1 = data.events, eventName
|
||||||
|
if ____data_events_0[____eventName_1] == nil then
|
||||||
|
____data_events_0[____eventName_1] = {}
|
||||||
|
end
|
||||||
|
local ____data_events_eventName_2 = data.events[eventName]
|
||||||
|
____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick
|
||||||
|
end,
|
||||||
|
expirationDurationTicks
|
||||||
|
)
|
||||||
|
end
|
||||||
|
function PlayerUpdateHandler.prototype.playerUpdateImmediate(self, event, mutate)
|
||||||
|
self:playerUpdateThrottle(event, mutate, 0)
|
||||||
|
end
|
||||||
|
local PlayerUpdates = __TS__New(____exports.PlayerUpdateHandler)
|
||||||
|
____exports.default = PlayerUpdates
|
||||||
|
return ____exports
|
||||||
|
|
@ -1,213 +1,8 @@
|
||||||
local ____lualib = require("lualib_bundle")
|
|
||||||
local __TS__Class = ____lualib.__TS__Class
|
|
||||||
local Map = ____lualib.Map
|
|
||||||
local __TS__Iterator = ____lualib.__TS__Iterator
|
|
||||||
local __TS__New = ____lualib.__TS__New
|
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler")
|
||||||
local isEventType = ____eventTypeCheck.isEventType
|
local EntityUpdates = ____EntityUpdateHandler.default
|
||||||
local ____converters = require("main.events.converters")
|
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
|
||||||
local Converters = ____converters.Converters
|
local MapChunkUpdate = ____MapChunkUpdateHandler.default
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
|
||||||
local EventUpdatesManager = ____EventDataCache.default
|
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
|
||||||
local ____entityUpdates = require("main.events.entityUpdates")
|
|
||||||
local EntityUpdates = ____entityUpdates.default
|
|
||||||
local Type = KafkatorioPacketData.Type
|
|
||||||
local MapChunkUpdateHandler = __TS__Class()
|
|
||||||
MapChunkUpdateHandler.name = "MapChunkUpdateHandler"
|
|
||||||
function MapChunkUpdateHandler.prototype.____constructor(self)
|
|
||||||
end
|
|
||||||
function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks)
|
|
||||||
local tiles = event.surface.find_tiles_filtered({area = event.area})
|
|
||||||
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
|
||||||
event.surface,
|
|
||||||
Converters.convertMapTablePosition(event.position),
|
|
||||||
tiles,
|
|
||||||
event,
|
|
||||||
nil,
|
|
||||||
expirationDurationTicks
|
|
||||||
)
|
|
||||||
end
|
|
||||||
function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event)
|
|
||||||
local surface = game.get_surface(event.surface_index)
|
|
||||||
if surface == nil then
|
|
||||||
local eventName = Converters.eventNameString(event.name)
|
|
||||||
log("[handleBuiltTileEvent] undefined surface " .. eventName)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local tiles = Converters.convertPlacedTiles(event.tile, event.tiles)
|
|
||||||
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
|
|
||||||
for ____, ____value in __TS__Iterator(groupedTiles) do
|
|
||||||
local chunkPos = ____value[1]
|
|
||||||
local tiles = ____value[2]
|
|
||||||
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
|
||||||
surface,
|
|
||||||
chunkPos,
|
|
||||||
tiles,
|
|
||||||
event,
|
|
||||||
function(data)
|
|
||||||
if isEventType(event, defines.events.on_player_built_tile) then
|
|
||||||
data.player = event.player_index
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if isEventType(event, defines.events.on_robot_built_tile) then
|
|
||||||
local ____data_2 = data
|
|
||||||
local ____event_robot_unit_number_0 = event.robot
|
|
||||||
if ____event_robot_unit_number_0 ~= nil then
|
|
||||||
____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number
|
|
||||||
end
|
|
||||||
____data_2.robot = {
|
|
||||||
unitNumber = ____event_robot_unit_number_0 or nil,
|
|
||||||
protoId = Converters.prototypeId(event.robot.type, event.robot.name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local exhaustiveCheck = event
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event)
|
|
||||||
local surface = game.get_surface(event.surface_index)
|
|
||||||
if surface == nil then
|
|
||||||
local eventName = Converters.eventNameString(event.name)
|
|
||||||
log("[handleMinedTileEvent] undefined surface " .. eventName)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local tiles = Converters.convertRemovedTiles(surface, event.tiles)
|
|
||||||
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
|
|
||||||
for ____, ____value in __TS__Iterator(groupedTiles) do
|
|
||||||
local chunkPos = ____value[1]
|
|
||||||
local tiles = ____value[2]
|
|
||||||
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
|
||||||
surface,
|
|
||||||
chunkPos,
|
|
||||||
tiles,
|
|
||||||
event,
|
|
||||||
function(data)
|
|
||||||
if isEventType(event, defines.events.on_player_mined_tile) then
|
|
||||||
data.player = event.player_index
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if isEventType(event, defines.events.on_robot_mined_tile) then
|
|
||||||
local ____data_5 = data
|
|
||||||
local ____event_robot_unit_number_3 = event.robot
|
|
||||||
if ____event_robot_unit_number_3 ~= nil then
|
|
||||||
____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number
|
|
||||||
end
|
|
||||||
____data_5.robot = {
|
|
||||||
unitNumber = ____event_robot_unit_number_3 or nil,
|
|
||||||
protoId = Converters.prototypeId(event.robot.type, event.robot.name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local exhaustiveCheck = event
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event)
|
|
||||||
local surface = game.get_surface(event.surface_index)
|
|
||||||
if surface == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles)
|
|
||||||
for ____, ____value in __TS__Iterator(groupedTiles) do
|
|
||||||
local chunkPos = ____value[1]
|
|
||||||
local tiles = ____value[2]
|
|
||||||
MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event)
|
|
||||||
local surface = game.get_surface(event.surface_index)
|
|
||||||
if surface == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
for ____, position in ipairs(event.positions) do
|
|
||||||
local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}}
|
|
||||||
EventUpdatesManager:debounce(
|
|
||||||
key,
|
|
||||||
Type.MapChunkTileUpdate,
|
|
||||||
function(data)
|
|
||||||
data.isDeleted = true
|
|
||||||
return true
|
|
||||||
end,
|
|
||||||
0
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks)
|
|
||||||
if surface == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local eventName = Converters.eventNameString(event.name)
|
|
||||||
local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition}
|
|
||||||
EventUpdatesManager:debounce(
|
|
||||||
key,
|
|
||||||
Type.MapChunkTileUpdate,
|
|
||||||
function(data)
|
|
||||||
if data.tileDictionary == nil then
|
|
||||||
data.tileDictionary = {tilesXY = {}, protos = {}}
|
|
||||||
end
|
|
||||||
local protosCount = table_size(data.tileDictionary.protos)
|
|
||||||
for ____, tile in ipairs(tiles) do
|
|
||||||
local protoId = Converters.prototypeId("tile", tile.name)
|
|
||||||
if data.tileDictionary.protos[protoId] == nil then
|
|
||||||
end
|
|
||||||
local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId
|
|
||||||
if ____data_tileDictionary_protos_7[____protoId_8] == nil then
|
|
||||||
local ____protosCount_6 = protosCount
|
|
||||||
protosCount = ____protosCount_6 + 1
|
|
||||||
____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6
|
|
||||||
end
|
|
||||||
local protoKey = data.tileDictionary.protos[protoId]
|
|
||||||
local xString = tostring(tile.position.x)
|
|
||||||
local yString = tostring(tile.position.y)
|
|
||||||
local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString
|
|
||||||
if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then
|
|
||||||
____data_tileDictionary_tilesXY_9[____xString_10] = {}
|
|
||||||
end
|
|
||||||
data.tileDictionary.tilesXY[xString][yString] = protoKey
|
|
||||||
end
|
|
||||||
if data.events == nil then
|
|
||||||
data.events = {}
|
|
||||||
end
|
|
||||||
local ____data_events_11, ____eventName_12 = data.events, eventName
|
|
||||||
if ____data_events_11[____eventName_12] == nil then
|
|
||||||
____data_events_11[____eventName_12] = {}
|
|
||||||
end
|
|
||||||
local ____data_events_eventName_13 = data.events[eventName]
|
|
||||||
____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick
|
|
||||||
if updater ~= nil then
|
|
||||||
updater(data)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
expirationDurationTicks
|
|
||||||
)
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
if not mapChunkPositionToTiles:has(chunkPosition) then
|
|
||||||
mapChunkPositionToTiles:set(chunkPosition, {})
|
|
||||||
end
|
|
||||||
local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition)
|
|
||||||
if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then
|
|
||||||
local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition)
|
|
||||||
____temp_15[#____temp_15 + 1] = tile
|
|
||||||
____mapChunkPositionToTiles_get_result_push_result_14 = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return mapChunkPositionToTiles
|
|
||||||
end
|
|
||||||
local MapChunkUpdate = __TS__New(MapChunkUpdateHandler)
|
|
||||||
____exports.default = MapChunkUpdate
|
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_chunk_generated,
|
defines.events.on_chunk_generated,
|
||||||
function(e)
|
function(e)
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,26 @@
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local playerUpdateThrottle, playerOnlineInfo, handleBannedEvent, Type
|
local disconnectReasons
|
||||||
local ____converters = require("main.events.converters")
|
local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
|
||||||
local EventUpdatesManager = ____EventDataCache.default
|
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
local ____PacketEmitter = require("main.PacketEmitter")
|
||||||
local packetEmitter = ____PacketEmitter.default
|
local packetEmitter = ____PacketEmitter.default
|
||||||
function playerUpdateThrottle(event, mutate, expirationDurationTicks)
|
local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler")
|
||||||
if expirationDurationTicks == nil then
|
local PlayerUpdates = ____PlayerUpdateHandler.default
|
||||||
expirationDurationTicks = nil
|
|
||||||
end
|
|
||||||
local playerIndex = event.player_index
|
|
||||||
if playerIndex == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local eventName = Converters.eventNameString(event.name)
|
|
||||||
EventUpdatesManager:throttle(
|
|
||||||
{index = playerIndex},
|
|
||||||
Type.PlayerUpdate,
|
|
||||||
function(data)
|
|
||||||
local player = game.players[playerIndex]
|
|
||||||
if player ~= nil then
|
|
||||||
mutate(player, data)
|
|
||||||
end
|
|
||||||
if data.events == nil then
|
|
||||||
data.events = {}
|
|
||||||
end
|
|
||||||
local ____data_events_0, ____eventName_1 = data.events, eventName
|
|
||||||
if ____data_events_0[____eventName_1] == nil then
|
|
||||||
____data_events_0[____eventName_1] = {}
|
|
||||||
end
|
|
||||||
local ____data_events_eventName_2 = data.events[eventName]
|
|
||||||
____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick
|
|
||||||
end,
|
|
||||||
expirationDurationTicks
|
|
||||||
)
|
|
||||||
end
|
|
||||||
function playerOnlineInfo(player, data)
|
|
||||||
data.lastOnline = player.last_online
|
|
||||||
data.onlineTime = player.online_time
|
|
||||||
data.afkTime = player.afk_time
|
|
||||||
data.isConnected = player.connected
|
|
||||||
end
|
|
||||||
function handleBannedEvent(event)
|
|
||||||
playerUpdateThrottle(
|
|
||||||
event,
|
|
||||||
function(player, data)
|
|
||||||
data.bannedReason = event.reason or nil
|
|
||||||
playerOnlineInfo(player, data)
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
Type = KafkatorioPacketData.Type
|
|
||||||
local function playerUpdateImmediate(event, mutate)
|
|
||||||
playerUpdateThrottle(event, mutate, 0)
|
|
||||||
end
|
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_player_joined_game,
|
defines.events.on_player_joined_game,
|
||||||
function(e)
|
function(e)
|
||||||
playerUpdateThrottle(
|
PlayerUpdates:playerUpdateThrottle(
|
||||||
e,
|
e,
|
||||||
function(player, data)
|
function(player, data)
|
||||||
data.isAdmin = player.admin
|
data.isAdmin = player.admin
|
||||||
local ____data_5 = data
|
local ____data_2 = data
|
||||||
local ____player_character_unit_number_3 = player.character
|
local ____player_character_unit_number_0 = player.character
|
||||||
if ____player_character_unit_number_3 ~= nil then
|
if ____player_character_unit_number_0 ~= nil then
|
||||||
____player_character_unit_number_3 = ____player_character_unit_number_3.unit_number
|
____player_character_unit_number_0 = ____player_character_unit_number_0.unit_number
|
||||||
end
|
end
|
||||||
____data_5.characterUnitNumber = ____player_character_unit_number_3 or nil
|
____data_2.characterUnitNumber = ____player_character_unit_number_0 or nil
|
||||||
data.chatColour = Converters.mapColour(player.chat_color)
|
data.chatColour = Converters.mapColour(player.chat_color)
|
||||||
data.colour = Converters.mapColour(player.color)
|
data.colour = Converters.mapColour(player.color)
|
||||||
data.forceIndex = player.force.index
|
data.forceIndex = player.force.index
|
||||||
|
|
@ -78,7 +29,7 @@ script.on_event(
|
||||||
data.isSpectator = player.spectator
|
data.isSpectator = player.spectator
|
||||||
data.surfaceIndex = player.surface.index
|
data.surfaceIndex = player.surface.index
|
||||||
data.tag = player.tag
|
data.tag = player.tag
|
||||||
playerOnlineInfo(player, data)
|
Converters.playerOnlineInfo(player, data)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
@ -86,7 +37,7 @@ script.on_event(
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_player_changed_position,
|
defines.events.on_player_changed_position,
|
||||||
function(e)
|
function(e)
|
||||||
playerUpdateThrottle(
|
PlayerUpdates:playerUpdateThrottle(
|
||||||
e,
|
e,
|
||||||
function(player, data)
|
function(player, data)
|
||||||
data.position = {player.position.x, player.position.y}
|
data.position = {player.position.x, player.position.y}
|
||||||
|
|
@ -97,7 +48,7 @@ script.on_event(
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_player_changed_surface,
|
defines.events.on_player_changed_surface,
|
||||||
function(e)
|
function(e)
|
||||||
playerUpdateThrottle(
|
PlayerUpdates:playerUpdateThrottle(
|
||||||
e,
|
e,
|
||||||
function(player, data)
|
function(player, data)
|
||||||
data.position = {player.position.x, player.position.y}
|
data.position = {player.position.x, player.position.y}
|
||||||
|
|
@ -109,11 +60,11 @@ script.on_event(
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_player_died,
|
defines.events.on_player_died,
|
||||||
function(e)
|
function(e)
|
||||||
playerUpdateThrottle(
|
PlayerUpdates:playerUpdateThrottle(
|
||||||
e,
|
e,
|
||||||
function(player, data)
|
function(player, data)
|
||||||
data.ticksToRespawn = player.ticks_to_respawn or nil
|
data.ticksToRespawn = player.ticks_to_respawn or nil
|
||||||
playerOnlineInfo(player, data)
|
Converters.playerOnlineInfo(player, data)
|
||||||
if e.cause ~= nil then
|
if e.cause ~= nil then
|
||||||
data.diedCause = {
|
data.diedCause = {
|
||||||
unitNumber = e.cause.unit_number or nil,
|
unitNumber = e.cause.unit_number or nil,
|
||||||
|
|
@ -124,25 +75,31 @@ script.on_event(
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
script.on_event(defines.events.on_player_banned, handleBannedEvent)
|
script.on_event(
|
||||||
script.on_event(defines.events.on_player_unbanned, handleBannedEvent)
|
defines.events.on_player_banned,
|
||||||
|
function(event)
|
||||||
|
PlayerUpdates:handleBannedEvent(event)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
script.on_event(
|
||||||
|
defines.events.on_player_unbanned,
|
||||||
|
function(event)
|
||||||
|
PlayerUpdates:handleBannedEvent(event)
|
||||||
|
end
|
||||||
|
)
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_player_kicked,
|
defines.events.on_player_kicked,
|
||||||
function(event)
|
function(event)
|
||||||
log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name))
|
log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name))
|
||||||
playerUpdateImmediate(
|
PlayerUpdates:playerUpdateImmediate(
|
||||||
event,
|
event,
|
||||||
function(player, data)
|
function(player, data)
|
||||||
data.kickedReason = event.reason or nil
|
data.kickedReason = event.reason or nil
|
||||||
playerOnlineInfo(player, data)
|
Converters.playerOnlineInfo(player, data)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
local disconnectReasons = {}
|
|
||||||
for name, disconnectId in pairs(defines.disconnect_reason) do
|
|
||||||
disconnectReasons[disconnectId] = name
|
|
||||||
end
|
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_pre_player_left_game,
|
defines.events.on_pre_player_left_game,
|
||||||
function(event)
|
function(event)
|
||||||
|
|
@ -156,13 +113,17 @@ script.on_event(
|
||||||
defines.events.on_player_removed,
|
defines.events.on_player_removed,
|
||||||
function(event)
|
function(event)
|
||||||
log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name))
|
log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name))
|
||||||
playerUpdateImmediate(
|
PlayerUpdates:playerUpdateImmediate(
|
||||||
event,
|
event,
|
||||||
function(player, data)
|
function(player, data)
|
||||||
data.isRemoved = true
|
data.isRemoved = true
|
||||||
playerOnlineInfo(player, data)
|
Converters.playerOnlineInfo(player, data)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
|
disconnectReasons = {}
|
||||||
|
for name, disconnectId in pairs(defines.disconnect_reason) do
|
||||||
|
disconnectReasons[disconnectId] = name
|
||||||
|
end
|
||||||
return ____exports
|
return ____exports
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
local ____lualib = require("lualib_bundle")
|
|
||||||
local __TS__ArrayPushArray = ____lualib.__TS__ArrayPushArray
|
|
||||||
local ____exports = {}
|
local ____exports = {}
|
||||||
local prototypeUpdates, getMapTilePrototypes
|
local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup
|
||||||
local ____PacketEmitter = require("main.PacketEmitter")
|
local ____PacketEmitter = require("main.PacketEmitter")
|
||||||
local PacketEmitter = ____PacketEmitter.default
|
local PacketEmitter = ____PacketEmitter.default
|
||||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||||
|
|
@ -9,18 +7,19 @@ local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype
|
||||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||||
local ____converters = require("main.events.converters")
|
local ____converters = require("main.events.converters")
|
||||||
local Converters = ____converters.Converters
|
local Converters = ____converters.Converters
|
||||||
function prototypeUpdates()
|
function emit(protosByType)
|
||||||
local prototypes = {}
|
for ____, protos in pairs(protosByType) do
|
||||||
__TS__ArrayPushArray(
|
PacketEmitter:emitInstantPacket({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos})
|
||||||
prototypes,
|
end
|
||||||
getMapTilePrototypes()
|
|
||||||
)
|
|
||||||
return prototypes
|
|
||||||
end
|
end
|
||||||
function getMapTilePrototypes()
|
function getMapTilePrototypes()
|
||||||
local tiles = {}
|
local tiles = {}
|
||||||
|
if not (tiles.tile ~= nil) then
|
||||||
|
tiles.tile = {}
|
||||||
|
end
|
||||||
for ____, tile in pairs(game.tile_prototypes) do
|
for ____, tile in pairs(game.tile_prototypes) do
|
||||||
tiles[#tiles + 1] = {
|
local ____tiles_tile_0 = tiles.tile
|
||||||
|
____tiles_tile_0[#____tiles_tile_0 + 1] = {
|
||||||
type = FactorioPrototype.Type.MapTile,
|
type = FactorioPrototype.Type.MapTile,
|
||||||
protoId = Converters.prototypeId("tile", tile.name),
|
protoId = Converters.prototypeId("tile", tile.name),
|
||||||
order = tile.order,
|
order = tile.order,
|
||||||
|
|
@ -32,11 +31,56 @@ function getMapTilePrototypes()
|
||||||
end
|
end
|
||||||
return tiles
|
return tiles
|
||||||
end
|
end
|
||||||
|
function getEntityPrototypes()
|
||||||
|
local protos = {}
|
||||||
|
for ____, entity in pairs(game.entity_prototypes) do
|
||||||
|
local key = (entity.group.name .. "/") .. entity.subgroup.name
|
||||||
|
if not (protos[key] ~= nil) then
|
||||||
|
protos[key] = {}
|
||||||
|
end
|
||||||
|
local entityProto = {
|
||||||
|
type = FactorioPrototype.Type.Entity,
|
||||||
|
protoId = Converters.prototypeId(entity.type, entity.name),
|
||||||
|
group = convertItemGroup(entity.group),
|
||||||
|
subgroup = convertItemSubgroup(entity.subgroup),
|
||||||
|
isBuilding = entity.is_building,
|
||||||
|
isEntityWithOwner = entity.is_entity_with_owner,
|
||||||
|
isMilitaryTarget = entity.is_military_target,
|
||||||
|
maxHealth = entity.max_health
|
||||||
|
}
|
||||||
|
if entity.map_color ~= nil then
|
||||||
|
entityProto.mapColour = Converters.mapColour(entity.map_color)
|
||||||
|
end
|
||||||
|
if entity.friendly_map_color ~= nil then
|
||||||
|
entityProto.mapColourFriend = Converters.mapColour(entity.friendly_map_color)
|
||||||
|
end
|
||||||
|
if entity.enemy_map_color ~= nil then
|
||||||
|
entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color)
|
||||||
|
end
|
||||||
|
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
|
||||||
|
local ____protos_key_1 = protos[key]
|
||||||
|
____protos_key_1[#____protos_key_1 + 1] = entityProto
|
||||||
|
end
|
||||||
|
return protos
|
||||||
|
end
|
||||||
|
function convertItemGroup(itemGroup)
|
||||||
|
return {name = itemGroup.name, type = itemGroup.type, parentName = nil}
|
||||||
|
end
|
||||||
|
function convertItemSubgroup(itemGroup)
|
||||||
|
local ____itemGroup_name_4 = itemGroup.name
|
||||||
|
local ____itemGroup_type_5 = itemGroup.type
|
||||||
|
local ____itemGroup_group_name_2 = itemGroup.group
|
||||||
|
if ____itemGroup_group_name_2 ~= nil then
|
||||||
|
____itemGroup_group_name_2 = ____itemGroup_group_name_2.name
|
||||||
|
end
|
||||||
|
return {name = ____itemGroup_name_4, type = ____itemGroup_type_5, parentName = ____itemGroup_group_name_2}
|
||||||
|
end
|
||||||
function ____exports.emitPrototypes()
|
function ____exports.emitPrototypes()
|
||||||
local data = {
|
local mapTileProtos = getMapTilePrototypes()
|
||||||
prototypes = prototypeUpdates(),
|
emit(mapTileProtos)
|
||||||
type = KafkatorioPacketData.Type.PrototypesUpdate
|
local ____ = game.item_group_prototypes
|
||||||
}
|
local ____ = game.item_subgroup_prototypes
|
||||||
PacketEmitter:emitInstantPacket(data)
|
local entityProtos = getEntityPrototypes()
|
||||||
|
emit(entityProtos)
|
||||||
end
|
end
|
||||||
return ____exports
|
return ____exports
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ local ____surfaceUpdates = require("main.events.surfaceUpdates")
|
||||||
local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate
|
local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate
|
||||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
local ____EventDataCache = require("main.cache.EventDataCache")
|
||||||
local EventCacheService = ____EventDataCache.default
|
local EventCacheService = ____EventDataCache.default
|
||||||
local ____mapChunkUpdates = require("main.events.mapChunkUpdates")
|
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
|
||||||
local MapChunkUpdate = ____mapChunkUpdates.default
|
local MapChunkUpdate = ____MapChunkUpdateHandler.default
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_tick,
|
defines.events.on_tick,
|
||||||
function(event)
|
function(event)
|
||||||
|
|
|
||||||
|
|
@ -211,15 +211,17 @@ export namespace FactorioPrototype {
|
||||||
export interface Entity {
|
export interface Entity {
|
||||||
type: FactorioPrototype.Type.Entity;
|
type: FactorioPrototype.Type.Entity;
|
||||||
protoId: PrototypeId;
|
protoId: PrototypeId;
|
||||||
mapColour: Colour;
|
group: EntityItemGroup;
|
||||||
protoType: string;
|
subgroup: EntityItemGroup;
|
||||||
objectName: string;
|
colour?: Colour | null;
|
||||||
colour: Colour;
|
mapColour?: Colour | null;
|
||||||
|
mapColourFriend?: Colour | null;
|
||||||
|
mapColourEnemy?: Colour | null;
|
||||||
maxHealth: Float;
|
maxHealth: Float;
|
||||||
isBuilding: boolean;
|
isBuilding: boolean;
|
||||||
isEntityWithOwner: boolean;
|
isEntityWithOwner: boolean;
|
||||||
isMilitaryTarget: boolean;
|
isMilitaryTarget: boolean;
|
||||||
miningProperties: MiningProperties;
|
miningProperties?: EntityMiningProperties | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MapTile {
|
export interface MapTile {
|
||||||
|
|
@ -278,7 +280,13 @@ export namespace FactorioEntityData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MiningProperties {
|
export interface EntityItemGroup {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
parentName?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EntityMiningProperties {
|
||||||
canBeMined: boolean;
|
canBeMined: boolean;
|
||||||
products: MinedProduct[] | null;
|
products: MinedProduct[] | null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,12 @@
|
||||||
import PacketEmitter from "../PacketEmitter";
|
|
||||||
import {
|
|
||||||
ConfigurationUpdateGameData,
|
|
||||||
ConfigurationUpdateModData,
|
|
||||||
KafkatorioPacketData
|
|
||||||
} from "../../generated/kafkatorio-schema";
|
|
||||||
import {initGlobal} from "../global-init";
|
import {initGlobal} from "../global-init";
|
||||||
import {emitPrototypes} from "./prototypeUpdates";
|
import {emitPrototypes} from "./prototypeUpdates";
|
||||||
import Type = KafkatorioPacketData.Type;
|
import ConfigurationUpdates from "./handlers/ConfigurationUpdateHandler";
|
||||||
import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate;
|
|
||||||
|
|
||||||
|
|
||||||
script.on_configuration_changed((data: ConfigurationChangedData) => {
|
script.on_configuration_changed((data: ConfigurationChangedData) => {
|
||||||
// runs whenever the version of the base game, or a mod, changes
|
// runs whenever the version of the base game, or a mod, changes
|
||||||
initGlobal(true)
|
initGlobal(true)
|
||||||
// KafkatorioSettings.loadSettings()
|
// KafkatorioSettings.loadSettings()
|
||||||
emitConfigurationUpdate(data)
|
ConfigurationUpdates.emitConfigurationUpdate(data)
|
||||||
emitPrototypes()
|
emitPrototypes()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
function emitConfigurationUpdate(changeData: ConfigurationChangedData) {
|
|
||||||
|
|
||||||
const configUpdateData: ConfigurationUpdate = {
|
|
||||||
type: Type.ConfigurationUpdate,
|
|
||||||
migrationApplied: changeData.migration_applied,
|
|
||||||
modStartupSettingsChange: changeData.mod_startup_settings_changed,
|
|
||||||
allMods: allMods(changeData),
|
|
||||||
factorioData: factorioData(changeData)
|
|
||||||
}
|
|
||||||
|
|
||||||
PacketEmitter.emitInstantPacket(configUpdateData)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function factorioData(changeData: ConfigurationChangedData): ConfigurationUpdateGameData {
|
|
||||||
return {
|
|
||||||
oldVersion: changeData.old_version ?? null,
|
|
||||||
newVersion: changeData.new_version ?? null,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] {
|
|
||||||
|
|
||||||
let namesOfChangedMods: string[] = Object.keys(e.mod_changes)
|
|
||||||
let namesOfCurrentMods: string[] = Object.keys(script.active_mods)
|
|
||||||
|
|
||||||
let modNames = [...new Set<string>(
|
|
||||||
namesOfChangedMods.concat(namesOfCurrentMods)
|
|
||||||
)]
|
|
||||||
|
|
||||||
return modNames.map((modName) => {
|
|
||||||
|
|
||||||
let currentVer = script.active_mods[modName] ?? e.mod_changes[modName]?.new_version ?? null
|
|
||||||
let previousVer = e.mod_changes[modName]?.old_version ?? null
|
|
||||||
|
|
||||||
return {
|
|
||||||
modName: modName,
|
|
||||||
currentVersion: currentVer,
|
|
||||||
previousVersion: previousVer,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import {DefinedEventName} from "../types";
|
import {DefinedEventName} from "../types";
|
||||||
import {
|
import {
|
||||||
Colour,
|
Colour,
|
||||||
|
EntityMiningProperties,
|
||||||
EntityStatus,
|
EntityStatus,
|
||||||
EventName,
|
EventName,
|
||||||
FactorioEntityData,
|
FactorioEntityData,
|
||||||
|
KafkatorioPacketData,
|
||||||
MapChunkPosition,
|
MapChunkPosition,
|
||||||
|
MinedProduct,
|
||||||
PrototypeId,
|
PrototypeId,
|
||||||
} from "../../generated/kafkatorio-schema";
|
} from "../../generated/kafkatorio-schema";
|
||||||
|
|
||||||
|
|
@ -133,6 +136,46 @@ export namespace Converters {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function miningProperties(
|
||||||
|
properties: LuaEntityPrototype["mineable_properties"]
|
||||||
|
): EntityMiningProperties {
|
||||||
|
|
||||||
|
const products: MinedProduct[] = []
|
||||||
|
|
||||||
|
if (properties.products != null) {
|
||||||
|
for (const product of properties.products) {
|
||||||
|
if (product.type == "fluid") {
|
||||||
|
products[products.length] = {
|
||||||
|
type: MinedProduct.Type.MinedProductFluid,
|
||||||
|
amount: product.amount,
|
||||||
|
resultProtoId: Converters.prototypeId(product.type, product.name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (product.type == "item") {
|
||||||
|
products[products.length] = {
|
||||||
|
type: MinedProduct.Type.MinedProductItem,
|
||||||
|
amount: product.amount,
|
||||||
|
resultProtoId: Converters.prototypeId(product.type, product.name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
canBeMined: properties.minable,
|
||||||
|
products: products,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) {
|
||||||
|
data.lastOnline = player.last_online
|
||||||
|
data.onlineTime = player.online_time
|
||||||
|
data.afkTime = player.afk_time
|
||||||
|
data.isConnected = player.connected
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const EntityStatusRecord: Record<defines.entity_status, EntityStatus> = {
|
const EntityStatusRecord: Record<defines.entity_status, EntityStatus> = {
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
[ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS,
|
[ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS,
|
||||||
|
|
|
||||||
|
|
@ -1,230 +1,4 @@
|
||||||
import {Converters} from "./converters";
|
import EntityUpdates from "./handlers/EntityUpdateHandler";
|
||||||
import EventDataCache from "../cache/EventDataCache";
|
|
||||||
import {
|
|
||||||
EventName,
|
|
||||||
FactorioEntityData,
|
|
||||||
KafkatorioPacketData,
|
|
||||||
MapChunkPosition,
|
|
||||||
PrototypeId,
|
|
||||||
Tick,
|
|
||||||
} from "../../generated/kafkatorio-schema";
|
|
||||||
|
|
||||||
|
|
||||||
export class EntityUpdatesHandler {
|
|
||||||
|
|
||||||
|
|
||||||
handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
|
|
||||||
|
|
||||||
const surface = game.get_surface(event.surface_index)
|
|
||||||
if (surface == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [chunkPos, tiles] of pairs(tilesByChunk)) {
|
|
||||||
|
|
||||||
const entities: FactorioEntityData.Resource[] = []
|
|
||||||
|
|
||||||
for (const tile in tiles) {
|
|
||||||
const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos)
|
|
||||||
for (const resource of resources) {
|
|
||||||
entities[entities.length] = resource
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityUpdatesHandler.throttleResourceEntitiesUpdate(
|
|
||||||
Converters.eventNameString(event.name),
|
|
||||||
event.tick as Tick,
|
|
||||||
event.surface_index,
|
|
||||||
[chunkPos[0], chunkPos[1]],
|
|
||||||
entities,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleMinedEntityEvent(
|
|
||||||
event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent,
|
|
||||||
) {
|
|
||||||
EntityUpdatesHandler.throttleEntityUpdate(event, event.entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleBuiltEntityEvent(
|
|
||||||
event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent,
|
|
||||||
) {
|
|
||||||
EntityUpdatesHandler.throttleEntityUpdate(event, event.created_entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) {
|
|
||||||
const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area)
|
|
||||||
EntityUpdatesHandler.throttleResourceEntitiesUpdate(
|
|
||||||
Converters.eventNameString(event.name),
|
|
||||||
event.tick as Tick,
|
|
||||||
event.surface.index,
|
|
||||||
[event.position.x, event.position.y],
|
|
||||||
entities,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static throttleEntityUpdate(event: EntityUpdateEvent, entity: LuaEntity) {
|
|
||||||
|
|
||||||
if (entity.unit_number == undefined) {
|
|
||||||
// ignore for now - I'm not sure how to track entities without a unit_number
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const eventName = Converters.eventNameString(event.name)
|
|
||||||
|
|
||||||
const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = {
|
|
||||||
protoId: Converters.prototypeIdEntity(entity),
|
|
||||||
surfaceIndex: entity.surface.index,
|
|
||||||
chunkPosition: Converters.mapPositionToChunkPosition(entity.position)
|
|
||||||
}
|
|
||||||
|
|
||||||
const entityUpdate: FactorioEntityData.Standard = {
|
|
||||||
type: FactorioEntityData.Type.Standard,
|
|
||||||
protoId: Converters.prototypeIdEntity(entity),
|
|
||||||
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,
|
|
||||||
data => {
|
|
||||||
|
|
||||||
data.events ??= {}
|
|
||||||
data.events[eventName] ??= []
|
|
||||||
data.events[eventName].push(event.tick)
|
|
||||||
|
|
||||||
data.distinctEntities ??= {}
|
|
||||||
data.distinctEntities[entityKey] = entityUpdate
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static throttleResourceEntitiesUpdate(
|
|
||||||
eventName: EventName,
|
|
||||||
eventTick: Tick,
|
|
||||||
surfaceIndex: SurfaceIndex,
|
|
||||||
chunkPosition: MapChunkPosition,
|
|
||||||
entities: FactorioEntityData.Resource[],
|
|
||||||
) {
|
|
||||||
|
|
||||||
// first group by prototype ID
|
|
||||||
const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {}
|
|
||||||
|
|
||||||
for (const entity of entities) {
|
|
||||||
entitiesByProtoId[entity.protoId] ??= []
|
|
||||||
entitiesByProtoId[entity.protoId].push(entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) {
|
|
||||||
|
|
||||||
// create an update for each prototype
|
|
||||||
|
|
||||||
const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = {
|
|
||||||
protoId: protoId,
|
|
||||||
surfaceIndex: surfaceIndex,
|
|
||||||
chunkPosition: [chunkPosition[0], chunkPosition[1]],
|
|
||||||
}
|
|
||||||
|
|
||||||
EventDataCache.throttle<KafkatorioPacketData.MapChunkEntityUpdate>(
|
|
||||||
entityUpdateKey,
|
|
||||||
KafkatorioPacketData.Type.MapChunkEntityUpdate,
|
|
||||||
data => {
|
|
||||||
|
|
||||||
data.events ??= {}
|
|
||||||
data.events[eventName] ??= []
|
|
||||||
data.events[eventName].push(eventTick)
|
|
||||||
|
|
||||||
for (const entity of resourceEntities) {
|
|
||||||
const [x, y] = entity.position
|
|
||||||
const entityKey: string = `${x},${y}`
|
|
||||||
|
|
||||||
data.distinctEntities ??= {}
|
|
||||||
data.distinctEntities[entityKey] = entity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Get all resources on a tile-position */
|
|
||||||
private static getTileResourceEntities(
|
|
||||||
surface: LuaSurface,
|
|
||||||
mapPosition: MapPosition,
|
|
||||||
): FactorioEntityData.Resource[] {
|
|
||||||
|
|
||||||
const rawEntities = 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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Get all resources within a map-area */
|
|
||||||
private static getAreaResourceEntities(
|
|
||||||
surface: LuaSurface,
|
|
||||||
area: BoundingBoxTable,
|
|
||||||
): FactorioEntityData.Resource[] {
|
|
||||||
|
|
||||||
const rawEntities = 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const EntityUpdates = new EntityUpdatesHandler()
|
|
||||||
|
|
||||||
export default EntityUpdates
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => {
|
script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => {
|
||||||
log(`on_built_entity ${e.tick}`)
|
log(`on_built_entity ${e.tick}`)
|
||||||
|
|
@ -248,29 +22,3 @@ script.on_event(defines.events.on_robot_mined_entity, (e: OnRobotMinedEntityEven
|
||||||
log(`on_robot_mined_entity ${e.tick}`)
|
log(`on_robot_mined_entity ${e.tick}`)
|
||||||
EntityUpdates.handleMinedEntityEvent(e)
|
EntityUpdates.handleMinedEntityEvent(e)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
type EntityUpdateEvent =
|
|
||||||
| OnBuiltEntityEvent
|
|
||||||
|
|
||||||
| OnEntityClonedEvent
|
|
||||||
| OnEntityDamagedEvent
|
|
||||||
| OnEntityDestroyedEvent
|
|
||||||
| OnEntityDiedEvent
|
|
||||||
| OnEntityLogisticSlotChangedEvent
|
|
||||||
| OnEntityRenamedEvent
|
|
||||||
| OnEntitySettingsPastedEvent
|
|
||||||
| OnEntitySpawnedEvent
|
|
||||||
|
|
||||||
| OnPlayerMinedEntityEvent
|
|
||||||
| OnPlayerRepairedEntityEvent
|
|
||||||
| OnPlayerRotatedEntityEvent
|
|
||||||
|
|
||||||
| OnRobotMinedEntityEvent
|
|
||||||
| OnRobotBuiltEntityEvent
|
|
||||||
|
|
||||||
| OnPostEntityDiedEvent
|
|
||||||
| OnPreEntitySettingsPastedEvent
|
|
||||||
|
|
||||||
| OnSelectedEntityChangedEvent
|
|
||||||
| OnTriggerCreatedEntityEvent
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
import {
|
||||||
|
ConfigurationUpdateGameData,
|
||||||
|
ConfigurationUpdateModData,
|
||||||
|
KafkatorioPacketData
|
||||||
|
} from "../../../generated/kafkatorio-schema";
|
||||||
|
import PacketEmitter from "../../PacketEmitter";
|
||||||
|
import ConfigurationUpdate = KafkatorioPacketData.ConfigurationUpdate;
|
||||||
|
|
||||||
|
|
||||||
|
export class ConfigurationUpdateHandler {
|
||||||
|
|
||||||
|
|
||||||
|
emitConfigurationUpdate(changeData: ConfigurationChangedData) {
|
||||||
|
|
||||||
|
const configUpdateData: ConfigurationUpdate = {
|
||||||
|
type: KafkatorioPacketData.Type.ConfigurationUpdate,
|
||||||
|
migrationApplied: changeData.migration_applied,
|
||||||
|
modStartupSettingsChange: changeData.mod_startup_settings_changed,
|
||||||
|
allMods: ConfigurationUpdateHandler.allMods(changeData),
|
||||||
|
factorioData: ConfigurationUpdateHandler.factorioData(changeData)
|
||||||
|
}
|
||||||
|
|
||||||
|
PacketEmitter.emitInstantPacket(configUpdateData)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static factorioData(changeData: ConfigurationChangedData): ConfigurationUpdateGameData {
|
||||||
|
return {
|
||||||
|
oldVersion: changeData.old_version ?? null,
|
||||||
|
newVersion: changeData.new_version ?? null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static allMods(e: ConfigurationChangedData): ConfigurationUpdateModData[] {
|
||||||
|
|
||||||
|
let namesOfChangedMods: string[] = Object.keys(e.mod_changes)
|
||||||
|
let namesOfCurrentMods: string[] = Object.keys(script.active_mods)
|
||||||
|
|
||||||
|
let modNames = [...new Set<string>(
|
||||||
|
namesOfChangedMods.concat(namesOfCurrentMods)
|
||||||
|
)]
|
||||||
|
|
||||||
|
return modNames.map((modName) => {
|
||||||
|
|
||||||
|
let currentVer = script.active_mods[modName] ?? e.mod_changes[modName]?.new_version ?? null
|
||||||
|
let previousVer = e.mod_changes[modName]?.old_version ?? null
|
||||||
|
|
||||||
|
return {
|
||||||
|
modName: modName,
|
||||||
|
currentVersion: currentVer,
|
||||||
|
previousVersion: previousVer,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConfigurationUpdates = new ConfigurationUpdateHandler()
|
||||||
|
|
||||||
|
export default ConfigurationUpdates
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
import {
|
||||||
|
EventName,
|
||||||
|
FactorioEntityData,
|
||||||
|
KafkatorioPacketData,
|
||||||
|
MapChunkPosition, PrototypeId,
|
||||||
|
Tick
|
||||||
|
} from "../../../generated/kafkatorio-schema";
|
||||||
|
import {Converters} from "../converters";
|
||||||
|
import EventDataCache from "../../cache/EventDataCache";
|
||||||
|
|
||||||
|
|
||||||
|
export class EntityUpdatesHandler {
|
||||||
|
|
||||||
|
|
||||||
|
handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
|
||||||
|
|
||||||
|
const surface = game.get_surface(event.surface_index)
|
||||||
|
if (surface == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [chunkPos, tiles] of pairs(tilesByChunk)) {
|
||||||
|
|
||||||
|
const entities: FactorioEntityData.Resource[] = []
|
||||||
|
|
||||||
|
for (const tile in tiles) {
|
||||||
|
const resources: FactorioEntityData.Resource[] = EntityUpdatesHandler.getTileResourceEntities(surface, chunkPos)
|
||||||
|
for (const resource of resources) {
|
||||||
|
entities[entities.length] = resource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityUpdatesHandler.throttleResourceEntitiesUpdate(
|
||||||
|
Converters.eventNameString(event.name),
|
||||||
|
event.tick as Tick,
|
||||||
|
event.surface_index,
|
||||||
|
[chunkPos[0], chunkPos[1]],
|
||||||
|
entities,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleMinedEntityEvent(
|
||||||
|
event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent,
|
||||||
|
) {
|
||||||
|
EntityUpdatesHandler.throttleEntityUpdate(event, event.entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleBuiltEntityEvent(
|
||||||
|
event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent,
|
||||||
|
) {
|
||||||
|
EntityUpdatesHandler.throttleEntityUpdate(event, event.created_entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleChunkGeneratedEvent(event: OnChunkGeneratedEvent) {
|
||||||
|
const entities = EntityUpdatesHandler.getAreaResourceEntities(event.surface, event.area)
|
||||||
|
EntityUpdatesHandler.throttleResourceEntitiesUpdate(
|
||||||
|
Converters.eventNameString(event.name),
|
||||||
|
event.tick as Tick,
|
||||||
|
event.surface.index,
|
||||||
|
[event.position.x, event.position.y],
|
||||||
|
entities,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static throttleEntityUpdate(event: EntityUpdateEvent, entity: LuaEntity) {
|
||||||
|
|
||||||
|
if (entity.unit_number == undefined) {
|
||||||
|
// ignore for now - I'm not sure how to track entities without a unit_number
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const eventName = Converters.eventNameString(event.name)
|
||||||
|
|
||||||
|
const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = {
|
||||||
|
protoId: Converters.prototypeIdEntity(entity),
|
||||||
|
surfaceIndex: entity.surface.index,
|
||||||
|
chunkPosition: Converters.mapPositionToChunkPosition(entity.position)
|
||||||
|
}
|
||||||
|
|
||||||
|
const entityUpdate: FactorioEntityData.Standard = {
|
||||||
|
type: FactorioEntityData.Type.Standard,
|
||||||
|
protoId: Converters.prototypeIdEntity(entity),
|
||||||
|
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,
|
||||||
|
data => {
|
||||||
|
|
||||||
|
data.events ??= {}
|
||||||
|
data.events[eventName] ??= []
|
||||||
|
data.events[eventName].push(event.tick)
|
||||||
|
|
||||||
|
data.distinctEntities ??= {}
|
||||||
|
data.distinctEntities[entityKey] = entityUpdate
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static throttleResourceEntitiesUpdate(
|
||||||
|
eventName: EventName,
|
||||||
|
eventTick: Tick,
|
||||||
|
surfaceIndex: SurfaceIndex,
|
||||||
|
chunkPosition: MapChunkPosition,
|
||||||
|
entities: FactorioEntityData.Resource[],
|
||||||
|
) {
|
||||||
|
|
||||||
|
// first group by prototype ID
|
||||||
|
const entitiesByProtoId: { [protoId: PrototypeId]: FactorioEntityData.Resource[] } = {}
|
||||||
|
|
||||||
|
for (const entity of entities) {
|
||||||
|
entitiesByProtoId[entity.protoId] ??= []
|
||||||
|
entitiesByProtoId[entity.protoId].push(entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [protoId, resourceEntities] of pairs(entitiesByProtoId)) {
|
||||||
|
|
||||||
|
// create an update for each prototype
|
||||||
|
|
||||||
|
const entityUpdateKey: KafkatorioPacketData.MapChunkEntityUpdate["key"] = {
|
||||||
|
protoId: protoId,
|
||||||
|
surfaceIndex: surfaceIndex,
|
||||||
|
chunkPosition: [chunkPosition[0], chunkPosition[1]],
|
||||||
|
}
|
||||||
|
|
||||||
|
EventDataCache.throttle<KafkatorioPacketData.MapChunkEntityUpdate>(
|
||||||
|
entityUpdateKey,
|
||||||
|
KafkatorioPacketData.Type.MapChunkEntityUpdate,
|
||||||
|
data => {
|
||||||
|
|
||||||
|
data.events ??= {}
|
||||||
|
data.events[eventName] ??= []
|
||||||
|
data.events[eventName].push(eventTick)
|
||||||
|
|
||||||
|
for (const entity of resourceEntities) {
|
||||||
|
const [x, y] = entity.position
|
||||||
|
const entityKey: string = `${x},${y}`
|
||||||
|
|
||||||
|
data.distinctEntities ??= {}
|
||||||
|
data.distinctEntities[entityKey] = entity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Get all resources on a tile-position */
|
||||||
|
private static getTileResourceEntities(
|
||||||
|
surface: LuaSurface,
|
||||||
|
mapPosition: MapPosition,
|
||||||
|
): FactorioEntityData.Resource[] {
|
||||||
|
|
||||||
|
const rawEntities = 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Get all resources within a map-area */
|
||||||
|
private static getAreaResourceEntities(
|
||||||
|
surface: LuaSurface,
|
||||||
|
area: BoundingBoxTable,
|
||||||
|
): FactorioEntityData.Resource[] {
|
||||||
|
|
||||||
|
const rawEntities = 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const EntityUpdates = new EntityUpdatesHandler()
|
||||||
|
|
||||||
|
export default EntityUpdates
|
||||||
|
|
||||||
|
|
||||||
|
type EntityUpdateEvent =
|
||||||
|
| OnBuiltEntityEvent
|
||||||
|
|
||||||
|
| OnEntityClonedEvent
|
||||||
|
| OnEntityDamagedEvent
|
||||||
|
| OnEntityDestroyedEvent
|
||||||
|
| OnEntityDiedEvent
|
||||||
|
| OnEntityLogisticSlotChangedEvent
|
||||||
|
| OnEntityRenamedEvent
|
||||||
|
| OnEntitySettingsPastedEvent
|
||||||
|
| OnEntitySpawnedEvent
|
||||||
|
|
||||||
|
| OnPlayerMinedEntityEvent
|
||||||
|
| OnPlayerRepairedEntityEvent
|
||||||
|
| OnPlayerRotatedEntityEvent
|
||||||
|
|
||||||
|
| OnRobotMinedEntityEvent
|
||||||
|
| OnRobotBuiltEntityEvent
|
||||||
|
|
||||||
|
| OnPostEntityDiedEvent
|
||||||
|
| OnPreEntitySettingsPastedEvent
|
||||||
|
|
||||||
|
| OnSelectedEntityChangedEvent
|
||||||
|
| OnTriggerCreatedEntityEvent
|
||||||
|
|
@ -0,0 +1,242 @@
|
||||||
|
import {Converters} from "../converters";
|
||||||
|
import {isEventType} from "../eventTypeCheck";
|
||||||
|
import {
|
||||||
|
KafkatorioPacketData,
|
||||||
|
MapChunkPosition,
|
||||||
|
MinedProduct,
|
||||||
|
PrototypeKey
|
||||||
|
} from "../../../generated/kafkatorio-schema";
|
||||||
|
import EventUpdatesManager, {EventUpdates} from "../../cache/EventDataCache";
|
||||||
|
import {MapChunkUpdateEvent, MapTileChangeEvent} from "../mapChunkUpdates";
|
||||||
|
import PacketKey = EventUpdates.PacketKey;
|
||||||
|
import Type = MinedProduct.Type;
|
||||||
|
|
||||||
|
type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void
|
||||||
|
|
||||||
|
|
||||||
|
class MapChunkUpdateHandler {
|
||||||
|
|
||||||
|
handleChunkGeneratedEvent(
|
||||||
|
event: OnChunkGeneratedEvent,
|
||||||
|
expirationDurationTicks?: uint,
|
||||||
|
) {
|
||||||
|
const tiles = event.surface.find_tiles_filtered({area: event.area})
|
||||||
|
|
||||||
|
MapChunkUpdateHandler.mapTilesUpdateDebounce(
|
||||||
|
event.surface,
|
||||||
|
Converters.convertMapTablePosition(event.position),
|
||||||
|
tiles,
|
||||||
|
event,
|
||||||
|
undefined,
|
||||||
|
expirationDurationTicks,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) {
|
||||||
|
|
||||||
|
const surface = game.get_surface(event.surface_index)
|
||||||
|
if (surface == undefined) {
|
||||||
|
const eventName = Converters.eventNameString(event.name)
|
||||||
|
log(`[handleBuiltTileEvent] undefined surface ${eventName}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles)
|
||||||
|
const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles)
|
||||||
|
|
||||||
|
for (const [chunkPos, tiles] of groupedTiles) {
|
||||||
|
MapChunkUpdateHandler.mapTilesUpdateDebounce(
|
||||||
|
surface,
|
||||||
|
chunkPos,
|
||||||
|
tiles,
|
||||||
|
event,
|
||||||
|
(data => {
|
||||||
|
if (isEventType(event, defines.events.on_player_built_tile)) {
|
||||||
|
data.player = event.player_index
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (isEventType(event, defines.events.on_robot_built_tile)) {
|
||||||
|
data.robot = {
|
||||||
|
unitNumber: event.robot?.unit_number ?? null,
|
||||||
|
protoId: Converters.prototypeId(event.robot.type, event.robot.name),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// this line will not compile if the previous 'if' statements are not exhaustive
|
||||||
|
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
|
||||||
|
const exhaustiveCheck: never = event
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
|
||||||
|
const surface = game.get_surface(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 = MapChunkUpdateHandler.groupTiles(tiles)
|
||||||
|
|
||||||
|
for (const [chunkPos, tiles] of groupedTiles) {
|
||||||
|
|
||||||
|
MapChunkUpdateHandler.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,
|
||||||
|
protoId: Converters.prototypeId(event.robot.type, event.robot.name),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// this line will not compile if the previous 'if' statements are not exhaustive
|
||||||
|
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
|
||||||
|
const exhaustiveCheck: never = event
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handleScriptSetTilesEvent(event: ScriptRaisedSetTilesEvent) {
|
||||||
|
|
||||||
|
const surface = game.get_surface(event.surface_index)
|
||||||
|
if (surface == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const groupedTiles = MapChunkUpdateHandler.groupTiles(event.tiles)
|
||||||
|
|
||||||
|
for (const [chunkPos, tiles] of groupedTiles) {
|
||||||
|
MapChunkUpdateHandler.mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
handlePreChunkDeleted(event: OnPreChunkDeletedEvent) {
|
||||||
|
|
||||||
|
const surface = game.get_surface(event.surface_index)
|
||||||
|
if (surface == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const position of event.positions) {
|
||||||
|
const key: PacketKey<KafkatorioPacketData.MapChunkTileUpdate> = {
|
||||||
|
surfaceIndex: surface.index,
|
||||||
|
chunkPosition: [position.x, position.y],
|
||||||
|
}
|
||||||
|
|
||||||
|
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
||||||
|
key,
|
||||||
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
|
data => data.isDeleted = true,
|
||||||
|
0, // deletion is important - emit ASAP
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static mapTilesUpdateDebounce(
|
||||||
|
surface: LuaSurface | undefined,
|
||||||
|
chunkPosition: MapChunkPosition,
|
||||||
|
tiles: TileRead[],
|
||||||
|
event: MapChunkUpdateEvent | MapTileChangeEvent,
|
||||||
|
updater?: MapChunkTileUpdater,
|
||||||
|
expirationDurationTicks?: uint,
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (surface == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventName = Converters.eventNameString(event.name)
|
||||||
|
|
||||||
|
const key: KafkatorioPacketData.MapChunkTileUpdate["key"] = {
|
||||||
|
surfaceIndex: surface.index,
|
||||||
|
chunkPosition: chunkPosition,
|
||||||
|
}
|
||||||
|
|
||||||
|
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
||||||
|
key,
|
||||||
|
KafkatorioPacketData.Type.MapChunkTileUpdate,
|
||||||
|
data => {
|
||||||
|
|
||||||
|
// tile dictionary update
|
||||||
|
if (data.tileDictionary == undefined) {
|
||||||
|
data.tileDictionary = {
|
||||||
|
tilesXY: {},
|
||||||
|
protos: {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let protosCount: uint = table_size(data.tileDictionary.protos)
|
||||||
|
for (const tile of tiles) {
|
||||||
|
const protoId = Converters.prototypeId("tile", tile.name)
|
||||||
|
|
||||||
|
if (data.tileDictionary.protos[protoId] == null) {
|
||||||
|
|
||||||
|
}
|
||||||
|
data.tileDictionary.protos[protoId] ??= protosCount++ as PrototypeKey
|
||||||
|
|
||||||
|
const protoKey = data.tileDictionary.protos[protoId]
|
||||||
|
|
||||||
|
const xString = `${tile.position.x}`
|
||||||
|
const yString = `${tile.position.y}`
|
||||||
|
|
||||||
|
data.tileDictionary.tilesXY[xString] ??= {}
|
||||||
|
data.tileDictionary.tilesXY[xString][yString] = protoKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// events count update
|
||||||
|
data.events ??= {}
|
||||||
|
data.events[eventName] ??= []
|
||||||
|
data.events[eventName].push(event.tick)
|
||||||
|
|
||||||
|
// apply mutator
|
||||||
|
if (updater != undefined) {
|
||||||
|
updater(data)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
expirationDurationTicks,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static groupTiles(tiles: TileRead[]): Map<MapChunkPosition, TileRead[]> {
|
||||||
|
|
||||||
|
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)),
|
||||||
|
]
|
||||||
|
if (!mapChunkPositionToTiles.has(chunkPosition)) {
|
||||||
|
mapChunkPositionToTiles.set(chunkPosition, [])
|
||||||
|
}
|
||||||
|
mapChunkPositionToTiles.get(chunkPosition)?.push(tile)
|
||||||
|
}
|
||||||
|
return mapChunkPositionToTiles
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const MapChunkUpdate = new MapChunkUpdateHandler()
|
||||||
|
|
||||||
|
export default MapChunkUpdate
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import {KafkatorioPacketData} from "../../../generated/kafkatorio-schema";
|
||||||
|
import {Converters} from "../converters";
|
||||||
|
import EventUpdatesManager from "../../cache/EventDataCache";
|
||||||
|
|
||||||
|
|
||||||
|
export type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void
|
||||||
|
|
||||||
|
|
||||||
|
export type PlayerUpdateEvent =
|
||||||
|
| OnPlayerJoinedGameEvent
|
||||||
|
| OnPlayerChangedPositionEvent
|
||||||
|
| OnPlayerChangedSurfaceEvent
|
||||||
|
| OnPlayerDiedEvent
|
||||||
|
| OnPlayerBannedEvent
|
||||||
|
| OnPlayerUnbannedEvent
|
||||||
|
| OnPlayerKickedEvent
|
||||||
|
| OnPrePlayerLeftGameEvent
|
||||||
|
| OnPlayerRemovedEvent
|
||||||
|
|
||||||
|
|
||||||
|
export class PlayerUpdateHandler {
|
||||||
|
|
||||||
|
handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) {
|
||||||
|
this.playerUpdateThrottle(
|
||||||
|
event,
|
||||||
|
(player, data) => {
|
||||||
|
data.bannedReason = event.reason ?? null
|
||||||
|
Converters.playerOnlineInfo(player, data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
playerUpdateThrottle(
|
||||||
|
event: PlayerUpdateEvent,
|
||||||
|
mutate: PlayerUpdater,
|
||||||
|
expirationDurationTicks: uint | undefined = undefined,
|
||||||
|
) {
|
||||||
|
const playerIndex = event.player_index
|
||||||
|
if (playerIndex == undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventName = Converters.eventNameString(event.name)
|
||||||
|
|
||||||
|
EventUpdatesManager.throttle<KafkatorioPacketData.PlayerUpdate>(
|
||||||
|
{index: playerIndex},
|
||||||
|
KafkatorioPacketData.Type.PlayerUpdate,
|
||||||
|
data => {
|
||||||
|
const player = game.players[playerIndex]
|
||||||
|
if (player != undefined) {
|
||||||
|
mutate(player, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
data.events ??= {}
|
||||||
|
data.events[eventName] ??= []
|
||||||
|
data.events[eventName].push(event.tick)
|
||||||
|
},
|
||||||
|
expirationDurationTicks,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
playerUpdateImmediate(
|
||||||
|
event: PlayerUpdateEvent,
|
||||||
|
mutate: PlayerUpdater,
|
||||||
|
) {
|
||||||
|
this.playerUpdateThrottle(event, mutate, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const PlayerUpdates = new PlayerUpdateHandler()
|
||||||
|
|
||||||
|
export default PlayerUpdates
|
||||||
|
|
@ -1,17 +1,5 @@
|
||||||
import {isEventType} from "./eventTypeCheck";
|
import EntityUpdates from "./handlers/EntityUpdateHandler";
|
||||||
import {Converters} from "./converters";
|
import MapChunkUpdate from "./handlers/MapChunkUpdateHandler";
|
||||||
import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache";
|
|
||||||
import {
|
|
||||||
KafkatorioPacketData,
|
|
||||||
MapChunkPosition, PrototypeId,
|
|
||||||
PrototypeKey,
|
|
||||||
} from "../../generated/kafkatorio-schema";
|
|
||||||
import EntityUpdates from "./entityUpdates";
|
|
||||||
import CacheKey = EventUpdates.PacketKey;
|
|
||||||
import Type = KafkatorioPacketData.Type;
|
|
||||||
|
|
||||||
|
|
||||||
type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void
|
|
||||||
|
|
||||||
|
|
||||||
export type MapTileChangeEvent =
|
export type MapTileChangeEvent =
|
||||||
|
|
@ -29,242 +17,11 @@ export type MapChunkUpdateEvent =
|
||||||
| OnPreChunkDeletedEvent
|
| OnPreChunkDeletedEvent
|
||||||
|
|
||||||
|
|
||||||
class MapChunkUpdateHandler {
|
script.on_event(defines.events.on_chunk_generated, (e: OnChunkGeneratedEvent) => {
|
||||||
|
log(`on_chunk_generated ${e.tick}`)
|
||||||
handleChunkGeneratedEvent(
|
MapChunkUpdate.handleChunkGeneratedEvent(e)
|
||||||
event: OnChunkGeneratedEvent,
|
EntityUpdates.handleChunkGeneratedEvent(e)
|
||||||
expirationDurationTicks?: uint,
|
})
|
||||||
) {
|
|
||||||
const tiles = event.surface.find_tiles_filtered({area: event.area})
|
|
||||||
|
|
||||||
MapChunkUpdateHandler.mapTilesUpdateDebounce(
|
|
||||||
event.surface,
|
|
||||||
Converters.convertMapTablePosition(event.position),
|
|
||||||
tiles,
|
|
||||||
event,
|
|
||||||
undefined,
|
|
||||||
expirationDurationTicks,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) {
|
|
||||||
|
|
||||||
const surface = game.get_surface(event.surface_index)
|
|
||||||
if (surface == undefined) {
|
|
||||||
const eventName = Converters.eventNameString(event.name)
|
|
||||||
log(`[handleBuiltTileEvent] undefined surface ${eventName}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles)
|
|
||||||
const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles)
|
|
||||||
|
|
||||||
for (const [chunkPos, tiles] of groupedTiles) {
|
|
||||||
MapChunkUpdateHandler.mapTilesUpdateDebounce(
|
|
||||||
surface,
|
|
||||||
chunkPos,
|
|
||||||
tiles,
|
|
||||||
event,
|
|
||||||
(data => {
|
|
||||||
if (isEventType(event, defines.events.on_player_built_tile)) {
|
|
||||||
data.player = event.player_index
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (isEventType(event, defines.events.on_robot_built_tile)) {
|
|
||||||
data.robot = {
|
|
||||||
unitNumber: event.robot?.unit_number ?? null,
|
|
||||||
protoId: Converters.prototypeId(event.robot.type, event.robot.name),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// this line will not compile if the previous 'if' statements are not exhaustive
|
|
||||||
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
|
|
||||||
const exhaustiveCheck: never = event
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
|
|
||||||
const surface = game.get_surface(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 = MapChunkUpdateHandler.groupTiles(tiles)
|
|
||||||
|
|
||||||
for (const [chunkPos, tiles] of groupedTiles) {
|
|
||||||
|
|
||||||
MapChunkUpdateHandler.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,
|
|
||||||
protoId: Converters.prototypeId(event.robot.type, event.robot.name),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// this line will not compile if the previous 'if' statements are not exhaustive
|
|
||||||
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
|
|
||||||
const exhaustiveCheck: never = event
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleScriptSetTilesEvent(event: ScriptRaisedSetTilesEvent) {
|
|
||||||
|
|
||||||
const surface = game.get_surface(event.surface_index)
|
|
||||||
if (surface == undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupedTiles = MapChunkUpdateHandler.groupTiles(event.tiles)
|
|
||||||
|
|
||||||
for (const [chunkPos, tiles] of groupedTiles) {
|
|
||||||
MapChunkUpdateHandler.mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handlePreChunkDeleted(event: OnPreChunkDeletedEvent) {
|
|
||||||
|
|
||||||
const surface = game.get_surface(event.surface_index)
|
|
||||||
if (surface == undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const position of event.positions) {
|
|
||||||
const key: CacheKey<KafkatorioPacketData.MapChunkTileUpdate> = {
|
|
||||||
surfaceIndex: surface.index,
|
|
||||||
chunkPosition: [position.x, position.y],
|
|
||||||
}
|
|
||||||
|
|
||||||
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
|
||||||
key,
|
|
||||||
Type.MapChunkTileUpdate,
|
|
||||||
data => data.isDeleted = true,
|
|
||||||
0, // deletion is important - emit ASAP
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static mapTilesUpdateDebounce(
|
|
||||||
surface: LuaSurface | undefined,
|
|
||||||
chunkPosition: MapChunkPosition,
|
|
||||||
tiles: TileRead[],
|
|
||||||
event: MapChunkUpdateEvent | MapTileChangeEvent,
|
|
||||||
updater?: MapChunkTileUpdater,
|
|
||||||
expirationDurationTicks?: uint,
|
|
||||||
) {
|
|
||||||
|
|
||||||
if (surface == undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const eventName = Converters.eventNameString(event.name)
|
|
||||||
|
|
||||||
const key: KafkatorioPacketData.MapChunkTileUpdate["key"] = {
|
|
||||||
surfaceIndex: surface.index,
|
|
||||||
chunkPosition: chunkPosition,
|
|
||||||
}
|
|
||||||
|
|
||||||
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkTileUpdate>(
|
|
||||||
key,
|
|
||||||
Type.MapChunkTileUpdate,
|
|
||||||
data => {
|
|
||||||
|
|
||||||
// tile dictionary update
|
|
||||||
if (data.tileDictionary == undefined) {
|
|
||||||
data.tileDictionary = {
|
|
||||||
tilesXY: {},
|
|
||||||
protos: {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let protosCount: uint = table_size(data.tileDictionary.protos)
|
|
||||||
for (const tile of tiles) {
|
|
||||||
const protoId = Converters.prototypeId("tile", tile.name)
|
|
||||||
|
|
||||||
if (data.tileDictionary.protos[protoId] == null) {
|
|
||||||
|
|
||||||
}
|
|
||||||
data.tileDictionary.protos[protoId] ??= protosCount++ as PrototypeKey
|
|
||||||
|
|
||||||
const protoKey = data.tileDictionary.protos[protoId]
|
|
||||||
|
|
||||||
const xString = `${tile.position.x}`
|
|
||||||
const yString = `${tile.position.y}`
|
|
||||||
|
|
||||||
data.tileDictionary.tilesXY[xString] ??= {}
|
|
||||||
data.tileDictionary.tilesXY[xString][yString] = protoKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// events count update
|
|
||||||
data.events ??= {}
|
|
||||||
data.events[eventName] ??= []
|
|
||||||
data.events[eventName].push(event.tick)
|
|
||||||
|
|
||||||
// apply mutator
|
|
||||||
if (updater != undefined) {
|
|
||||||
updater(data)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
expirationDurationTicks,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static groupTiles(tiles: TileRead[]): Map<MapChunkPosition, TileRead[]> {
|
|
||||||
|
|
||||||
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)),
|
|
||||||
]
|
|
||||||
if (!mapChunkPositionToTiles.has(chunkPosition)) {
|
|
||||||
mapChunkPositionToTiles.set(chunkPosition, [])
|
|
||||||
}
|
|
||||||
mapChunkPositionToTiles.get(chunkPosition)?.push(tile)
|
|
||||||
}
|
|
||||||
return mapChunkPositionToTiles
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const MapChunkUpdate = new MapChunkUpdateHandler()
|
|
||||||
|
|
||||||
export default MapChunkUpdate
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
|
||||||
defines.events.on_chunk_generated,
|
|
||||||
(e: OnChunkGeneratedEvent) => {
|
|
||||||
log(`on_chunk_generated ${e.tick}`)
|
|
||||||
MapChunkUpdate.handleChunkGeneratedEvent(e)
|
|
||||||
EntityUpdates.handleChunkGeneratedEvent(e)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// script.on_event(
|
// script.on_event(
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,7 @@
|
||||||
import {Converters} from "./converters";
|
import {Converters} from "./converters";
|
||||||
import EventUpdatesManager from "../cache/EventDataCache";
|
|
||||||
import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema";
|
import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema";
|
||||||
import packetEmitter from "../PacketEmitter";
|
import packetEmitter from "../PacketEmitter";
|
||||||
import Type = KafkatorioPacketData.Type;
|
import PlayerUpdates from "./handlers/PlayerUpdateHandler";
|
||||||
|
|
||||||
|
|
||||||
type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void
|
|
||||||
|
|
||||||
|
|
||||||
type PlayerUpdateEvent =
|
|
||||||
| OnPlayerJoinedGameEvent
|
|
||||||
| OnPlayerChangedPositionEvent
|
|
||||||
| OnPlayerChangedSurfaceEvent
|
|
||||||
| OnPlayerDiedEvent
|
|
||||||
| OnPlayerBannedEvent
|
|
||||||
| OnPlayerUnbannedEvent
|
|
||||||
| OnPlayerKickedEvent
|
|
||||||
| OnPrePlayerLeftGameEvent
|
|
||||||
| OnPlayerRemovedEvent
|
|
||||||
|
|
||||||
|
|
||||||
function playerUpdateThrottle(
|
|
||||||
event: PlayerUpdateEvent,
|
|
||||||
mutate: PlayerUpdater,
|
|
||||||
expirationDurationTicks: uint | undefined = undefined,
|
|
||||||
) {
|
|
||||||
const playerIndex = event.player_index
|
|
||||||
if (playerIndex == undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const eventName = Converters.eventNameString(event.name)
|
|
||||||
|
|
||||||
EventUpdatesManager.throttle<KafkatorioPacketData.PlayerUpdate>(
|
|
||||||
{index: playerIndex },
|
|
||||||
Type.PlayerUpdate,
|
|
||||||
data => {
|
|
||||||
const player = game.players[playerIndex]
|
|
||||||
if (player != undefined) {
|
|
||||||
mutate(player, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.events ??= {}
|
|
||||||
data.events[eventName] ??= []
|
|
||||||
data.events[eventName].push(event.tick)
|
|
||||||
},
|
|
||||||
expirationDurationTicks,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function playerUpdateImmediate(
|
|
||||||
event: PlayerUpdateEvent,
|
|
||||||
mutate: PlayerUpdater,
|
|
||||||
) {
|
|
||||||
playerUpdateThrottle(event, mutate, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) {
|
// function playerUpdateDebounce(playerIndex: uint, mutate: PlayerUpdater) {
|
||||||
|
|
@ -68,154 +14,122 @@ function playerUpdateImmediate(
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function playerOnlineInfo(player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) {
|
|
||||||
data.lastOnline = player.last_online
|
|
||||||
data.onlineTime = player.online_time
|
|
||||||
data.afkTime = player.afk_time
|
|
||||||
data.isConnected = player.connected
|
|
||||||
}
|
|
||||||
|
|
||||||
script.on_event(
|
script.on_event(defines.events.on_player_joined_game, (e: OnPlayerJoinedGameEvent) => {
|
||||||
defines.events.on_player_joined_game,
|
PlayerUpdates.playerUpdateThrottle(
|
||||||
(e: OnPlayerJoinedGameEvent) => {
|
e,
|
||||||
playerUpdateThrottle(
|
|
||||||
e,
|
|
||||||
(player, data) => {
|
|
||||||
data.isAdmin = player.admin
|
|
||||||
data.characterUnitNumber = player.character?.unit_number ?? null
|
|
||||||
data.chatColour = Converters.mapColour(player.chat_color)
|
|
||||||
data.colour = Converters.mapColour(player.color)
|
|
||||||
data.forceIndex = player.force.index as ForceIndex
|
|
||||||
data.name = player.name
|
|
||||||
data.isShowOnMap = player.show_on_map
|
|
||||||
data.isSpectator = player.spectator
|
|
||||||
data.surfaceIndex = player.surface.index
|
|
||||||
data.tag = player.tag
|
|
||||||
playerOnlineInfo(player, data)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
|
||||||
defines.events.on_player_changed_position,
|
|
||||||
(e: OnPlayerChangedPositionEvent) => {
|
|
||||||
playerUpdateThrottle(
|
|
||||||
e,
|
|
||||||
(player, data) => {
|
|
||||||
data.position = [player.position.x, player.position.y]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
|
||||||
defines.events.on_player_changed_surface,
|
|
||||||
(e: OnPlayerChangedSurfaceEvent) => {
|
|
||||||
playerUpdateThrottle(
|
|
||||||
e,
|
|
||||||
(player, data) => {
|
|
||||||
data.position = [player.position.x, player.position.y]
|
|
||||||
data.surfaceIndex = player.surface.index
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
|
||||||
defines.events.on_player_died,
|
|
||||||
(e: OnPlayerDiedEvent) => {
|
|
||||||
playerUpdateThrottle(
|
|
||||||
e,
|
|
||||||
(player, data) => {
|
|
||||||
data.ticksToRespawn = player.ticks_to_respawn ?? null
|
|
||||||
playerOnlineInfo(player, data)
|
|
||||||
if (e.cause != undefined) {
|
|
||||||
data.diedCause = {
|
|
||||||
unitNumber: e.cause.unit_number ?? null,
|
|
||||||
protoId: Converters.prototypeId(e.cause.type, e.cause.name),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
script.on_event(defines.events.on_player_banned, handleBannedEvent)
|
|
||||||
script.on_event(defines.events.on_player_unbanned, handleBannedEvent)
|
|
||||||
|
|
||||||
function handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) {
|
|
||||||
playerUpdateThrottle(
|
|
||||||
event,
|
|
||||||
(player, data) => {
|
(player, data) => {
|
||||||
data.bannedReason = event.reason ?? null
|
data.isAdmin = player.admin
|
||||||
playerOnlineInfo(player, data)
|
data.characterUnitNumber = player.character?.unit_number ?? null
|
||||||
|
data.chatColour = Converters.mapColour(player.chat_color)
|
||||||
|
data.colour = Converters.mapColour(player.color)
|
||||||
|
data.forceIndex = player.force.index as ForceIndex
|
||||||
|
data.name = player.name
|
||||||
|
data.isShowOnMap = player.show_on_map
|
||||||
|
data.isSpectator = player.spectator
|
||||||
|
data.surfaceIndex = player.surface.index
|
||||||
|
data.tag = player.tag
|
||||||
|
Converters.playerOnlineInfo(player, data)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
})
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
script.on_event(defines.events.on_player_changed_position, (e: OnPlayerChangedPositionEvent) => {
|
||||||
defines.events.on_player_kicked,
|
PlayerUpdates.playerUpdateThrottle(
|
||||||
(event: OnPlayerKickedEvent) => {
|
e,
|
||||||
log(`on_player_kicked ${event.tick} ${event.name}`)
|
(player, data) => {
|
||||||
playerUpdateImmediate(
|
data.position = [player.position.x, player.position.y]
|
||||||
event,
|
}
|
||||||
(player, data) => {
|
)
|
||||||
data.kickedReason = event.reason ?? null
|
})
|
||||||
playerOnlineInfo(player, data)
|
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_player_changed_surface, (e: OnPlayerChangedSurfaceEvent) => {
|
||||||
|
PlayerUpdates.playerUpdateThrottle(
|
||||||
|
e,
|
||||||
|
(player, data) => {
|
||||||
|
data.position = [player.position.x, player.position.y]
|
||||||
|
data.surfaceIndex = player.surface.index
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_player_died, (e: OnPlayerDiedEvent) => {
|
||||||
|
PlayerUpdates.playerUpdateThrottle(
|
||||||
|
e,
|
||||||
|
(player, data) => {
|
||||||
|
data.ticksToRespawn = player.ticks_to_respawn ?? null
|
||||||
|
Converters.playerOnlineInfo(player, data)
|
||||||
|
if (e.cause != undefined) {
|
||||||
|
data.diedCause = {
|
||||||
|
unitNumber: e.cause.unit_number ?? null,
|
||||||
|
protoId: Converters.prototypeId(e.cause.type, e.cause.name),
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_player_banned, (event: OnPlayerBannedEvent) => {
|
||||||
|
PlayerUpdates.handleBannedEvent(event)
|
||||||
|
})
|
||||||
|
script.on_event(defines.events.on_player_unbanned, (event: OnPlayerBannedEvent) => {
|
||||||
|
PlayerUpdates.handleBannedEvent(event)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_player_kicked, (event: OnPlayerKickedEvent) => {
|
||||||
|
log(`on_player_kicked ${event.tick} ${event.name}`)
|
||||||
|
PlayerUpdates.playerUpdateImmediate(
|
||||||
|
event,
|
||||||
|
(player, data) => {
|
||||||
|
data.kickedReason = event.reason ?? null
|
||||||
|
Converters.playerOnlineInfo(player, data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_pre_player_left_game, (event: OnPrePlayerLeftGameEvent) => {
|
||||||
|
log(`on_pre_player_left_game ${event.tick} ${event.name}`)
|
||||||
|
|
||||||
|
const playerUpdateKey: PlayerUpdateKey = {
|
||||||
|
index: event.player_index,
|
||||||
|
}
|
||||||
|
|
||||||
|
const playerUpdate: KafkatorioPacketData.PlayerUpdate = {
|
||||||
|
type: KafkatorioPacketData.Type.PlayerUpdate,
|
||||||
|
key: playerUpdateKey,
|
||||||
|
disconnectReason: disconnectReasons.get(event.reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
packetEmitter.emitKeyedPacket(playerUpdate)
|
||||||
|
|
||||||
|
// playerUpdateImmediate(
|
||||||
|
// event,
|
||||||
|
// (player, data) => {
|
||||||
|
// data.disconnectReason = disconnectReasons.get(event.reason)
|
||||||
|
// playerOnlineInfo(player, data)
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
})
|
||||||
|
|
||||||
|
script.on_event(defines.events.on_player_removed, (event: OnPlayerRemovedEvent) => {
|
||||||
|
log(`on_player_removed ${event.tick} ${event.name}`)
|
||||||
|
PlayerUpdates.playerUpdateImmediate(
|
||||||
|
event,
|
||||||
|
(player, data) => {
|
||||||
|
data.isRemoved = true
|
||||||
|
Converters.playerOnlineInfo(player, data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
const disconnectReasons = new LuaTable<defines.disconnect_reason, keyof typeof defines.disconnect_reason>()
|
const disconnectReasons = new LuaTable<defines.disconnect_reason, keyof typeof defines.disconnect_reason>()
|
||||||
for (const [name, disconnectId] of pairs(defines.disconnect_reason)) {
|
for (const [name, disconnectId] of pairs(defines.disconnect_reason)) {
|
||||||
disconnectReasons.set(disconnectId, name)
|
disconnectReasons.set(disconnectId, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
script.on_event(
|
|
||||||
defines.events.on_pre_player_left_game,
|
|
||||||
(event: OnPrePlayerLeftGameEvent) => {
|
|
||||||
log(`on_pre_player_left_game ${event.tick} ${event.name}`)
|
|
||||||
|
|
||||||
const playerUpdateKey: PlayerUpdateKey = {
|
|
||||||
index: event.player_index ,
|
|
||||||
}
|
|
||||||
|
|
||||||
const playerUpdate: KafkatorioPacketData.PlayerUpdate = {
|
|
||||||
type: KafkatorioPacketData.Type.PlayerUpdate,
|
|
||||||
key: playerUpdateKey,
|
|
||||||
disconnectReason: disconnectReasons.get(event.reason)
|
|
||||||
}
|
|
||||||
|
|
||||||
packetEmitter.emitKeyedPacket(playerUpdate)
|
|
||||||
|
|
||||||
// playerUpdateImmediate(
|
|
||||||
// event,
|
|
||||||
// (player, data) => {
|
|
||||||
// data.disconnectReason = disconnectReasons.get(event.reason)
|
|
||||||
// playerOnlineInfo(player, data)
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
script.on_event(
|
|
||||||
defines.events.on_player_removed,
|
|
||||||
(event: OnPlayerRemovedEvent) => {
|
|
||||||
log(`on_player_removed ${event.tick} ${event.name}`)
|
|
||||||
playerUpdateImmediate(
|
|
||||||
event,
|
|
||||||
(player, data) => {
|
|
||||||
data.isRemoved = true
|
|
||||||
playerOnlineInfo(player, data)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,48 @@
|
||||||
import PacketEmitter from "../PacketEmitter";
|
import PacketEmitter from "../PacketEmitter";
|
||||||
import {FactorioPrototype, KafkatorioPacketData} from "../../generated/kafkatorio-schema";
|
import {
|
||||||
|
EntityItemGroup,
|
||||||
|
FactorioPrototype,
|
||||||
|
KafkatorioPacketData
|
||||||
|
} from "../../generated/kafkatorio-schema";
|
||||||
import {Converters} from "./converters";
|
import {Converters} from "./converters";
|
||||||
import PrototypesUpdate = KafkatorioPacketData.PrototypesUpdate;
|
|
||||||
|
|
||||||
|
type PrototypesByType<T extends FactorioPrototype> = LuaTable<string, T[]>
|
||||||
|
|
||||||
|
|
||||||
export function emitPrototypes() {
|
export function emitPrototypes() {
|
||||||
|
|
||||||
const data: PrototypesUpdate = {
|
const mapTileProtos: PrototypesByType<FactorioPrototype.MapTile> = getMapTilePrototypes()
|
||||||
prototypes: prototypeUpdates(),
|
emit(mapTileProtos)
|
||||||
type: KafkatorioPacketData.Type.PrototypesUpdate,
|
|
||||||
|
|
||||||
|
game.item_group_prototypes
|
||||||
|
game.item_subgroup_prototypes
|
||||||
|
|
||||||
|
|
||||||
|
const entityProtos: PrototypesByType<FactorioPrototype.Entity> = getEntityPrototypes()
|
||||||
|
emit(entityProtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function emit<T extends FactorioPrototype>(protosByType: PrototypesByType<T>) {
|
||||||
|
for (const [, protos] of pairs(protosByType)) {
|
||||||
|
PacketEmitter.emitInstantPacket({
|
||||||
|
type: KafkatorioPacketData.Type.PrototypesUpdate,
|
||||||
|
prototypes: protos,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getMapTilePrototypes(): PrototypesByType<FactorioPrototype.MapTile> {
|
||||||
|
const tiles = new LuaTable<string, FactorioPrototype.MapTile[]>()
|
||||||
|
if (!tiles.has("tile")) {
|
||||||
|
tiles.set("tile", [])
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketEmitter.emitInstantPacket(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function prototypeUpdates(): FactorioPrototype[] {
|
|
||||||
let prototypes: FactorioPrototype[] = []
|
|
||||||
|
|
||||||
prototypes.push(...getMapTilePrototypes())
|
|
||||||
|
|
||||||
return prototypes
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getMapTilePrototypes(): FactorioPrototype.MapTile[] {
|
|
||||||
let tiles: FactorioPrototype.MapTile[] = []
|
|
||||||
for (const [, tile] of game.tile_prototypes) {
|
for (const [, tile] of game.tile_prototypes) {
|
||||||
tiles.push({
|
tiles.get("tile").push({
|
||||||
type: FactorioPrototype.Type.MapTile,
|
type: FactorioPrototype.Type.MapTile,
|
||||||
|
|
||||||
protoId: Converters.prototypeId("tile", tile.name),
|
protoId: Converters.prototypeId("tile", tile.name),
|
||||||
|
|
@ -42,19 +57,59 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// function getEntityPrototypes(): FactorioPrototype.MapTile[] {
|
function getEntityPrototypes(): PrototypesByType<FactorioPrototype.Entity> {
|
||||||
// let tiles: FactorioPrototype.MapTile[] = []
|
const protos = new LuaTable<string, FactorioPrototype.Entity[]>()
|
||||||
// for (const [, tile] of game.tile_prototypes) {
|
|
||||||
// tiles.push({
|
for (const [, entity] of game.entity_prototypes) {
|
||||||
// type: FactorioPrototype.Type.MapTile,
|
const key: string = `${entity.group.name}/${entity.subgroup.name}`
|
||||||
//
|
|
||||||
// name: tile.name,
|
if (!protos.has(key)) {
|
||||||
// order: tile.order,
|
protos.set(key, [])
|
||||||
// layer: tile.layer,
|
}
|
||||||
// collisionMasks: convertCollisionMaskToNames(tile.collision_mask),
|
|
||||||
// mapColour: Converters.mapColour(tile.map_color),
|
const entityProto: FactorioPrototype.Entity = {
|
||||||
// canBeMined: tile.mineable_properties.minable,
|
type: FactorioPrototype.Type.Entity,
|
||||||
// })
|
protoId: Converters.prototypeId(entity.type, entity.name),
|
||||||
// }
|
|
||||||
// return tiles
|
group: convertItemGroup(entity.group),
|
||||||
// }
|
subgroup: convertItemSubgroup(entity.subgroup),
|
||||||
|
|
||||||
|
isBuilding: entity.is_building,
|
||||||
|
isEntityWithOwner: entity.is_entity_with_owner,
|
||||||
|
isMilitaryTarget: entity.is_military_target,
|
||||||
|
maxHealth: entity.max_health,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.map_color != undefined) {
|
||||||
|
entityProto.mapColour = Converters.mapColour(entity.map_color)
|
||||||
|
}
|
||||||
|
if (entity.friendly_map_color != undefined) {
|
||||||
|
entityProto.mapColourFriend = Converters.mapColour(entity.friendly_map_color)
|
||||||
|
}
|
||||||
|
if (entity.enemy_map_color != undefined) {
|
||||||
|
entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color)
|
||||||
|
}
|
||||||
|
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
|
||||||
|
|
||||||
|
protos.get(key).push(entityProto)
|
||||||
|
}
|
||||||
|
return protos
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function convertItemGroup(itemGroup: LuaGroup): EntityItemGroup {
|
||||||
|
return {
|
||||||
|
name: itemGroup.name,
|
||||||
|
type: itemGroup.type,
|
||||||
|
parentName: null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function convertItemSubgroup(itemGroup: LuaGroup): EntityItemGroup {
|
||||||
|
return {
|
||||||
|
name: itemGroup.name,
|
||||||
|
type: itemGroup.type,
|
||||||
|
parentName: itemGroup.group?.name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import {isEventType} from "./eventTypeCheck";
|
||||||
import {Converters} from "./converters";
|
import {Converters} from "./converters";
|
||||||
import {handleSurfaceUpdate} from "./surfaceUpdates";
|
import {handleSurfaceUpdate} from "./surfaceUpdates";
|
||||||
import EventCacheService from "../cache/EventDataCache";
|
import EventCacheService from "../cache/EventDataCache";
|
||||||
import MapChunkUpdate from "./mapChunkUpdates";
|
import MapChunkUpdate from "./handlers/MapChunkUpdateHandler";
|
||||||
|
|
||||||
|
|
||||||
script.on_event(
|
script.on_event(
|
||||||
|
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
// import {isEventType} from "./eventTypeCheck";
|
|
||||||
// import {Converters} from "./converters";
|
|
||||||
// import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache";
|
|
||||||
// import {
|
|
||||||
// KafkatorioPacketData,
|
|
||||||
// MapChunkPosition,
|
|
||||||
// PrototypeKey,
|
|
||||||
// } from "../../generated/kafkatorio-schema";
|
|
||||||
// import CacheKey = EventUpdates.PacketKey;
|
|
||||||
// import Type = KafkatorioPacketData.Type;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// export class ResourceEntityUpdatesHandler {
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// handleChunkGeneratedEvent(
|
|
||||||
// event: OnChunkGeneratedEvent,
|
|
||||||
// expirationDurationTicks?: uint,
|
|
||||||
// ) {
|
|
||||||
// const resourceEntities = this.getAreaResourceEntities(event.surface, event.area)
|
|
||||||
//
|
|
||||||
// mapTilesUpdateDebounce(
|
|
||||||
// event.surface,
|
|
||||||
// Converters.convertMapTablePosition(event.position),
|
|
||||||
// tiles,
|
|
||||||
// event,
|
|
||||||
// undefined,
|
|
||||||
// expirationDurationTicks,
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// private resourceEntityUpdatesThrottle(
|
|
||||||
// surface: LuaSurface | undefined,
|
|
||||||
// chunkPosition: MapChunkPosition,
|
|
||||||
// tiles: TileRead[],
|
|
||||||
// event: MapTileUpdateEvent,
|
|
||||||
// updater?: MapChunkUpdater,
|
|
||||||
// expirationDurationTicks?: uint,
|
|
||||||
// ) {
|
|
||||||
//
|
|
||||||
// if (surface == undefined) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const eventName = Converters.eventNameString(event.name)
|
|
||||||
//
|
|
||||||
// const key: KafkatorioPacketData.ResourceEntitiesUpdate["key"] = {
|
|
||||||
// surfaceIndex: surface.index as SurfaceIndex,
|
|
||||||
// chunkPosition: chunkPosition,
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// EventUpdatesManager.throttle<KafkatorioPacketData.ResourceEntitiesUpdate>(
|
|
||||||
// key,
|
|
||||||
// Type.MapChunkUpdate,
|
|
||||||
// data => {
|
|
||||||
//
|
|
||||||
// // tile dictionary update
|
|
||||||
// if (data.tileDictionary == undefined) {
|
|
||||||
// data.tileDictionary = {
|
|
||||||
// tilesXY: {},
|
|
||||||
// protos: {},
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let protosCount: uint = table_size(data.tileDictionary.protos)
|
|
||||||
// for (const tile of tiles) {
|
|
||||||
// const tileName = tile.name as PrototypeIdMapTile
|
|
||||||
// const protoKey = protosCount++ as PrototypeKey
|
|
||||||
// data.tileDictionary.protos[tileName] ??= protoKey
|
|
||||||
//
|
|
||||||
// const xString = `${tile.position.x}`
|
|
||||||
// const yString = `${tile.position.y}`
|
|
||||||
//
|
|
||||||
// data.tileDictionary.tilesXY[xString] ??= {}
|
|
||||||
// data.tileDictionary.tilesXY[xString][yString] = protoKey
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // events count update
|
|
||||||
// data.events ??= {}
|
|
||||||
// data.events[eventName] ??= []
|
|
||||||
// data.events[eventName].push(event.tick)
|
|
||||||
//
|
|
||||||
// // apply mutator
|
|
||||||
// if (updater != undefined) {
|
|
||||||
// updater(data)
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// expirationDurationTicks,
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// const ResourceEntityUpdates = new ResourceEntityUpdatesHandler()
|
|
||||||
//
|
|
||||||
// export default ResourceEntityUpdates
|
|
||||||
|
|
@ -211,16 +211,15 @@ fun KTable<ServerMapChunkId, ServerMapChunkTiles<ColourHex>>.streamMapChunkColou
|
||||||
val pid = "$pid.output-chunk.${chunkSize.name}"
|
val pid = "$pid.output-chunk.${chunkSize.name}"
|
||||||
|
|
||||||
toStream("$pid.stream")
|
toStream("$pid.stream")
|
||||||
.filter("$pid.filter-tiles-not-empty") { _, v ->
|
.filter("$pid.filter-tiles-not-empty") { _, chunkTiles ->
|
||||||
!v?.map.isNullOrEmpty()
|
!chunkTiles?.map.isNullOrEmpty()
|
||||||
}
|
}
|
||||||
.mapValues("$pid.map-not-null") { _, v ->
|
.mapValues("$pid.map-not-null") { _, chunkTiles ->
|
||||||
requireNotNull(v)
|
requireNotNull(chunkTiles)
|
||||||
}
|
}
|
||||||
.peek("$pid.print-group-result") { _, v ->
|
.peek("$pid.print-group-result") { _, chunkTiles ->
|
||||||
println("Grouping map tiles result: ${v.chunkId} / ${v.map.size}")
|
println("Grouping map tiles result: ${chunkTiles.chunkId} / size:${chunkTiles.map.size}")
|
||||||
}
|
}.to(
|
||||||
.to(
|
|
||||||
outputTopic,
|
outputTopic,
|
||||||
producedAs(
|
producedAs(
|
||||||
"$pid.grouped-map-chunks",
|
"$pid.grouped-map-chunks",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue