massive refactor to export entities (buildings and resources)
- minor version bumps - new Factorio version - use both prototype name and type to identify a prototype - kxs-ts-gen: use BrandTyping, but exclude some identifiers - kxs-ts-gen: manually create zip dist, so it can run after the project compiles - mod: use typed-factorio strict types - mod: refactor event handlers to be a little more consistent and object-oriented
This commit is contained in:
parent
88982d818a
commit
90dc520d22
62 changed files with 2629 additions and 713 deletions
|
|
@ -18,12 +18,14 @@ fun Configuration.asProvider() {
|
|||
isCanBeConsumed = true
|
||||
}
|
||||
|
||||
|
||||
fun Configuration.asConsumer() {
|
||||
isVisible = false
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
|
||||
|
||||
fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration =
|
||||
attributes {
|
||||
attribute(USAGE_ATTRIBUTE, objects.named("factorio"))
|
||||
|
|
@ -32,6 +34,7 @@ fun Configuration.factorioModAttributes(objects: ObjectFactory): Configuration =
|
|||
attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.EMBEDDED))
|
||||
}
|
||||
|
||||
|
||||
fun Configuration.typescriptAttributes(objects: ObjectFactory): Configuration =
|
||||
attributes {
|
||||
attribute(USAGE_ATTRIBUTE, objects.named("typescript"))
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ import org.gradle.api.file.FileSystemOperations
|
|||
import org.gradle.api.tasks.JavaExec
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.work.DisableCachingByDefault
|
||||
|
||||
|
||||
@DisableCachingByDefault(because = "caching makes regenerating more difficult")
|
||||
abstract class GenerateTypeScriptTask @Inject constructor(
|
||||
private val fileOps: FileSystemOperations,
|
||||
) : JavaExec() {
|
||||
|
|
|
|||
|
|
@ -16,20 +16,22 @@ kvision = "5.11.0"
|
|||
log4j2 = "2.17.2"
|
||||
qosLogback = "1.2.11"
|
||||
slf4j = "1.7.36"
|
||||
okio = "3.1.0"
|
||||
okio = "3.2.0"
|
||||
scrimage = "4.0.31"
|
||||
semver = "1.2.0"
|
||||
|
||||
kotlinx-serialization = "1.3.3"
|
||||
kxs-charleskornKaml = "0.44.0"
|
||||
kxs-mamoeYamlkt = "0.12.0"
|
||||
kxs-kxsTsGen = "0.2.1"
|
||||
|
||||
kotlinJsWrappers = "1.0.0-pre.346"
|
||||
kotlinJsWrappers = "1.0.0-pre.349" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom
|
||||
|
||||
kotlinx-cli = "0.3.4"
|
||||
kotlinx-coroutines = "1.6.3"
|
||||
kotlinx-datetime = "0.3.3"
|
||||
kotlinx-html = "0.7.5"
|
||||
kotlinx-nodejs = "0.0.7"
|
||||
kotlinx-coroutines = "1.6.1"
|
||||
kotlinx-cli = "0.3.4"
|
||||
kotlinx-datetime = "0.3.3"
|
||||
|
||||
ktor = "2.0.3"
|
||||
|
||||
|
|
@ -39,20 +41,24 @@ simpleSyslogParser = "0.0.6"
|
|||
|
||||
kotkaStreams = "dev-SNAPSHOT"
|
||||
|
||||
|
||||
## test ##
|
||||
junit = "5.8.2"
|
||||
kotest = "5.3.1"
|
||||
mockk = "1.12.4"
|
||||
|
||||
|
||||
## infra ##
|
||||
factorio = "1.1.59"
|
||||
factorio = "1.1.61"
|
||||
confluent-kafkaConnect = "7.0.1"
|
||||
grafana = "8.5.0"
|
||||
prometheus = "v2.34.0"
|
||||
|
||||
|
||||
## gradle plugins ##
|
||||
gradleNodePlugin = "3.3.0" # https://github.com/node-gradle/gradle-node-plugin/releases
|
||||
|
||||
|
||||
#########
|
||||
[plugins]
|
||||
#########
|
||||
|
|
@ -89,8 +95,10 @@ kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "ko
|
|||
kotlinx-serialization-properties = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-properties" }
|
||||
kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf" }
|
||||
|
||||
kxs-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" }
|
||||
kxs-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" }
|
||||
kxs-charleskornKaml = { group = "com.charleskorn.kaml", name = "kaml", version.ref = "kxs-charleskornKaml" }
|
||||
kxs-mamoeYamlkt = { group = "net.mamoe.yamlkt", name = "yamlkt", version.ref = "kxs-mamoeYamlkt" }
|
||||
#kxs-kxsTsGen = { group = "dev.adamko.kxstsgen", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" }
|
||||
kxs-kxsTsGen = { group = "com.github.adamko-dev.kotlinx-serialization-typescript-generator", name = "kxs-ts-gen-core", version.ref = "kxs-kxsTsGen" }
|
||||
|
||||
|
||||
kotlinx-coroutines-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-bom", version.ref = "kotlinx-coroutines" }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import dev.adamko.kafkatorio.gradle.asProvider
|
||||
import dev.adamko.kafkatorio.gradle.typescriptAttributes
|
||||
import dev.adamko.kafkatorio.task.GenerateTypeScriptTask
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJvmCompilation
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
|
||||
plugins {
|
||||
|
|
@ -36,6 +39,7 @@ kotlin {
|
|||
all {
|
||||
languageSettings.apply {
|
||||
optIn("kotlin.ExperimentalStdlibApi")
|
||||
optIn("kotlin.ExperimentalUnsignedTypes")
|
||||
optIn("kotlin.RequiresOptIn")
|
||||
optIn("kotlin.js.ExperimentalJsExport")
|
||||
optIn("kotlin.time.ExperimentalTime")
|
||||
|
|
@ -51,7 +55,7 @@ kotlin {
|
|||
implementation(project.dependencies.platform(libs.kotlinx.serialization.bom))
|
||||
implementation(libs.kotlinx.serialization.core)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
api("dev.adamko.kxstsgen:kxs-ts-gen-core:0.1.3")
|
||||
api(libs.kxs.kxsTsGen)
|
||||
|
||||
implementation(dependencies.platform(libs.okio.bom))
|
||||
implementation(libs.okio.core)
|
||||
|
|
@ -96,16 +100,34 @@ kotlin {
|
|||
}
|
||||
|
||||
|
||||
val kotlinJvmMainCompilation: NamedDomainObjectProvider<KotlinJvmCompilation> =
|
||||
kotlin.jvm().compilations.named(KotlinCompilation.MAIN_COMPILATION_NAME)
|
||||
|
||||
|
||||
val jvmJar: TaskProvider<Jar> = tasks.named<Jar>(kotlin.jvm().artifactsTaskName)
|
||||
val mainCompilation: Provider<FileCollection> =
|
||||
kotlin.jvm().compilations.named("main").map { it.runtimeDependencyFiles }
|
||||
|
||||
val kotlinMainRuntimeDependencies: Provider<FileCollection> =
|
||||
kotlinJvmMainCompilation.map { it.runtimeDependencyFiles }
|
||||
|
||||
val kotlinMainCompileDependencies: Provider<FileCollection> =
|
||||
kotlinJvmMainCompilation.map { it.compileDependencyFiles }
|
||||
|
||||
val kotlinMainCompileTask: Provider<KotlinCompile> =
|
||||
kotlinJvmMainCompilation.map { it.compileKotlinTask }
|
||||
|
||||
|
||||
val generateTypeScript by tasks.registering(GenerateTypeScriptTask::class) {
|
||||
dependsOn(jvmJar)
|
||||
// dependsOn(kotlinMainCompileTask)
|
||||
|
||||
// inputs.files(jvmJar.map { it.outputs.files })
|
||||
// inputs.files(kotlinMainCompileTask.map { it.javaSources })
|
||||
|
||||
classpath(
|
||||
jvmJar,
|
||||
mainCompilation,
|
||||
kotlinMainRuntimeDependencies,
|
||||
// kotlinMainCompileTask.map { it.libraries }
|
||||
// kotlinMainDependencies,
|
||||
)
|
||||
output.set(layout.buildDirectory.dir("generated/typescript"))
|
||||
mainClass.set("dev.adamko.kafkatorio.events.schema.Kt2ts2Kt")
|
||||
|
|
@ -122,16 +144,26 @@ val generateTypeScriptOutputFiles: Provider<FileTree> =
|
|||
generateTypeScript.map { it.outputs.files.asFileTree }
|
||||
|
||||
|
||||
val schemaTs by distributions.registering {
|
||||
distributionBaseName.set(schemaTsDistributionName)
|
||||
contents {
|
||||
from(generateTypeScriptOutputFiles)
|
||||
}
|
||||
//val schemaTs by distributions.registering {
|
||||
// distributionBaseName.set(schemaTsDistributionName)
|
||||
// contents {
|
||||
// from(generateTypeScriptOutputFiles)
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//val schemaTsZipTask: TaskProvider<Zip> = tasks.named<Zip>("${schemaTs.name}DistZip")
|
||||
//val schemaTsZipTaskArchiveFile: Provider<RegularFile> = schemaTsZipTask.flatMap { it.archiveFile }
|
||||
|
||||
|
||||
val schemaTsZip by tasks.registering(Zip::class) {
|
||||
group = "kt2ts"
|
||||
|
||||
archiveBaseName.set("schema-ts")
|
||||
from(generateTypeScriptOutputFiles)
|
||||
destinationDirectory.set(layout.buildDirectory.dir("distributions/kt2ts"))
|
||||
}
|
||||
|
||||
|
||||
val schemaTsZipTask: TaskProvider<Zip> = tasks.named<Zip>("${schemaTs.name}DistZip")
|
||||
val schemaTsZipTaskArchiveFile: Provider<RegularFile> = schemaTsZipTask.flatMap { it.archiveFile }
|
||||
val schemaTsZipTaskArchiveFile: Provider<RegularFile> = schemaTsZip.flatMap { it.archiveFile }
|
||||
|
||||
|
||||
val typeScriptModelGenerated: Configuration by configurations.creating {
|
||||
|
|
@ -139,4 +171,5 @@ val typeScriptModelGenerated: Configuration by configurations.creating {
|
|||
typescriptAttributes(objects)
|
||||
|
||||
outgoing.artifact(schemaTsZipTaskArchiveFile)
|
||||
// outgoing.artifact(schemaTsZipTaskArchiveFile)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import kotlin.math.roundToInt
|
|||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
/**
|
||||
* Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any
|
||||
* value is > 1.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,191 @@
|
|||
package dev.adamko.kafkatorio.schema.common
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.entity.FactorioEntityData")
|
||||
sealed interface FactorioEntityData {
|
||||
|
||||
val protoId: PrototypeId
|
||||
val status: Status?
|
||||
|
||||
val position: MapEntityPosition
|
||||
|
||||
/** Non-specific entity data */
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.entity.FactorioEntityData.Standard")
|
||||
data class Standard(
|
||||
override val protoId: PrototypeId,
|
||||
override val status: Status? = null,
|
||||
|
||||
override val position: MapEntityPosition,
|
||||
val graphicsVariation: UByte? = null,
|
||||
val health: Float? = null,
|
||||
val isActive: Boolean? = null,
|
||||
val isRotatable: Boolean? = null,
|
||||
val lastUser: UInt? = null,
|
||||
val localisedDescription: String? = null,
|
||||
val localisedName: String? = null,
|
||||
) : FactorioEntityData
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.entity.FactorioEntityData.Resource")
|
||||
data class Resource(
|
||||
override val protoId: PrototypeId,
|
||||
override val status: Status? = null,
|
||||
|
||||
override val position: MapEntityPosition,
|
||||
val amount: UInt,
|
||||
/** Count of initial resource units contained. `null` if resource is not infinite. */
|
||||
val initialAmount: UInt? = null,
|
||||
) : FactorioEntityData
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.entity.FactorioEntityData.EntityStatus")
|
||||
enum class Status {
|
||||
CANT_DIVIDE_SEGMENTS,
|
||||
CHARGING,
|
||||
CLOSED_BY_CIRCUIT_NETWORK,
|
||||
DISABLED,
|
||||
DISABLED_BY_CONTROL_BEHAVIOR,
|
||||
DISABLED_BY_SCRIPT,
|
||||
DISCHARGING,
|
||||
FLUID_INGREDIENT_SHORTAGE,
|
||||
FULLY_CHARGED,
|
||||
FULL_OUTPUT,
|
||||
ITEM_INGREDIENT_SHORTAGE,
|
||||
LAUNCHING_ROCKET,
|
||||
LOW_INPUT_FLUID,
|
||||
LOW_POWER,
|
||||
LOW_TEMPERATURE,
|
||||
MARKED_FOR_DECONSTRUCTION,
|
||||
MISSING_REQUIRED_FLUID,
|
||||
MISSING_SCIENCE_PACKS,
|
||||
NETWORKS_CONNECTED,
|
||||
NETWORKS_DISCONNECTED,
|
||||
NORMAL,
|
||||
NOT_CONNECTED_TO_RAIL,
|
||||
NOT_PLUGGED_IN_ELECTRIC_NETWORK,
|
||||
NO_AMMO,
|
||||
NO_FUEL,
|
||||
NO_INGREDIENTS,
|
||||
NO_INPUT_FLUID,
|
||||
NO_MINABLE_RESOURCES,
|
||||
NO_MODULES_TO_TRANSMIT,
|
||||
NO_POWER,
|
||||
NO_RECIPE,
|
||||
NO_RESEARCH_IN_PROGRESS,
|
||||
OPENED_BY_CIRCUIT_NETWORK,
|
||||
OUT_OF_LOGISTIC_NETWORK,
|
||||
PREPARING_ROCKET_FOR_LAUNCH,
|
||||
RECHARGING_AFTER_POWER_OUTAGE,
|
||||
TURNED_OFF_DURING_DAYTIME,
|
||||
WAITING_FOR_SOURCE_ITEMS,
|
||||
WAITING_FOR_SPACE_IN_DESTINATION,
|
||||
WAITING_FOR_TARGET_TO_BE_BUILT,
|
||||
WAITING_FOR_TRAIN,
|
||||
WAITING_TO_LAUNCH_ROCKET,
|
||||
WORKING,
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
enum entity_status {
|
||||
working,
|
||||
normal,
|
||||
no_power,
|
||||
low_power,
|
||||
no_fuel,
|
||||
disabled_by_control_behavior,
|
||||
opened_by_circuit_network,
|
||||
closed_by_circuit_network,
|
||||
disabled_by_script,
|
||||
marked_for_deconstruction,
|
||||
not_plugged_in_electric_network,
|
||||
networks_connected,
|
||||
networks_disconnected,
|
||||
charging,
|
||||
discharging,
|
||||
fully_charged,
|
||||
out_of_logistic_network,
|
||||
no_recipe,
|
||||
no_ingredients,
|
||||
no_input_fluid,
|
||||
no_research_in_progress,
|
||||
no_minable_resources,
|
||||
low_input_fluid,
|
||||
fluid_ingredient_shortage,
|
||||
full_output,
|
||||
item_ingredient_shortage,
|
||||
missing_required_fluid,
|
||||
missing_science_packs,
|
||||
waiting_for_source_items,
|
||||
waiting_for_space_in_destination,
|
||||
preparing_rocket_for_launch,
|
||||
waiting_to_launch_rocket,
|
||||
launching_rocket,
|
||||
no_modules_to_transmit,
|
||||
recharging_after_power_outage,
|
||||
waiting_for_target_to_be_built,
|
||||
waiting_for_train,
|
||||
no_ammo,
|
||||
low_temperature,
|
||||
disabled,
|
||||
turned_off_during_daytime,
|
||||
not_connected_to_rail,
|
||||
cant_divide_segments,
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
AssemblingMachine
|
||||
Beam
|
||||
Car
|
||||
Character
|
||||
CharacterCorpse
|
||||
CraftingMachine
|
||||
ElectricEnergyInterface
|
||||
ElectricPole
|
||||
EntityGhost
|
||||
EntityWithHealth
|
||||
EntityWithOwner
|
||||
FlyingText
|
||||
Furnace
|
||||
Gate
|
||||
Generator
|
||||
Ghost
|
||||
HeatInterface
|
||||
HighlightBox
|
||||
InfinityContainer
|
||||
InfinityPipe
|
||||
Inserter
|
||||
ItemEntity
|
||||
LandMine
|
||||
LinkedBelt
|
||||
Loader
|
||||
Market
|
||||
MiningDrill
|
||||
ProgrammableSpeaker
|
||||
Pump
|
||||
Radar
|
||||
Rail
|
||||
RailChainSignal
|
||||
RailSignal
|
||||
Reactor
|
||||
ResourceEntity
|
||||
RocketSilo
|
||||
SmokeWithTrigger
|
||||
SpiderVehicle
|
||||
Splitter
|
||||
TrainStop
|
||||
TransportBeltConnectable
|
||||
TransportBeltToGround
|
||||
Turret
|
||||
Unit
|
||||
Vehicle
|
||||
*/
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
package dev.adamko.kafkatorio.schema.common
|
||||
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.Tick")
|
||||
@JvmInline
|
||||
value class Tick(val value: UInt)
|
||||
|
||||
|
|
@ -17,6 +19,7 @@ val UInt.tick
|
|||
* See [`LuaSurface.index`](https://lua-api.factorio.com/latest/LuaSurface.html#LuaSurface.index)
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.SurfaceIndex")
|
||||
@JvmInline
|
||||
value class SurfaceIndex(private val id: UInt) {
|
||||
override fun toString(): String = "$id"
|
||||
|
|
@ -24,6 +27,7 @@ value class SurfaceIndex(private val id: UInt) {
|
|||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.ForceIndex")
|
||||
@JvmInline
|
||||
value class ForceIndex(private val id: UInt) {
|
||||
override fun toString(): String = "$id"
|
||||
|
|
@ -32,6 +36,7 @@ value class ForceIndex(private val id: UInt) {
|
|||
|
||||
/** The player's index in `LuaGameScript::players` */
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.PlayerIndex")
|
||||
@JvmInline
|
||||
value class PlayerIndex(private val id: UInt) {
|
||||
override fun toString(): String = "$id"
|
||||
|
|
@ -40,6 +45,7 @@ value class PlayerIndex(private val id: UInt) {
|
|||
|
||||
/** > This is universally unique for every entity that has one, for the lifetime of a whole game. */
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.UnitNumber")
|
||||
@JvmInline
|
||||
value class UnitNumber(private val id: UInt) {
|
||||
override fun toString(): String = "$id"
|
||||
|
|
@ -47,13 +53,7 @@ value class UnitNumber(private val id: UInt) {
|
|||
|
||||
|
||||
@Serializable
|
||||
@JvmInline
|
||||
value class PrototypeName(private val id: String) {
|
||||
override fun toString(): String = id
|
||||
}
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.EventName")
|
||||
@JvmInline
|
||||
value class EventName(private val name: String) {
|
||||
override fun toString(): String = name
|
||||
|
|
@ -62,23 +62,23 @@ value class EventName(private val name: String) {
|
|||
|
||||
interface EntityIdentifiers {
|
||||
val unitNumber: UnitNumber?
|
||||
val name: String
|
||||
/** The prototype-type of the entity. */
|
||||
val protoType: String
|
||||
/** The 'prototype type' and 'prototype name' of the entity. */
|
||||
val protoId: PrototypeId
|
||||
}
|
||||
|
||||
|
||||
// instant of EntityIdentifiers, because kxs needs a concrete instance
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.EntityIdentifiersData")
|
||||
data class EntityIdentifiersData(
|
||||
override val unitNumber: UnitNumber? = null,
|
||||
override val name: String,
|
||||
override val protoType: String,
|
||||
override val protoId: PrototypeId,
|
||||
) : EntityIdentifiers
|
||||
|
||||
|
||||
@JvmInline
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.id.FactorioServerId")
|
||||
@JvmInline
|
||||
value class FactorioServerId(private val id: String) {
|
||||
override fun toString() = id
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,14 @@ import kotlinx.serialization.Serializable
|
|||
@Serializable
|
||||
@SerialName("kafkatorio.prototype.FactorioPrototype")
|
||||
sealed interface FactorioPrototype {
|
||||
val name: PrototypeName
|
||||
val protoId: PrototypeId
|
||||
val mapColour: Colour
|
||||
|
||||
|
||||
@SerialName("kafkatorio.prototype.MapTile")
|
||||
@Serializable
|
||||
data class MapTile(
|
||||
override val name: PrototypeName,
|
||||
override val protoId: PrototypeId,
|
||||
override val mapColour: Colour,
|
||||
|
||||
val layer: UInt,
|
||||
|
|
@ -29,7 +30,7 @@ sealed interface FactorioPrototype {
|
|||
@SerialName("kafkatorio.prototype.Entity")
|
||||
@Serializable
|
||||
data class Entity(
|
||||
override val name: PrototypeName,
|
||||
override val protoId: PrototypeId,
|
||||
override val mapColour: Colour,
|
||||
|
||||
val protoType: String,
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@ const val MAP_CHUNK_SIZE = 32
|
|||
data class MapTile(
|
||||
val x: Int,
|
||||
val y: Int,
|
||||
val proto: PrototypeName,
|
||||
val protoId: PrototypeId,
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* 2D map of x/y tile positions and prototype-name, optimised for JSON size.
|
||||
*
|
||||
* [protos] is a one-to-one map between a [PrototypeName] and [PrototypeKey].
|
||||
* [protos] is a one-to-one map between a prototype[PrototypeId] and [PrototypeKey].
|
||||
*
|
||||
* [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeName] only for a
|
||||
* [PrototypeKey] is an arbitrary integer value, which maps to one [PrototypeId] only for a
|
||||
* specific instance of [MapTileDictionary].
|
||||
*
|
||||
* Each X/Y coordinate in [tilesXY] maps to a [PrototypeKey].
|
||||
|
|
@ -30,9 +30,10 @@ data class MapTile(
|
|||
data class MapTileDictionary(
|
||||
/** Map an X,Y coordinate a prototype name */
|
||||
val tilesXY: Map<String, Map<String, PrototypeKey>>,
|
||||
val protos: Map<PrototypeName, PrototypeKey>,
|
||||
val protos: Map<PrototypeId, PrototypeKey>,
|
||||
) {
|
||||
private val protosIndexToName: Map<PrototypeKey, PrototypeName> by lazy {
|
||||
|
||||
private val protosIndexToId: Map<PrototypeKey, PrototypeId> by lazy {
|
||||
protos.entries.associate { (name, key) -> key to name }
|
||||
}
|
||||
|
||||
|
|
@ -41,11 +42,11 @@ data class MapTileDictionary(
|
|||
row.forEach { (yString, protoIndex) ->
|
||||
val x = xString.toIntOrNull()
|
||||
val y = yString.toIntOrNull()
|
||||
val protoName = protosIndexToName[protoIndex]
|
||||
val protoName = protosIndexToId[protoIndex]
|
||||
if (x != null && y != null && protoName != null) {
|
||||
add(MapTile(x, y, protoName))
|
||||
} else if (protoName == null) {
|
||||
println("warning: no prototype name found for index:$protoIndex. $protosIndexToName")
|
||||
println("warning: no prototype name found for index:$protoIndex. $protosIndexToId")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,817 @@
|
|||
package dev.adamko.kafkatorio.schema.common
|
||||
|
||||
import kotlin.jvm.JvmInline
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
/**
|
||||
* Both a [name] and [type] are required to unique identify a [prototype][FactorioPrototype].
|
||||
*
|
||||
*
|
||||
* @property[name] The name of the prototype, which is unique per specific Prototype [type]
|
||||
*/
|
||||
// * Each subclass of [PrototypeId] is equivalent to a Prototype `type`.
|
||||
//sealed interface PrototypeId {
|
||||
//
|
||||
// val name: String
|
||||
//
|
||||
// @Serializable
|
||||
// @JvmInline
|
||||
// @SerialName("kafkatorio.prototype.id.PrototypeIdMapTile")
|
||||
// value class MapTile(override val name: String) : PrototypeId {
|
||||
// override fun toString(): String = name
|
||||
// }
|
||||
//
|
||||
// @Serializable
|
||||
// @JvmInline
|
||||
// @SerialName("kafkatorio.prototype.id.PrototypeIdEntity")
|
||||
// value class Entity(override val name: String) : PrototypeId {
|
||||
// override fun toString(): String = name
|
||||
// }
|
||||
//
|
||||
// @Serializable
|
||||
// @JvmInline
|
||||
// @SerialName("kafkatorio.prototype.id.PrototypeIdResourceEntity")
|
||||
// value class ResourceEntity(override val name: String) : PrototypeId {
|
||||
// override fun toString(): String = name
|
||||
// }
|
||||
//
|
||||
// @Serializable
|
||||
// @JvmInline
|
||||
// @SerialName("kafkatorio.prototype.id.PrototypeIdFluid")
|
||||
// value class Fluid(override val name: String) : PrototypeId {
|
||||
// override fun toString(): String = name
|
||||
// }
|
||||
//
|
||||
// @Serializable
|
||||
// @JvmInline
|
||||
// @SerialName("kafkatorio.prototype.id.PrototypeIdItem")
|
||||
// value class Item(override val name: String) : PrototypeId {
|
||||
// override fun toString(): String = name
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
@Serializable
|
||||
@JvmInline
|
||||
@SerialName("kafkatorio.id.PrototypeId")
|
||||
value class PrototypeId private constructor(
|
||||
private val typeNameConcat: String,
|
||||
) {
|
||||
|
||||
val type: Type get() = Type(typeNameConcat.substringBefore(delim, ""))
|
||||
val name: Name get() = Name(typeNameConcat.substringAfter(delim, ""))
|
||||
|
||||
|
||||
operator fun component1(): Type = type
|
||||
operator fun component2(): Name = name
|
||||
|
||||
|
||||
constructor(
|
||||
type: String,
|
||||
name: String,
|
||||
) : this("${type}${delim}${name}")
|
||||
|
||||
|
||||
/** Denotes the class of the Prototype */
|
||||
@Serializable
|
||||
@JvmInline
|
||||
@SerialName("kafkatorio.id.PrototypeIdType")
|
||||
value class Type(private val id: String) {
|
||||
override fun toString(): String = id
|
||||
}
|
||||
|
||||
|
||||
/** A specific implementation of a [type]. Unique per prototype 'super class' */
|
||||
@Serializable
|
||||
@JvmInline
|
||||
@SerialName("kafkatorio.id.PrototypeIdName")
|
||||
value class Name(private val name: String) {
|
||||
override fun toString(): String = name
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private const val delim = '/'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//@Suppress("unused")
|
||||
//enum class PrototypeTypeId(
|
||||
// val id: String
|
||||
//) {
|
||||
// AmbientSound("ambient-sound"),
|
||||
// Animation("animation"),
|
||||
// EditorController("editor-controller"),
|
||||
// Font("font"),
|
||||
// GodController("god-controller"),
|
||||
// MapGenPresets("map-gen-presets"),
|
||||
// MapSettings("map-settings"),
|
||||
// MouseCursor("mouse-cursor"),
|
||||
// Sound("sound"),
|
||||
// SpectatorController("spectator-controller"),
|
||||
// Sprite("sprite"),
|
||||
// TileEffect("tile-effect"),
|
||||
// TipsAndTricksItemCategory("tips-and-tricks-item-category"),
|
||||
// TriggerTargetType("trigger-target-type"),
|
||||
// WindSound("wind-sound"),
|
||||
// Achievement("achievement"),
|
||||
// BuildEntityAchievement("build-entity-achievement"),
|
||||
// CombatRobotCountAchievement("combat-robot-count"),
|
||||
// ConstructWithRobotsAchievement("construct-with-robots-achievement"),
|
||||
// DeconstructWithRobotsAchievement("deconstruct-with-robots-achievement"),
|
||||
// DeliverByRobotsAchievement("deliver-by-robots-achievement"),
|
||||
// DontBuildEntityAchievement("dont-build-entity-achievement"),
|
||||
// DontCraftManuallyAchievement("dont-craft-manually-achievement"),
|
||||
// DontUseEntityInEnergyProductionAchievement("dont-use-entity-in-energy-production-achievement"),
|
||||
// FinishTheGameAchievement("finish-the-game-achievement"),
|
||||
// GroupAttackAchievement("group-attack-achievement"),
|
||||
// KillAchievement("kill-achievement"),
|
||||
// PlayerDamagedAchievement("player-damaged-achievement"),
|
||||
// ProduceAchievement("produce-achievement"),
|
||||
// ProducePerHourAchievement("produce-per-hour-achievement"),
|
||||
// ResearchAchievement("research-achievement"),
|
||||
// TrainPathAchievement("train-path-achievement"),
|
||||
// AmmoCategory("ammo-category"),
|
||||
// AutoplaceControl("autoplace-control"),
|
||||
// CustomInput("custom-input"),
|
||||
// DamageType("damage-type"),
|
||||
// Decorative("optimized-decorative"),
|
||||
// Entity("<abstract>"),
|
||||
// Arrow("arrow"),
|
||||
// ArtilleryFlare("artillery-flare"),
|
||||
// ArtilleryProjectile("artillery-projectile"),
|
||||
// Beam("beam"),
|
||||
// CharacterCorpse("character-corpse"),
|
||||
// Cliff("cliff"),
|
||||
// Corpse("corpse"),
|
||||
// RailRemnants("rail-remnants"),
|
||||
// DeconstructibleTileProxy("deconstructible-tile-proxy"),
|
||||
// EntityGhost("entity-ghost"),
|
||||
// /** for migration, cannot be used */
|
||||
// EntityParticle("particle"),
|
||||
// /** for migration, cannot be used */
|
||||
// LeafParticle("leaf-particle"),
|
||||
// EntityWithHealth("<abstract>"),
|
||||
// EntityWithOwner("<abstract>"),
|
||||
// Accumulator("accumulator"),
|
||||
// ArtilleryTurret("artillery-turret"),
|
||||
// Beacon("beacon"),
|
||||
// Boiler("boiler"),
|
||||
// BurnerGenerator("burner-generator"),
|
||||
// Character("character"),
|
||||
// Combinator("<abstract>"),
|
||||
// ArithmeticCombinator("arithmetic-combinator"),
|
||||
// DeciderCombinator("decider-combinator"),
|
||||
// ConstantCombinator("constant-combinator"),
|
||||
// Container("container"),
|
||||
// LogisticContainer("logistic-container"),
|
||||
// InfinityContainer("infinity-container"),
|
||||
// CraftingMachine("<abstract>"),
|
||||
// AssemblingMachine("assembling-machine"),
|
||||
// RocketSilo("rocket-silo"),
|
||||
// Furnace("furnace"),
|
||||
// ElectricEnergyInterface("electric-energy-interface"),
|
||||
// ElectricPole("electric-pole"),
|
||||
// EnemySpawner("unit-spawner"),
|
||||
// FlyingRobot("<abstract>"),
|
||||
// CombatRobot("combat-robot"),
|
||||
// RobotWithLogisticInterface("<abstract>"),
|
||||
// ConstructionRobot("construction-robot"),
|
||||
// LogisticRobot("logistic-robot"),
|
||||
// Gate("gate"),
|
||||
// Generator("generator"),
|
||||
// HeatInterface("heat-interface"),
|
||||
// HeatPipe("heat-pipe"),
|
||||
// Inserter("inserter"),
|
||||
// Lab("lab"),
|
||||
// Lamp("lamp"),
|
||||
// LandMine("land-mine"),
|
||||
// LinkedContainer("linked-container"),
|
||||
// Market("market"),
|
||||
// MiningDrill("mining-drill"),
|
||||
// OffshorePump("offshore-pump"),
|
||||
// Pipe("pipe"),
|
||||
// InfinityPipe("infinity-pipe"),
|
||||
// PipeToGround("pipe-to-ground"),
|
||||
// PlayerPort("player-port"),
|
||||
// PowerSwitch("power-switch"),
|
||||
// ProgrammableSpeaker("programmable-speaker"),
|
||||
// Pump("pump"),
|
||||
// Radar("radar"),
|
||||
// Rail("<abstract>"),
|
||||
// CurvedRail("curved-rail"),
|
||||
// StraightRail("straight-rail"),
|
||||
// RailSignalBase("<abstract>"),
|
||||
// RailChainSignal("rail-chain-signal"),
|
||||
// RailSignal("rail-signal"),
|
||||
// Reactor("reactor"),
|
||||
// Roboport("roboport"),
|
||||
// SimpleEntityWithOwner("simple-entity-with-owner"),
|
||||
// SimpleEntityWithForce("simple-entity-with-force"),
|
||||
// SolarPanel("solar-panel"),
|
||||
// StorageTank("storage-tank"),
|
||||
// TrainStop("train-stop"),
|
||||
// TransportBeltConnectable("<abstract>"),
|
||||
// LinkedBelt("linked-belt"),
|
||||
// Loader1x1("loader-1x1"),
|
||||
// Loader1x2("loader"),
|
||||
// Splitter("splitter"),
|
||||
// TransportBelt("transport-belt"),
|
||||
// UndergroundBelt("underground-belt"),
|
||||
// Turret("turret"),
|
||||
// AmmoTurret("ammo-turret"),
|
||||
// ElectricTurret("electric-turret"),
|
||||
// FluidTurret("fluid-turret"),
|
||||
// Unit("unit"),
|
||||
// Vehicle("<abstract>"),
|
||||
// Car("car"),
|
||||
// RollingStock("<abstract>"),
|
||||
// ArtilleryWagon("artillery-wagon"),
|
||||
// CargoWagon("cargo-wagon"),
|
||||
// FluidWagon("fluid-wagon"),
|
||||
// Locomotive("locomotive"),
|
||||
// SpiderVehicle("spider-vehicle"),
|
||||
// Wall("wall"),
|
||||
// Fish("fish"),
|
||||
// SimpleEntity("simple-entity"),
|
||||
// SpiderLeg("spider-leg"),
|
||||
// Tree("tree"),
|
||||
// Explosion("explosion"),
|
||||
// FlameThrowerExplosion("flame-thrower-explosion"),
|
||||
// FireFlame("fire"),
|
||||
// FluidStream("stream"),
|
||||
// FlyingText("flying-text"),
|
||||
// HighlightBoxEntity("highlight-box"),
|
||||
// ItemEntity("item-entity"),
|
||||
// ItemRequestProxy("item-request-proxy"),
|
||||
// ParticleSource("particle-source"),
|
||||
// Projectile("projectile"),
|
||||
// ResourceEntity("resource"),
|
||||
// RocketSiloRocket("rocket-silo-rocket"),
|
||||
// RocketSiloRocketShadow("rocket-silo-rocket-shadow"),
|
||||
// Smoke("<abstract>"),
|
||||
// /** for migration, cannot be used */
|
||||
// SimpleSmoke("smoke"),
|
||||
// SmokeWithTrigger("smoke-with-trigger"),
|
||||
// SpeechBubble("speech-bubble"),
|
||||
// Sticker("sticker"),
|
||||
// TileGhost("tile-ghost"),
|
||||
// Equipment("<abstract>"),
|
||||
// ActiveDefenseEquipment("active-defense-equipment"),
|
||||
// BatteryEquipment("battery-equipment"),
|
||||
// BeltImmunityEquipment("belt-immunity-equipment"),
|
||||
// EnergyShieldEquipment("energy-shield-equipment"),
|
||||
// GeneratorEquipment("generator-equipment"),
|
||||
// MovementBonusEquipment("movement-bonus-equipment"),
|
||||
// NightVisionEquipment("night-vision-equipment"),
|
||||
// RoboportEquipment("roboport-equipment"),
|
||||
// SolarPanelEquipment("solar-panel-equipment"),
|
||||
// EquipmentCategory("equipment-category"),
|
||||
// EquipmentGrid("equipment-grid"),
|
||||
// Fluid("fluid"),
|
||||
// FuelCategory("fuel-category"),
|
||||
// GuiStyle("gui-style"),
|
||||
// Item("item"),
|
||||
// AmmoItem("ammo"),
|
||||
// Capsule("capsule"),
|
||||
// Gun("gun"),
|
||||
// ItemWithEntityData("item-with-entity-data"),
|
||||
// ItemWithLabel("item-with-label"),
|
||||
// ItemWithInventory("item-with-inventory"),
|
||||
// BlueprintBook("blueprint-book"),
|
||||
// ItemWithTags("item-with-tags"),
|
||||
// SelectionTool("selection-tool"),
|
||||
// BlueprintItem("blueprint"),
|
||||
// CopyPasteTool("copy-paste-tool"),
|
||||
// DeconstructionItem("deconstruction-item"),
|
||||
// UpgradeItem("upgrade-item"),
|
||||
// Module("module"),
|
||||
// RailPlanner("rail-planner"),
|
||||
// SpidertronRemote("spidertron-remote"),
|
||||
// Tool("tool"),
|
||||
// Armor("armor"),
|
||||
// /** for migration, cannot be used */
|
||||
// MiningTool("mining-tool"),
|
||||
// RepairTool("repair-tool"),
|
||||
// ItemGroup("item-group"),
|
||||
// ItemSubGroup("item-subgroup"),
|
||||
// ModuleCategory("module-category"),
|
||||
// NamedNoiseExpression("noise-expression"),
|
||||
// NoiseLayer("noise-layer"),
|
||||
// Particle("optimized-particle"),
|
||||
// Recipe("recipe"),
|
||||
// RecipeCategory("recipe-category"),
|
||||
// ResourceCategory("resource-category"),
|
||||
// Shortcut("shortcut"),
|
||||
// Technology("technology"),
|
||||
// Tile("tile"),
|
||||
// TipsAndTricksItem("tips-and-tricks-item"),
|
||||
// TrivialSmoke("trivial-smoke"),
|
||||
// Tutorial("tutorial"),
|
||||
// UtilityConstants("utility-constants"),
|
||||
// UtilitySounds("utility-sounds"),
|
||||
// UtilitySprites("utility-sprites"),
|
||||
// VirtualSignal("virtual-signal"),
|
||||
// ;
|
||||
//
|
||||
// fun named(protoName: String): PrototypeId = PrototypeId(this, protoName)
|
||||
//
|
||||
// companion object {
|
||||
// val entries: Set<PrototypeTypeId> = values().toSet()
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
//@Suppress("unused")
|
||||
//sealed class PrototypeType(
|
||||
// val id: String
|
||||
//) {
|
||||
//
|
||||
// object AmbientSound : PrototypeType("ambient-sound")
|
||||
// object Animation : PrototypeType("animation")
|
||||
// object EditorController : PrototypeType("editor-controller")
|
||||
// object Font : PrototypeType("font")
|
||||
// object GodController : PrototypeType("god-controller")
|
||||
// object MapGenPresets : PrototypeType("map-gen-presets")
|
||||
// object MapSettings : PrototypeType("map-settings")
|
||||
// object MouseCursor : PrototypeType("mouse-cursor")
|
||||
// object Sound : PrototypeType("sound")
|
||||
// object SpectatorController : PrototypeType("spectator-controller")
|
||||
// object Sprite : PrototypeType("sprite")
|
||||
// object TileEffect : PrototypeType("tile-effect")
|
||||
// object TipsAndTricksItemCategory : PrototypeType("tips-and-tricks-item-category")
|
||||
// object TriggerTargetType : PrototypeType("trigger-target-type")
|
||||
// object WindSound : PrototypeType("wind-sound")
|
||||
//
|
||||
//
|
||||
// object Achievement : PrototypeType("achievement")
|
||||
// object BuildEntityAchievement : PrototypeType("build-entity-achievement")
|
||||
// object CombatRobotCountAchievement : PrototypeType("combat-robot-count")
|
||||
// object ConstructWithRobotsAchievement : PrototypeType("construct-with-robots-achievement")
|
||||
// object DeconstructWithRobotsAchievement : PrototypeType("deconstruct-with-robots-achievement")
|
||||
// object DeliverByRobotsAchievement : PrototypeType("deliver-by-robots-achievement")
|
||||
// object DontBuildEntityAchievement : PrototypeType("dont-build-entity-achievement")
|
||||
// object DontCraftManuallyAchievement : PrototypeType("dont-craft-manually-achievement")
|
||||
// object DontUseEntityInEnergyProductionAchievement : PrototypeType("dont-use-entity-in-energy-production-achievement")
|
||||
//
|
||||
//
|
||||
// object FinishTheGameAchievement : PrototypeType("finish-the-game-achievement")
|
||||
// object GroupAttackAchievement : PrototypeType("group-attack-achievement")
|
||||
// object KillAchievement : PrototypeType("kill-achievement")
|
||||
// object PlayerDamagedAchievement : PrototypeType("player-damaged-achievement")
|
||||
// object ProduceAchievement : PrototypeType("produce-achievement")
|
||||
// object ProducePerHourAchievement : PrototypeType("produce-per-hour-achievement")
|
||||
// object ResearchAchievement : PrototypeType("research-achievement")
|
||||
// object TrainPathAchievement : PrototypeType("train-path-achievement")
|
||||
// object AmmoCategory : PrototypeType("ammo-category")
|
||||
// object AutoplaceControl : PrototypeType("autoplace-control")
|
||||
// object CustomInput : PrototypeType("custom-input")
|
||||
// object DamageType : PrototypeType("damage-type")
|
||||
// object Decorative : PrototypeType("optimized-decorative")
|
||||
//
|
||||
//
|
||||
// object Entity : PrototypeType("stract>")
|
||||
// object Arrow : PrototypeType("arrow")
|
||||
// object ArtilleryFlare : PrototypeType("artillery-flare")
|
||||
// object ArtilleryProjectile : PrototypeType("artillery-projectile")
|
||||
// object Beam : PrototypeType("beam")
|
||||
// object CharacterCorpse : PrototypeType("character-corpse")
|
||||
// object Cliff : PrototypeType("cliff")
|
||||
// object Corpse : PrototypeType("corpse")
|
||||
// object RailRemnants : PrototypeType("rail-remnants")
|
||||
// object DeconstructibleTileProxy : PrototypeType("deconstructible-tile-proxy")
|
||||
// object EntityGhost : PrototypeType("entity-ghost")
|
||||
// /** for migration, cannot be used */
|
||||
// object EntityParticle : PrototypeType("particle")
|
||||
// /** for migration, cannot be used */
|
||||
// object LeafParticle : PrototypeType("leaf-particle")
|
||||
//
|
||||
//
|
||||
// object EntityWithOwner : PrototypeType("stract>")
|
||||
// object Accumulator : PrototypeType("accumulator")
|
||||
// object ArtilleryTurret : PrototypeType("artillery-turret")
|
||||
// object Beacon : PrototypeType("beacon")
|
||||
// object Boiler : PrototypeType("boiler")
|
||||
// object BurnerGenerator : PrototypeType("burner-generator")
|
||||
// object Character : PrototypeType("character")
|
||||
//
|
||||
//
|
||||
// object Combinator : PrototypeType("stract>")
|
||||
// object ArithmeticCombinator : PrototypeType("arithmetic-combinator")
|
||||
// object DeciderCombinator : PrototypeType("decider-combinator")
|
||||
// object ConstantCombinator : PrototypeType("constant-combinator")
|
||||
// object Container : PrototypeType("container")
|
||||
// object LogisticContainer : PrototypeType("logistic-container")
|
||||
// object InfinityContainer : PrototypeType("infinity-container")
|
||||
//
|
||||
//
|
||||
// object CraftingMachine : PrototypeType("stract>")
|
||||
// object AssemblingMachine : PrototypeType("assembling-machine")
|
||||
// object RocketSilo : PrototypeType("rocket-silo")
|
||||
// object Furnace : PrototypeType("furnace")
|
||||
// object ElectricEnergyInterface : PrototypeType("electric-energy-interface")
|
||||
// object ElectricPole : PrototypeType("electric-pole")
|
||||
// object EnemySpawner : PrototypeType("unit-spawner")
|
||||
//
|
||||
//
|
||||
// object FlyingRobot : PrototypeType("stract>")
|
||||
// object CombatRobot : PrototypeType("combat-robot") , PrototypeAbstract.FlyingRobot
|
||||
//
|
||||
//
|
||||
// object RobotWithLogisticInterface : PrototypeType("stract>")
|
||||
// object ConstructionRobot : PrototypeType("construction-robot")
|
||||
// object LogisticRobot : PrototypeType("logistic-robot")
|
||||
// object Gate : PrototypeType("gate")
|
||||
// object Generator : PrototypeType("generator")
|
||||
// object HeatInterface : PrototypeType("heat-interface")
|
||||
// object HeatPipe : PrototypeType("heat-pipe")
|
||||
// object Inserter : PrototypeType("inserter")
|
||||
// object Lab : PrototypeType("lab")
|
||||
// object Lamp : PrototypeType("lamp")
|
||||
// object LandMine : PrototypeType("land-mine")
|
||||
// object LinkedContainer : PrototypeType("linked-container")
|
||||
// object Market : PrototypeType("market")
|
||||
// object MiningDrill : PrototypeType("mining-drill")
|
||||
// object OffshorePump : PrototypeType("offshore-pump")
|
||||
// object Pipe : PrototypeType("pipe")
|
||||
// object InfinityPipe : PrototypeType("infinity-pipe")
|
||||
// object PipeToGround : PrototypeType("pipe-to-ground")
|
||||
// object PlayerPort : PrototypeType("player-port")
|
||||
// object PowerSwitch : PrototypeType("power-switch")
|
||||
// object ProgrammableSpeaker : PrototypeType("programmable-speaker")
|
||||
// object Pump : PrototypeType("pump")
|
||||
// object Radar : PrototypeType("radar")
|
||||
//
|
||||
// object CurvedRail : PrototypeType("curved-rail"), PrototypeAbstract.Rail
|
||||
// object StraightRail : PrototypeType("straight-rail"), PrototypeAbstract.Rail
|
||||
//
|
||||
// object RailSignalBase : PrototypeType("stract>")
|
||||
// object RailChainSignal : PrototypeType("rail-chain-signal")
|
||||
// object RailSignal : PrototypeType("rail-signal")
|
||||
// object Reactor : PrototypeType("reactor")
|
||||
// object Roboport : PrototypeType("roboport")
|
||||
// object SimpleEntityWithOwner : PrototypeType("simple-entity-with-owner")
|
||||
// object SimpleEntityWithForce : PrototypeType("simple-entity-with-force")
|
||||
// object SolarPanel : PrototypeType("solar-panel")
|
||||
// object StorageTank : PrototypeType("storage-tank")
|
||||
// object TrainStop : PrototypeType("train-stop")
|
||||
//
|
||||
//
|
||||
// object TransportBeltConnectable : PrototypeType("stract>")
|
||||
// object LinkedBelt : PrototypeType("linked-belt")
|
||||
// object Loader1x1 : PrototypeType("loader-1x1")
|
||||
// object Loader1x2 : PrototypeType("loader")
|
||||
// object Splitter : PrototypeType("splitter")
|
||||
// object TransportBelt : PrototypeType("transport-belt")
|
||||
// object UndergroundBelt : PrototypeType("underground-belt")
|
||||
// object Turret : PrototypeType("turret")
|
||||
// object AmmoTurret : PrototypeType("ammo-turret")
|
||||
// object ElectricTurret : PrototypeType("electric-turret")
|
||||
// object FluidTurret : PrototypeType("fluid-turret")
|
||||
// object Unit : PrototypeType("unit")
|
||||
//
|
||||
//
|
||||
// object Car : PrototypeType("car>"), PrototypeAbstract.Vehicle
|
||||
// object SpiderVehicle : PrototypeType("spider-vehicle"), PrototypeAbstract.Vehicle
|
||||
//
|
||||
//
|
||||
// object ArtilleryWagon : PrototypeType("artillery-wagon"), PrototypeAbstract.RollingStock
|
||||
// object CargoWagon : PrototypeType("cargo-wagon"), PrototypeAbstract.RollingStock
|
||||
// object FluidWagon : PrototypeType("fluid-wagon"), PrototypeAbstract.RollingStock
|
||||
// object Locomotive : PrototypeType("locomotive"), PrototypeAbstract.RollingStock
|
||||
//
|
||||
// object Wall : PrototypeType("wall")
|
||||
//
|
||||
//
|
||||
// object Fish : PrototypeType("fish"), PrototypeAbstract.EntityWithHealth
|
||||
// object SimpleEntity : PrototypeType("simple-entity"), PrototypeAbstract.EntityWithHealth
|
||||
// object SpiderLeg : PrototypeType("spider-leg"), PrototypeAbstract.EntityWithHealth
|
||||
// object Tree : PrototypeType("tree"), PrototypeAbstract.EntityWithHealth
|
||||
//
|
||||
//
|
||||
// object Explosion : PrototypeType("explosion"),
|
||||
// object FlameThrowerExplosion : PrototypeType("flame-thrower-explosion"),
|
||||
// object FireFlame : PrototypeType("fire"),
|
||||
// object FluidStream : PrototypeType("stream"),
|
||||
// object FlyingText : PrototypeType("flying-text"),
|
||||
// object HighlightBoxEntity : PrototypeType("highlight-box"),
|
||||
// object ItemEntity : PrototypeType("item-entity"),
|
||||
// object ItemRequestProxy : PrototypeType("item-request-proxy"),
|
||||
// object ParticleSource : PrototypeType("particle-source"),
|
||||
// object Projectile : PrototypeType("projectile"),
|
||||
// object ResourceEntity : PrototypeType("resource"),
|
||||
// object RocketSiloRocket : PrototypeType("rocket-silo-rocket"),
|
||||
// object RocketSiloRocketShadow : PrototypeType("rocket-silo-rocket-shadow"),
|
||||
//
|
||||
// /** for migration, cannot be used */
|
||||
// object SimpleSmoke : PrototypeType("smoke"), PrototypeAbstract.Smoke
|
||||
// object SmokeWithTrigger : PrototypeType("smoke-with-trigger"), PrototypeAbstract.Smoke
|
||||
// object SpeechBubble : PrototypeType("speech-bubble"), PrototypeAbstract.Smoke
|
||||
// object Sticker : PrototypeType("sticker"), PrototypeAbstract.Smoke
|
||||
// object TileGhost : PrototypeType("tile-ghost"), PrototypeAbstract.Smoke
|
||||
//
|
||||
// object Equipment : PrototypeType("abstract>")
|
||||
// object ActiveDefenseEquipment : PrototypeType("active-defense-equipment")
|
||||
// object BatteryEquipment : PrototypeType("battery-equipment")
|
||||
// object BeltImmunityEquipment : PrototypeType("belt-immunity-equipment")
|
||||
// object EnergyShieldEquipment : PrototypeType("energy-shield-equipment")
|
||||
// object GeneratorEquipment : PrototypeType("generator-equipment")
|
||||
// object MovementBonusEquipment : PrototypeType("movement-bonus-equipment")
|
||||
// object NightVisionEquipment : PrototypeType("night-vision-equipment")
|
||||
// object RoboportEquipment : PrototypeType("roboport-equipment")
|
||||
// object SolarPanelEquipment : PrototypeType("solar-panel-equipment")
|
||||
// object EquipmentCategory : PrototypeType("equipment-category")
|
||||
// object EquipmentGrid : PrototypeType("equipment-grid")
|
||||
// object Fluid : PrototypeType("fluid")
|
||||
// object FuelCategory : PrototypeType("fuel-category")
|
||||
// object GuiStyle : PrototypeType("gui-style")
|
||||
// object Item : PrototypeType("item")
|
||||
// object AmmoItem : PrototypeType("ammo")
|
||||
// object Capsule : PrototypeType("capsule")
|
||||
// object Gun : PrototypeType("gun")
|
||||
// object ItemWithEntityData : PrototypeType("item-with-entity-data")
|
||||
// object ItemWithLabel : PrototypeType("item-with-label")
|
||||
// object ItemWithInventory : PrototypeType("item-with-inventory")
|
||||
// object BlueprintBook : PrototypeType("blueprint-book")
|
||||
// object ItemWithTags : PrototypeType("item-with-tags")
|
||||
// object SelectionTool : PrototypeType("selection-tool")
|
||||
// object BlueprintItem : PrototypeType("blueprint")
|
||||
// object CopyPasteTool : PrototypeType("copy-paste-tool")
|
||||
// object DeconstructionItem : PrototypeType("deconstruction-item")
|
||||
// object UpgradeItem : PrototypeType("upgrade-item")
|
||||
// object Module : PrototypeType("module")
|
||||
// object RailPlanner : PrototypeType("rail-planner")
|
||||
// object SpidertronRemote : PrototypeType("spidertron-remote")
|
||||
// object Tool : PrototypeType("tool")
|
||||
// object Armor : PrototypeType("armor")
|
||||
// /** for migration, cannot be used */
|
||||
// object MiningTool : PrototypeType("mining-tool")
|
||||
// object RepairTool : PrototypeType("repair-tool")
|
||||
// object ItemGroup : PrototypeType("item-group")
|
||||
// object ItemSubGroup : PrototypeType("item-subgroup")
|
||||
// object ModuleCategory : PrototypeType("module-category")
|
||||
// object NamedNoiseExpression : PrototypeType("noise-expression")
|
||||
// object NoiseLayer : PrototypeType("noise-layer")
|
||||
// object Particle : PrototypeType("optimized-particle")
|
||||
// object Recipe : PrototypeType("recipe")
|
||||
// object RecipeCategory : PrototypeType("recipe-category")
|
||||
// object ResourceCategory : PrototypeType("resource-category")
|
||||
// object Shortcut : PrototypeType("shortcut")
|
||||
// object Technology : PrototypeType("technology")
|
||||
// object Tile : PrototypeType("tile")
|
||||
// object TipsAndTricksItem : PrototypeType("tips-and-tricks-item")
|
||||
// object TrivialSmoke : PrototypeType("trivial-smoke")
|
||||
// object Tutorial : PrototypeType("tutorial")
|
||||
// object UtilityConstants : PrototypeType("utility-constants")
|
||||
// object UtilitySounds : PrototypeType("utility-sounds")
|
||||
// object UtilitySprites : PrototypeType("utility-sprites")
|
||||
// object VirtualSignal : PrototypeType("virtual-signal")
|
||||
//
|
||||
//}
|
||||
//
|
||||
//@Suppress("unused")
|
||||
//sealed interface PrototypeAbstract {
|
||||
// //@formatter:off
|
||||
// sealed interface PrototypeBase : PrototypeAbstract
|
||||
// sealed interface Entity : PrototypeAbstract
|
||||
// sealed interface EntityWithHealth : Entity
|
||||
//
|
||||
// sealed interface EntityWithOwner : EntityWithHealth
|
||||
//
|
||||
// sealed interface Combinator : EntityWithOwner
|
||||
// sealed interface CraftingMachine : EntityWithOwner
|
||||
// sealed interface FlyingRobot : EntityWithOwner
|
||||
//
|
||||
// sealed interface RobotWithLogisticInterface : FlyingRobot
|
||||
//
|
||||
// sealed interface Rail : EntityWithOwner
|
||||
//
|
||||
// sealed interface RailSignalBase : EntityWithOwner
|
||||
// sealed interface TransportBeltConnectable : EntityWithOwner
|
||||
// sealed interface Vehicle : EntityWithOwner
|
||||
// sealed interface RollingStock : Vehicle
|
||||
// sealed interface Smoke : Entity
|
||||
// sealed interface Equipment : PrototypeAbstract
|
||||
// //@formatter:on
|
||||
//}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
||||
* [[Prototype/AmbientSound]] '''ambient-sound'''
|
||||
* [[Prototype/Animation]] '''animation'''
|
||||
* [[Prototype/EditorController]] '''editor-controller'''
|
||||
* [[Prototype/Font]] '''font'''
|
||||
* [[Prototype/GodController]] '''god-controller'''
|
||||
* [[Prototype/MapGenPresets]] '''map-gen-presets'''
|
||||
* [[Prototype/MapSettings]] '''map-settings'''
|
||||
* [[Prototype/MouseCursor]] '''mouse-cursor'''
|
||||
* [[Prototype/Sound]] '''sound'''
|
||||
* [[Prototype/SpectatorController]] '''spectator-controller'''
|
||||
* [[Prototype/Sprite]] '''sprite'''
|
||||
* [[Prototype/TileEffect]] '''tile-effect'''
|
||||
* [[Prototype/TipsAndTricksItemCategory]] '''tips-and-tricks-item-category'''
|
||||
* [[Prototype/TriggerTargetType]] '''trigger-target-type'''
|
||||
* [[Prototype/WindSound]] '''wind-sound'''
|
||||
* [[PrototypeBase]] <abstract>
|
||||
</div><div class="prototype-tree">
|
||||
* [[Prototype/Achievement]] '''achievement'''
|
||||
** [[Prototype/BuildEntityAchievement]] '''build-entity-achievement'''
|
||||
** [[Prototype/CombatRobotCountAchievement]] '''combat-robot-count'''
|
||||
** [[Prototype/ConstructWithRobotsAchievement]] '''construct-with-robots-achievement'''
|
||||
** [[Prototype/DeconstructWithRobotsAchievement]] '''deconstruct-with-robots-achievement'''
|
||||
** [[Prototype/DeliverByRobotsAchievement]] '''deliver-by-robots-achievement'''
|
||||
** [[Prototype/DontBuildEntityAchievement]] '''dont-build-entity-achievement'''
|
||||
** [[Prototype/DontCraftManuallyAchievement]] '''dont-craft-manually-achievement'''
|
||||
** [[Prototype/DontUseEntityInEnergyProductionAchievement]] '''dont-use-entity-in-energy-production-achievement'''
|
||||
** [[Prototype/FinishTheGameAchievement]] '''finish-the-game-achievement'''
|
||||
** [[Prototype/GroupAttackAchievement]] '''group-attack-achievement'''
|
||||
** [[Prototype/KillAchievement]] '''kill-achievement'''
|
||||
** [[Prototype/PlayerDamagedAchievement]] '''player-damaged-achievement'''
|
||||
** [[Prototype/ProduceAchievement]] '''produce-achievement'''
|
||||
** [[Prototype/ProducePerHourAchievement]] '''produce-per-hour-achievement'''
|
||||
** [[Prototype/ResearchAchievement]] '''research-achievement'''
|
||||
** [[Prototype/TrainPathAchievement]] '''train-path-achievement'''
|
||||
* [[Prototype/AmmoCategory]] '''ammo-category'''
|
||||
* [[Prototype/AutoplaceControl]] '''autoplace-control'''
|
||||
* [[Prototype/CustomInput]] '''custom-input'''
|
||||
* [[Prototype/DamageType]] '''damage-type'''
|
||||
* [[Prototype/Decorative]] '''optimized-decorative'''
|
||||
* [[Prototype/Entity]] <abstract>
|
||||
** [[Prototype/Arrow]] '''arrow'''
|
||||
** [[Prototype/ArtilleryFlare]] '''artillery-flare'''
|
||||
** [[Prototype/ArtilleryProjectile]] '''artillery-projectile'''
|
||||
** [[Prototype/Beam]] '''beam'''
|
||||
** [[Prototype/CharacterCorpse]] '''character-corpse'''
|
||||
** [[Prototype/Cliff]] '''cliff'''
|
||||
** [[Prototype/Corpse]] '''corpse'''
|
||||
*** [[Prototype/RailRemnants]] '''rail-remnants'''
|
||||
** [[Prototype/DeconstructibleTileProxy]] '''deconstructible-tile-proxy'''
|
||||
** [[Prototype/EntityGhost]] '''entity-ghost'''
|
||||
** [[Prototype/EntityParticle]] '''particle''' (for migration, cannot be used)
|
||||
*** [[Prototype/LeafParticle]] '''leaf-particle''' (for migration, cannot be used)
|
||||
** [[Prototype/EntityWithHealth]] <abstract>
|
||||
*** [[Prototype/EntityWithOwner]] <abstract>
|
||||
**** [[Prototype/Accumulator]] '''accumulator'''
|
||||
**** [[Prototype/ArtilleryTurret]] '''artillery-turret'''
|
||||
**** [[Prototype/Beacon]] '''beacon'''
|
||||
**** [[Prototype/Boiler]] '''boiler'''
|
||||
**** [[Prototype/BurnerGenerator]] '''burner-generator'''
|
||||
**** [[Prototype/Character]] '''character'''
|
||||
**** [[Prototype/Combinator]] <abstract>
|
||||
***** [[Prototype/ArithmeticCombinator]] '''arithmetic-combinator'''
|
||||
***** [[Prototype/DeciderCombinator]] '''decider-combinator'''
|
||||
**** [[Prototype/ConstantCombinator]] '''constant-combinator'''
|
||||
**** [[Prototype/Container]] '''container'''
|
||||
***** [[Prototype/LogisticContainer]] '''logistic-container'''
|
||||
****** [[Prototype/InfinityContainer]] '''infinity-container'''
|
||||
**** [[Prototype/CraftingMachine]] <abstract>
|
||||
***** [[Prototype/AssemblingMachine]] '''assembling-machine'''
|
||||
****** [[Prototype/RocketSilo]] '''rocket-silo'''
|
||||
***** [[Prototype/Furnace]] '''furnace'''
|
||||
**** [[Prototype/ElectricEnergyInterface]] '''electric-energy-interface'''
|
||||
**** [[Prototype/ElectricPole]] '''electric-pole'''
|
||||
**** [[Prototype/EnemySpawner]] '''unit-spawner'''
|
||||
**** [[Prototype/FlyingRobot]] <abstract>
|
||||
***** [[Prototype/CombatRobot]] '''combat-robot'''
|
||||
***** [[Prototype/RobotWithLogisticInterface]] <abstract>
|
||||
****** [[Prototype/ConstructionRobot]] '''construction-robot'''
|
||||
****** [[Prototype/LogisticRobot]] '''logistic-robot'''
|
||||
**** [[Prototype/Gate]] '''gate'''
|
||||
**** [[Prototype/Generator]] '''generator'''
|
||||
**** [[Prototype/HeatInterface]] '''heat-interface'''
|
||||
**** [[Prototype/HeatPipe]] '''heat-pipe'''
|
||||
**** [[Prototype/Inserter]] '''inserter'''
|
||||
**** [[Prototype/Lab]] '''lab'''
|
||||
**** [[Prototype/Lamp]] '''lamp'''
|
||||
**** [[Prototype/LandMine]] '''land-mine'''
|
||||
**** [[Prototype/LinkedContainer]] '''linked-container'''
|
||||
**** [[Prototype/Market]] '''market'''
|
||||
**** [[Prototype/MiningDrill]] '''mining-drill'''
|
||||
**** [[Prototype/OffshorePump]] '''offshore-pump'''
|
||||
**** [[Prototype/Pipe]] '''pipe'''
|
||||
***** [[Prototype/InfinityPipe]] '''infinity-pipe'''
|
||||
**** [[Prototype/PipeToGround]] '''pipe-to-ground'''
|
||||
**** [[Prototype/PlayerPort]] '''player-port'''
|
||||
**** [[Prototype/PowerSwitch]] '''power-switch'''
|
||||
**** [[Prototype/ProgrammableSpeaker]] '''programmable-speaker'''
|
||||
**** [[Prototype/Pump]] '''pump'''
|
||||
**** [[Prototype/Radar]] '''radar'''
|
||||
**** [[Prototype/Rail]] <abstract>
|
||||
***** [[Prototype/CurvedRail]] '''curved-rail'''
|
||||
***** [[Prototype/StraightRail]] '''straight-rail'''
|
||||
**** [[Prototype/RailSignalBase]] <abstract>
|
||||
***** [[Prototype/RailChainSignal]] '''rail-chain-signal'''
|
||||
***** [[Prototype/RailSignal]] '''rail-signal'''
|
||||
**** [[Prototype/Reactor]] '''reactor'''
|
||||
**** [[Prototype/Roboport]] '''roboport'''
|
||||
**** [[Prototype/SimpleEntityWithOwner]] '''simple-entity-with-owner'''
|
||||
***** [[Prototype/SimpleEntityWithForce]] '''simple-entity-with-force'''
|
||||
**** [[Prototype/SolarPanel]] '''solar-panel'''
|
||||
**** [[Prototype/StorageTank]] '''storage-tank'''
|
||||
**** [[Prototype/TrainStop]] '''train-stop'''
|
||||
**** [[Prototype/TransportBeltConnectable]] <abstract>
|
||||
***** [[Prototype/LinkedBelt]] '''linked-belt'''
|
||||
***** [[Prototype/Loader1x1]] '''loader-1x1'''
|
||||
***** [[Prototype/Loader1x2]] '''loader'''
|
||||
***** [[Prototype/Splitter]] '''splitter'''
|
||||
***** [[Prototype/TransportBelt]] '''transport-belt'''
|
||||
***** [[Prototype/UndergroundBelt]] '''underground-belt'''
|
||||
**** [[Prototype/Turret]] '''turret'''
|
||||
***** [[Prototype/AmmoTurret]] '''ammo-turret'''
|
||||
***** [[Prototype/ElectricTurret]] '''electric-turret'''
|
||||
***** [[Prototype/FluidTurret]] '''fluid-turret'''
|
||||
**** [[Prototype/Unit]] '''unit'''
|
||||
**** [[Prototype/Vehicle]] <abstract>
|
||||
***** [[Prototype/Car]] '''car'''
|
||||
***** [[Prototype/RollingStock]] <abstract>
|
||||
****** [[Prototype/ArtilleryWagon]] '''artillery-wagon'''
|
||||
****** [[Prototype/CargoWagon]] '''cargo-wagon'''
|
||||
****** [[Prototype/FluidWagon]] '''fluid-wagon'''
|
||||
****** [[Prototype/Locomotive]] '''locomotive'''
|
||||
***** [[Prototype/SpiderVehicle]] '''spider-vehicle'''
|
||||
**** [[Prototype/Wall]] '''wall'''
|
||||
*** [[Prototype/Fish]] '''fish'''
|
||||
*** [[Prototype/SimpleEntity]] '''simple-entity'''
|
||||
*** [[Prototype/SpiderLeg]] '''spider-leg'''
|
||||
*** [[Prototype/Tree]] '''tree'''
|
||||
** [[Prototype/Explosion]] '''explosion'''
|
||||
*** [[Prototype/FlameThrowerExplosion]] '''flame-thrower-explosion'''
|
||||
** [[Prototype/FireFlame]] '''fire'''
|
||||
** [[Prototype/FluidStream]] '''stream'''
|
||||
** [[Prototype/FlyingText]] '''flying-text'''
|
||||
** [[Prototype/HighlightBoxEntity]] '''highlight-box'''
|
||||
** [[Prototype/ItemEntity]] '''item-entity'''
|
||||
** [[Prototype/ItemRequestProxy]] '''item-request-proxy'''
|
||||
** [[Prototype/ParticleSource]] '''particle-source'''
|
||||
** [[Prototype/Projectile]] '''projectile'''
|
||||
** [[Prototype/ResourceEntity]] '''resource'''
|
||||
** [[Prototype/RocketSiloRocket]] '''rocket-silo-rocket'''
|
||||
** [[Prototype/RocketSiloRocketShadow]] '''rocket-silo-rocket-shadow'''
|
||||
** [[Prototype/Smoke]] <abstract>
|
||||
*** [[Prototype/SimpleSmoke]] '''smoke''' (for migration, cannot be used)
|
||||
*** [[Prototype/SmokeWithTrigger]] '''smoke-with-trigger'''
|
||||
** [[Prototype/SpeechBubble]] '''speech-bubble'''
|
||||
** [[Prototype/Sticker]] '''sticker'''
|
||||
** [[Prototype/TileGhost]] '''tile-ghost'''
|
||||
* [[Prototype/Equipment]] <abstract>
|
||||
** [[Prototype/ActiveDefenseEquipment]] '''active-defense-equipment'''
|
||||
** [[Prototype/BatteryEquipment]] '''battery-equipment'''
|
||||
** [[Prototype/BeltImmunityEquipment]] '''belt-immunity-equipment'''
|
||||
** [[Prototype/EnergyShieldEquipment]] '''energy-shield-equipment'''
|
||||
** [[Prototype/GeneratorEquipment]] '''generator-equipment'''
|
||||
** [[Prototype/MovementBonusEquipment]] '''movement-bonus-equipment'''
|
||||
** [[Prototype/NightVisionEquipment]] '''night-vision-equipment'''
|
||||
** [[Prototype/RoboportEquipment]] '''roboport-equipment'''
|
||||
** [[Prototype/SolarPanelEquipment]] '''solar-panel-equipment'''
|
||||
* [[Prototype/EquipmentCategory]] '''equipment-category'''
|
||||
* [[Prototype/EquipmentGrid]] '''equipment-grid'''
|
||||
* [[Prototype/Fluid]] '''fluid'''
|
||||
* [[Prototype/FuelCategory]] '''fuel-category'''
|
||||
* [[Prototype/GuiStyle]] '''gui-style'''
|
||||
* [[Prototype/Item]] '''item'''
|
||||
** [[Prototype/AmmoItem]] '''ammo'''
|
||||
** [[Prototype/Capsule]] '''capsule'''
|
||||
** [[Prototype/Gun]] '''gun'''
|
||||
** [[Prototype/ItemWithEntityData]] '''item-with-entity-data'''
|
||||
** [[Prototype/ItemWithLabel]] '''item-with-label'''
|
||||
*** [[Prototype/ItemWithInventory]] '''item-with-inventory'''
|
||||
**** [[Prototype/BlueprintBook]] '''blueprint-book'''
|
||||
*** [[Prototype/ItemWithTags]] '''item-with-tags'''
|
||||
*** [[Prototype/SelectionTool]] '''selection-tool'''
|
||||
**** [[Prototype/BlueprintItem]] '''blueprint'''
|
||||
**** [[Prototype/CopyPasteTool]] '''copy-paste-tool'''
|
||||
**** [[Prototype/DeconstructionItem]] '''deconstruction-item'''
|
||||
**** [[Prototype/UpgradeItem]] '''upgrade-item'''
|
||||
** [[Prototype/Module]] '''module'''
|
||||
** [[Prototype/RailPlanner]] '''rail-planner'''
|
||||
** [[Prototype/SpidertronRemote]] '''spidertron-remote'''
|
||||
** [[Prototype/Tool]] '''tool'''
|
||||
*** [[Prototype/Armor]] '''armor'''
|
||||
*** [[Prototype/MiningTool]] '''mining-tool''' (for migration, cannot be used)
|
||||
*** [[Prototype/RepairTool]] '''repair-tool'''
|
||||
* [[Prototype/ItemGroup]] '''item-group'''
|
||||
* [[Prototype/ItemSubGroup]] '''item-subgroup'''
|
||||
* [[Prototype/ModuleCategory]] '''module-category'''
|
||||
* [[Prototype/NamedNoiseExpression]] '''noise-expression'''
|
||||
* [[Prototype/NoiseLayer]] '''noise-layer'''
|
||||
* [[Prototype/Particle]] '''optimized-particle'''
|
||||
* [[Prototype/Recipe]] '''recipe'''
|
||||
* [[Prototype/RecipeCategory]] '''recipe-category'''
|
||||
* [[Prototype/ResourceCategory]] '''resource-category'''
|
||||
* [[Prototype/Shortcut]] '''shortcut'''
|
||||
* [[Prototype/Technology]] '''technology'''
|
||||
* [[Prototype/Tile]] '''tile'''
|
||||
* [[Prototype/TipsAndTricksItem]] '''tips-and-tricks-item'''
|
||||
* [[Prototype/TrivialSmoke]] '''trivial-smoke'''
|
||||
* [[Prototype/Tutorial]] '''tutorial'''
|
||||
* [[Prototype/UtilityConstants]] '''utility-constants'''
|
||||
* [[Prototype/UtilitySounds]] '''utility-sounds'''
|
||||
* [[Prototype/UtilitySprites]] '''utility-sprites'''
|
||||
* [[Prototype/VirtualSignal]] '''virtual-signal'''
|
||||
|
||||
*/
|
||||
|
|
@ -6,16 +6,11 @@ import kotlinx.serialization.Serializable
|
|||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.resource.MinedProduct")
|
||||
data class MinedProduct(
|
||||
/** `item` or `fluid`. */
|
||||
val type: Type,
|
||||
sealed interface MinedProduct {
|
||||
|
||||
/** Prototype name of the result. */
|
||||
@SerialName("name")
|
||||
val resultPrototype: PrototypeName,
|
||||
|
||||
//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified.
|
||||
val amount: Double?,
|
||||
val resultProtoId: PrototypeId
|
||||
//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified.
|
||||
val amount: Double?
|
||||
|
||||
//Minimal amount of the item or fluid to give. Has no effect when amount is specified.
|
||||
//amount_min : Uint or double?,
|
||||
|
|
@ -26,17 +21,24 @@ data class MinedProduct(
|
|||
//A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced.
|
||||
//probability : Double?,
|
||||
|
||||
//How much of this product is a catalyst.
|
||||
//How much of this product is a catalyst.
|
||||
//catalyst_amount : Uint or double?,
|
||||
) {
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.resource.MinedProductType")
|
||||
enum class Type {
|
||||
@SerialName("item")
|
||||
ITEM,
|
||||
@SerialName("fluid")
|
||||
FLUID,
|
||||
}
|
||||
@SerialName("kafkatorio.resource.MinedProduct.MinedProductFluid")
|
||||
data class Fluid(
|
||||
override val amount: Double? = null,
|
||||
override val resultProtoId: PrototypeId,
|
||||
) : MinedProduct
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.resource.MinedProduct.MinedProductItem")
|
||||
data class Item(
|
||||
override val amount: Double? = null,
|
||||
override val resultProtoId: PrototypeId,
|
||||
) : MinedProduct
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,13 @@ import dev.adamko.kafkatorio.schema.common.Colour
|
|||
import dev.adamko.kafkatorio.schema.common.EntityIdentifiers
|
||||
import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData
|
||||
import dev.adamko.kafkatorio.schema.common.EventName
|
||||
import dev.adamko.kafkatorio.schema.common.FactorioEntityData
|
||||
import dev.adamko.kafkatorio.schema.common.ForceIndex
|
||||
import dev.adamko.kafkatorio.schema.common.MapChunkPosition
|
||||
import dev.adamko.kafkatorio.schema.common.MapEntityPosition
|
||||
import dev.adamko.kafkatorio.schema.common.MapTileDictionary
|
||||
import dev.adamko.kafkatorio.schema.common.PlayerIndex
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeName
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeId
|
||||
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
|
||||
import dev.adamko.kafkatorio.schema.common.Tick
|
||||
import dev.adamko.kafkatorio.schema.common.UnitNumber
|
||||
|
|
@ -23,6 +24,8 @@ import kotlinx.serialization.Serializable
|
|||
sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() {
|
||||
abstract val key: KafkatorioKeyedPacketKey
|
||||
/** A list of all events that have been aggregated into this packet. */
|
||||
// Maybe change to be Map<EventName, Tick>, where Tick is the most recent event?
|
||||
// A complete event timeline isn't necessary. The most recent tick of an event is good enough, and requires less space.
|
||||
abstract val events: Map<EventName, List<Tick>>?
|
||||
}
|
||||
|
||||
|
|
@ -40,8 +43,7 @@ sealed class KafkatorioKeyedPacketKey
|
|||
data class EntityUpdateKey(
|
||||
/** While normally optional, here a [unitNumber] is required for caching */
|
||||
override val unitNumber: UnitNumber,
|
||||
override val name: String,
|
||||
override val protoType: String,
|
||||
override val protoId: PrototypeId,
|
||||
) : EntityIdentifiers, KafkatorioKeyedPacketKey()
|
||||
|
||||
|
||||
|
|
@ -60,7 +62,6 @@ data class EntityUpdate(
|
|||
val lastUser: UInt? = null,
|
||||
val localisedDescription: String? = null,
|
||||
val localisedName: String? = null,
|
||||
val prototype: PrototypeName? = null,
|
||||
) : KafkatorioKeyedPacketData()
|
||||
|
||||
|
||||
|
|
@ -68,17 +69,18 @@ data class EntityUpdate(
|
|||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.packet.keyed.MapChunkUpdateKey")
|
||||
data class MapChunkUpdateKey(
|
||||
@SerialName("kafkatorio.packet.keyed.MapChunkTileUpdateKey")
|
||||
data class MapChunkTileUpdateKey(
|
||||
// val index: PlayerIndex, // maybe add player/robot key, to allow metrics like 'player x mined y tiles'
|
||||
val chunkPosition: MapChunkPosition,
|
||||
val surfaceIndex: SurfaceIndex,
|
||||
) : KafkatorioKeyedPacketKey()
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.packet.keyed.MapChunkUpdate")
|
||||
data class MapChunkUpdate(
|
||||
override val key: MapChunkUpdateKey,
|
||||
@SerialName("kafkatorio.packet.keyed.MapChunkTileUpdate")
|
||||
data class MapChunkTileUpdate(
|
||||
override val key: MapChunkTileUpdateKey,
|
||||
|
||||
override val events: Map<EventName, List<Tick>>? = null,
|
||||
|
||||
|
|
@ -93,6 +95,7 @@ data class MapChunkUpdate(
|
|||
|
||||
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.packet.keyed.PlayerUpdateKey")
|
||||
data class PlayerUpdateKey(
|
||||
|
|
@ -134,4 +137,32 @@ data class PlayerUpdate(
|
|||
) : KafkatorioKeyedPacketData()
|
||||
|
||||
|
||||
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdateKey")
|
||||
data class MapChunkEntityUpdateKey(
|
||||
val protoId: PrototypeId,
|
||||
val surfaceIndex: SurfaceIndex,
|
||||
val chunkPosition: MapChunkPosition,
|
||||
) : KafkatorioKeyedPacketKey()
|
||||
|
||||
|
||||
/**
|
||||
* @property[distinctEntities] Distinct entities. The key is arbitrary and is only used
|
||||
* for de-duplicating updates. It should only contain data that can be obtained from
|
||||
* [the value][FactorioEntityData].
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("kafkatorio.packet.keyed.MapChunkEntityUpdate")
|
||||
data class MapChunkEntityUpdate(
|
||||
override val key: MapChunkEntityUpdateKey,
|
||||
|
||||
override val events: Map<EventName, List<Tick>>? = null,
|
||||
|
||||
val distinctEntities: Map<String, FactorioEntityData>? = null,
|
||||
) : KafkatorioKeyedPacketData()
|
||||
|
||||
|
||||
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import dev.adamko.kafkatorio.library.jsonMapperKafkatorio
|
|||
import dev.adamko.kafkatorio.schema.common.EventName
|
||||
import dev.adamko.kafkatorio.schema.common.MapChunkPosition
|
||||
import dev.adamko.kafkatorio.schema.common.MapTileDictionary
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeName
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeId
|
||||
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
|
||||
import dev.adamko.kafkatorio.schema.common.tick
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdateKey
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import kotlinx.serialization.decodeFromString
|
||||
|
|
@ -59,8 +59,8 @@ class MapChunkUpdateTest : FunSpec({
|
|||
val expected = KafkatorioPacket(
|
||||
tick = 36u.tick,
|
||||
modVersion = "0.4.0",
|
||||
data = MapChunkUpdate(
|
||||
key = MapChunkUpdateKey(
|
||||
data = MapChunkTileUpdate(
|
||||
key = MapChunkTileUpdateKey(
|
||||
MapChunkPosition(-6, -3),
|
||||
SurfaceIndex(1u),
|
||||
),
|
||||
|
|
@ -78,9 +78,9 @@ class MapChunkUpdateTest : FunSpec({
|
|||
),
|
||||
),
|
||||
protos = mapOf(
|
||||
PrototypeName("water") to MapTileDictionary.PrototypeKey(1),
|
||||
PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2),
|
||||
PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32),
|
||||
PrototypeId("tile", "water") to MapTileDictionary.PrototypeKey(1),
|
||||
PrototypeId("tile", "grass-4") to MapTileDictionary.PrototypeKey(2),
|
||||
PrototypeId("tile", "grass-3") to MapTileDictionary.PrototypeKey(32),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package dev.adamko.kafkatorio.events.schema
|
|||
import dev.adamko.kafkatorio.library.jsonMapperKafkatorio
|
||||
import dev.adamko.kafkatorio.schema.common.Colour
|
||||
import dev.adamko.kafkatorio.schema.common.FactorioPrototype
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeName
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeId
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
|
||||
import io.kotest.core.spec.style.BehaviorSpec
|
||||
|
|
@ -12,6 +12,7 @@ import io.kotest.matchers.shouldBe
|
|||
import io.kotest.matchers.types.shouldBeInstanceOf
|
||||
import kotlinx.serialization.decodeFromString
|
||||
|
||||
|
||||
class PrototypesTest : BehaviorSpec({
|
||||
Given("Prototypes Json") {
|
||||
// language=JSON
|
||||
|
|
@ -669,7 +670,7 @@ class PrototypesTest : BehaviorSpec({
|
|||
.prototypes
|
||||
.forOne {
|
||||
it.shouldBeInstanceOf<FactorioPrototype.MapTile>()
|
||||
it.name shouldBe PrototypeName("tutorial-grid")
|
||||
it.protoId shouldBe PrototypeId.MapTile("tutorial-grid")
|
||||
it.order shouldBe "z[other]-c[tutorial]-a[tutorial-grid]"
|
||||
it.layer shouldBe 55u
|
||||
it.collisionMasks shouldBe listOf("ground-tile")
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import dev.adamko.kafkatorio.schema.common.EventName
|
|||
import dev.adamko.kafkatorio.schema.common.ForceIndex
|
||||
import dev.adamko.kafkatorio.schema.common.MapEntityPosition
|
||||
import dev.adamko.kafkatorio.schema.common.PlayerIndex
|
||||
import dev.adamko.kafkatorio.schema.common.PrototypeId
|
||||
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
|
||||
import dev.adamko.kafkatorio.schema.common.Tick
|
||||
import dev.adamko.kafkatorio.schema.common.UnitNumber
|
||||
|
|
@ -190,8 +191,7 @@ class UpdatePacketsTest : FunSpec({
|
|||
colour = null,
|
||||
diedCause = EntityIdentifiersData(
|
||||
unitNumber = UnitNumber(66u),
|
||||
name = "small-biter",
|
||||
protoType = "unit",
|
||||
protoId = PrototypeId("unit/small-biter"),
|
||||
),
|
||||
disconnectReason = null,
|
||||
events = mapOf(
|
||||
|
|
|
|||
|
|
@ -20,22 +20,22 @@ class MapTileDictionaryTest : FunSpec({
|
|||
"44" to mapOf("1" to MapTileDictionary.PrototypeKey(44)),
|
||||
),
|
||||
protos = mapOf(
|
||||
PrototypeName("water") to MapTileDictionary.PrototypeKey(1),
|
||||
PrototypeName("grass-4") to MapTileDictionary.PrototypeKey(2),
|
||||
PrototypeName("grass-3") to MapTileDictionary.PrototypeKey(32),
|
||||
PrototypeId.MapTile("water") to MapTileDictionary.PrototypeKey(1),
|
||||
PrototypeId.MapTile("grass-4") to MapTileDictionary.PrototypeKey(2),
|
||||
PrototypeId.MapTile("grass-3") to MapTileDictionary.PrototypeKey(32),
|
||||
|
||||
PrototypeName("not-used") to MapTileDictionary.PrototypeKey(99),
|
||||
PrototypeId.MapTile("not-used") to MapTileDictionary.PrototypeKey(99),
|
||||
)
|
||||
)
|
||||
|
||||
test("toMapTileList") {
|
||||
actual.toMapTileList() shouldContainAll listOf(
|
||||
MapTile(-192, -65, PrototypeName("grass-4")),
|
||||
MapTile(-192, -65, PrototypeId.MapTile("grass-4")),
|
||||
|
||||
MapTile(161, -96, PrototypeName("water")),
|
||||
MapTile(161, -95, PrototypeName("grass-4")),
|
||||
MapTile(161, 94, PrototypeName("grass-4")),
|
||||
MapTile(161, 93, PrototypeName("grass-3")),
|
||||
MapTile(161, -96, PrototypeId.MapTile("water")),
|
||||
MapTile(161, -95, PrototypeId.MapTile("grass-4")),
|
||||
MapTile(161, 94, PrototypeId.MapTile("grass-4")),
|
||||
MapTile(161, 93, PrototypeId.MapTile("grass-3")),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
package dev.adamko.kafkatorio.events.schema
|
||||
|
||||
import dev.adamko.kafkatorio.schema.common.PlayerIndex
|
||||
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
|
||||
import dev.adamko.kafkatorio.schema.common.UnitNumber
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
|
||||
import dev.adamko.kxstsgen.KxsTsConfig
|
||||
import dev.adamko.kxstsgen.KxsTsConfig.TypeAliasTypingConfig.BrandTyping
|
||||
import dev.adamko.kxstsgen.KxsTsGenerator
|
||||
import dev.adamko.kxstsgen.core.TsDeclaration.TsTypeAlias
|
||||
import dev.adamko.kxstsgen.core.TsElementId
|
||||
import dev.adamko.kxstsgen.core.TsLiteral
|
||||
import dev.adamko.kxstsgen.core.TsSourceCodeGenerator
|
||||
import dev.adamko.kxstsgen.core.TsTypeRef
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.createDirectories
|
||||
|
|
@ -13,14 +18,24 @@ import kotlinx.serialization.builtins.serializer
|
|||
import org.intellij.lang.annotations.Language
|
||||
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
val config = KxsTsConfig(
|
||||
// typeAliasTyping = BrandTyping
|
||||
typeAliasTyping = BrandTyping
|
||||
)
|
||||
|
||||
val gen2 = KxsTsGenerator(config)
|
||||
val gen2 = KxsTsGenerator(
|
||||
config = config,
|
||||
sourceCodeGenerator = MySourceCodeGenerator(config),
|
||||
)
|
||||
|
||||
// gen2.serializerDescriptorOverrides += mapOf(
|
||||
////@formatter:off
|
||||
// SurfaceIndex.serializer() to emptySet(),
|
||||
// PlayerIndex.serializer() to emptySet(),
|
||||
// UnitNumber.serializer() to emptySet(),
|
||||
////@formatter:on
|
||||
// )
|
||||
|
||||
gen2.descriptorOverrides += mapOf(
|
||||
//@formatter:off
|
||||
|
|
@ -32,6 +47,10 @@ fun main(args: Array<String>) {
|
|||
UByte .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UByte" ), TsTypeRef.Literal(TsLiteral.Custom("uint8" ), false)),
|
||||
UShort.serializer().descriptor to TsTypeAlias(TsElementId("kotlin.UShort"), TsTypeRef.Literal(TsLiteral.Custom("uint16"), false)),
|
||||
ULong .serializer().descriptor to TsTypeAlias(TsElementId("kotlin.ULong" ), TsTypeRef.Literal(TsLiteral.Custom("uint64"), false)),
|
||||
|
||||
PlayerIndex.serializer().descriptor to TsTypeAlias(TsElementId("PlayerIndex" ), TsTypeRef.Literal(TsLiteral.Custom("PlayerIndex"), false)),
|
||||
SurfaceIndex.serializer().descriptor to TsTypeAlias(TsElementId("SurfaceIndex" ), TsTypeRef.Literal(TsLiteral.Custom("SurfaceIndex"), false)),
|
||||
UnitNumber.serializer().descriptor to TsTypeAlias(TsElementId("UnitNumber" ), TsTypeRef.Literal(TsLiteral.Custom("UnitNumber"), false)),
|
||||
//@formatter:on
|
||||
)
|
||||
|
||||
|
|
@ -60,3 +79,26 @@ val kt2tsHeader = """
|
|||
|// Generated by kxs-ts-gen - do not edit this file manually
|
||||
|
|
||||
""".trimMargin()
|
||||
|
||||
|
||||
class MySourceCodeGenerator(
|
||||
config: KxsTsConfig,
|
||||
) : TsSourceCodeGenerator.Default(config) {
|
||||
|
||||
override fun generateTypeAlias(element: TsTypeAlias): String {
|
||||
|
||||
return if (element.id.name in listOf("PlayerIndex", "SurfaceIndex", "UnitNumber")) {
|
||||
""
|
||||
} else if (
|
||||
(element.typeRef as? TsTypeRef.Literal)?.element is TsLiteral.Custom
|
||||
|| element.id.name == "Tick"
|
||||
) {
|
||||
val aliasedRef = generateTypeReference(element.typeRef)
|
||||
"""
|
||||
|export type ${element.id.name} = ${aliasedRef};
|
||||
""".trimMargin()
|
||||
} else {
|
||||
super.generateTypeAlias(element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ val installEventsTsSchema by tasks.registering(Sync::class) {
|
|||
}
|
||||
) {
|
||||
// drop the first directory inside the zip
|
||||
eachFile { relativePath = dropDirectory() }
|
||||
// eachFile { relativePath = dropDirectory() }
|
||||
includeEmptyDirs = false
|
||||
}
|
||||
into(outputDir)
|
||||
|
|
|
|||
6
modules/events-mod/package-lock.json
generated
6
modules/events-mod/package-lock.json
generated
|
|
@ -75,9 +75,9 @@
|
|||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
|
||||
},
|
||||
"typed-factorio": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.3.0.tgz",
|
||||
"integrity": "sha512-qBHKjE+m9Im7vDhsGvl0uwaSFzJ5asqyfw414gF0owZwmSax2CIjdLx367qUgdD4flsB0n9HecBaZ0Yzt9zMPQ=="
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.3.2.tgz",
|
||||
"integrity": "sha512-sAVIDvSSBPWL7trI94SPd2Suq9dLjXmXL1WFKJIYJpFQocNwJUb0ydGRBsvJjZhVAyEZYJC0lHlDWH47RWP/tw=="
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.7.4",
|
||||
|
|
|
|||
|
|
@ -9,15 +9,19 @@
|
|||
"engines": {
|
||||
"node": "~14.19.1"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"devDependencies": {
|
||||
},
|
||||
"dependencies": {
|
||||
"lua-types": "^2.11.0",
|
||||
"typescript-to-lua": "1.6.1",
|
||||
"typed-factorio": "1.3.0",
|
||||
"typed-factorio": "1.3.2",
|
||||
"typescript": "4.7.4"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"peerDependencies": {},
|
||||
"optionalDependencies": {},
|
||||
"bundledDependencies": []
|
||||
"peerDependencies": {
|
||||
},
|
||||
"optionalDependencies": {
|
||||
},
|
||||
"bundledDependencies": [
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ local ____global_2Dinit = require("main.global-init")
|
|||
local initGlobal = ____global_2Dinit.initGlobal
|
||||
local ____prototypeUpdates = require("main.events.prototypeUpdates")
|
||||
local emitPrototypes = ____prototypeUpdates.emitPrototypes
|
||||
require("main.events.registerHandlers")
|
||||
require("main.events.registerEventListeners")
|
||||
require("main.events.mapChunkUpdates")
|
||||
require("main.events.playerUpdates")
|
||||
require("main.events.entityUpdates")
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ do
|
|||
KafkatorioPacketData.Type.PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate"
|
||||
KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate"
|
||||
KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate"
|
||||
KafkatorioPacketData.Type.MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate"
|
||||
KafkatorioPacketData.Type.MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate"
|
||||
KafkatorioPacketData.Type.MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate"
|
||||
KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate"
|
||||
KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error"
|
||||
end
|
||||
|
|
@ -20,7 +21,62 @@ do
|
|||
FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity"
|
||||
FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile"
|
||||
end
|
||||
____exports.MinedProductType = MinedProductType or ({})
|
||||
____exports.MinedProductType.item = "item"
|
||||
____exports.MinedProductType.fluid = "fluid"
|
||||
____exports.FactorioEntityData = {}
|
||||
local FactorioEntityData = ____exports.FactorioEntityData
|
||||
do
|
||||
FactorioEntityData.Type = Type or ({})
|
||||
FactorioEntityData.Type.Resource = "kafkatorio.entity.FactorioEntityData.Resource"
|
||||
FactorioEntityData.Type.Standard = "kafkatorio.entity.FactorioEntityData.Standard"
|
||||
end
|
||||
____exports.EntityStatus = EntityStatus or ({})
|
||||
____exports.EntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS"
|
||||
____exports.EntityStatus.CHARGING = "CHARGING"
|
||||
____exports.EntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK"
|
||||
____exports.EntityStatus.DISABLED = "DISABLED"
|
||||
____exports.EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR"
|
||||
____exports.EntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT"
|
||||
____exports.EntityStatus.DISCHARGING = "DISCHARGING"
|
||||
____exports.EntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE"
|
||||
____exports.EntityStatus.FULLY_CHARGED = "FULLY_CHARGED"
|
||||
____exports.EntityStatus.FULL_OUTPUT = "FULL_OUTPUT"
|
||||
____exports.EntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE"
|
||||
____exports.EntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET"
|
||||
____exports.EntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID"
|
||||
____exports.EntityStatus.LOW_POWER = "LOW_POWER"
|
||||
____exports.EntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE"
|
||||
____exports.EntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION"
|
||||
____exports.EntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID"
|
||||
____exports.EntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS"
|
||||
____exports.EntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED"
|
||||
____exports.EntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED"
|
||||
____exports.EntityStatus.NORMAL = "NORMAL"
|
||||
____exports.EntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL"
|
||||
____exports.EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK"
|
||||
____exports.EntityStatus.NO_AMMO = "NO_AMMO"
|
||||
____exports.EntityStatus.NO_FUEL = "NO_FUEL"
|
||||
____exports.EntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS"
|
||||
____exports.EntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID"
|
||||
____exports.EntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES"
|
||||
____exports.EntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT"
|
||||
____exports.EntityStatus.NO_POWER = "NO_POWER"
|
||||
____exports.EntityStatus.NO_RECIPE = "NO_RECIPE"
|
||||
____exports.EntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS"
|
||||
____exports.EntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK"
|
||||
____exports.EntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK"
|
||||
____exports.EntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH"
|
||||
____exports.EntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE"
|
||||
____exports.EntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME"
|
||||
____exports.EntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS"
|
||||
____exports.EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION"
|
||||
____exports.EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT"
|
||||
____exports.EntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN"
|
||||
____exports.EntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET"
|
||||
____exports.EntityStatus.WORKING = "WORKING"
|
||||
____exports.MinedProduct = {}
|
||||
local MinedProduct = ____exports.MinedProduct
|
||||
do
|
||||
MinedProduct.Type = Type or ({})
|
||||
MinedProduct.Type.MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid"
|
||||
MinedProduct.Type.MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem"
|
||||
end
|
||||
return ____exports
|
||||
|
|
|
|||
|
|
@ -1,7 +1,22 @@
|
|||
local ____exports = {}
|
||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||
local EntityStatus = ____kafkatorio_2Dschema.EntityStatus
|
||||
local FactorioEntityData = ____kafkatorio_2Dschema.FactorioEntityData
|
||||
____exports.Converters = {}
|
||||
local Converters = ____exports.Converters
|
||||
do
|
||||
local convertEntityStatus, EntityStatusRecord
|
||||
function convertEntityStatus(status)
|
||||
if status == nil then
|
||||
return nil
|
||||
else
|
||||
return EntityStatusRecord[status]
|
||||
end
|
||||
end
|
||||
function Converters.prototypeId(____type, name)
|
||||
return (____type .. "/") .. name
|
||||
end
|
||||
local floor = math.floor
|
||||
local mapEventIdToName = {}
|
||||
for eventName, eventId in pairs(defines.events) do
|
||||
mapEventIdToName[eventId] = eventName
|
||||
|
|
@ -36,5 +51,86 @@ do
|
|||
end
|
||||
return masks
|
||||
end
|
||||
function Converters.convertResourceEntity(entity)
|
||||
if entity.type ~= "resource" then
|
||||
return nil
|
||||
else
|
||||
return {
|
||||
type = FactorioEntityData.Type.Resource,
|
||||
protoId = Converters.prototypeId(entity.type, entity.name),
|
||||
status = convertEntityStatus(entity.status),
|
||||
amount = entity.amount,
|
||||
initialAmount = entity.initial_amount,
|
||||
position = Converters.convertMapTablePosition(entity.position)
|
||||
}
|
||||
end
|
||||
end
|
||||
function Converters.prototypeIdEntity(entity)
|
||||
return Converters.prototypeId(entity.type, entity.name)
|
||||
end
|
||||
function Converters.tilePositionToChunkPosition(mapPosition)
|
||||
return {
|
||||
floor(mapPosition.x / 32),
|
||||
floor(mapPosition.y)
|
||||
}
|
||||
end
|
||||
function Converters.mapPositionToChunkPosition(mapPosition)
|
||||
return {
|
||||
floor(mapPosition.x / 32),
|
||||
floor(mapPosition.y)
|
||||
}
|
||||
end
|
||||
function Converters.entityStatus(status)
|
||||
if status == nil then
|
||||
return nil
|
||||
else
|
||||
return EntityStatusRecord[status]
|
||||
end
|
||||
end
|
||||
EntityStatusRecord = {
|
||||
[defines.entity_status.cant_divide_segments] = EntityStatus.CANT_DIVIDE_SEGMENTS,
|
||||
[defines.entity_status.charging] = EntityStatus.CHARGING,
|
||||
[defines.entity_status.closed_by_circuit_network] = EntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
|
||||
[defines.entity_status.disabled] = EntityStatus.DISABLED,
|
||||
[defines.entity_status.disabled_by_control_behavior] = EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
|
||||
[defines.entity_status.disabled_by_script] = EntityStatus.DISABLED_BY_SCRIPT,
|
||||
[defines.entity_status.discharging] = EntityStatus.DISCHARGING,
|
||||
[defines.entity_status.fluid_ingredient_shortage] = EntityStatus.FLUID_INGREDIENT_SHORTAGE,
|
||||
[defines.entity_status.fully_charged] = EntityStatus.FULLY_CHARGED,
|
||||
[defines.entity_status.full_output] = EntityStatus.FULL_OUTPUT,
|
||||
[defines.entity_status.item_ingredient_shortage] = EntityStatus.ITEM_INGREDIENT_SHORTAGE,
|
||||
[defines.entity_status.launching_rocket] = EntityStatus.LAUNCHING_ROCKET,
|
||||
[defines.entity_status.low_input_fluid] = EntityStatus.LOW_INPUT_FLUID,
|
||||
[defines.entity_status.low_power] = EntityStatus.LOW_POWER,
|
||||
[defines.entity_status.low_temperature] = EntityStatus.LOW_TEMPERATURE,
|
||||
[defines.entity_status.marked_for_deconstruction] = EntityStatus.MARKED_FOR_DECONSTRUCTION,
|
||||
[defines.entity_status.missing_required_fluid] = EntityStatus.MISSING_REQUIRED_FLUID,
|
||||
[defines.entity_status.missing_science_packs] = EntityStatus.MISSING_SCIENCE_PACKS,
|
||||
[defines.entity_status.networks_connected] = EntityStatus.NETWORKS_CONNECTED,
|
||||
[defines.entity_status.networks_disconnected] = EntityStatus.NETWORKS_DISCONNECTED,
|
||||
[defines.entity_status.normal] = EntityStatus.NORMAL,
|
||||
[defines.entity_status.not_connected_to_rail] = EntityStatus.NOT_CONNECTED_TO_RAIL,
|
||||
[defines.entity_status.not_plugged_in_electric_network] = EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
|
||||
[defines.entity_status.no_ammo] = EntityStatus.NO_AMMO,
|
||||
[defines.entity_status.no_fuel] = EntityStatus.NO_FUEL,
|
||||
[defines.entity_status.no_ingredients] = EntityStatus.NO_INGREDIENTS,
|
||||
[defines.entity_status.no_input_fluid] = EntityStatus.NO_INPUT_FLUID,
|
||||
[defines.entity_status.no_minable_resources] = EntityStatus.NO_MINABLE_RESOURCES,
|
||||
[defines.entity_status.no_modules_to_transmit] = EntityStatus.NO_MODULES_TO_TRANSMIT,
|
||||
[defines.entity_status.no_power] = EntityStatus.NO_POWER,
|
||||
[defines.entity_status.no_recipe] = EntityStatus.NO_RECIPE,
|
||||
[defines.entity_status.no_research_in_progress] = EntityStatus.NO_RESEARCH_IN_PROGRESS,
|
||||
[defines.entity_status.opened_by_circuit_network] = EntityStatus.OPENED_BY_CIRCUIT_NETWORK,
|
||||
[defines.entity_status.out_of_logistic_network] = EntityStatus.OUT_OF_LOGISTIC_NETWORK,
|
||||
[defines.entity_status.preparing_rocket_for_launch] = EntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
|
||||
[defines.entity_status.recharging_after_power_outage] = EntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
|
||||
[defines.entity_status.turned_off_during_daytime] = EntityStatus.TURNED_OFF_DURING_DAYTIME,
|
||||
[defines.entity_status.waiting_for_source_items] = EntityStatus.WAITING_FOR_SOURCE_ITEMS,
|
||||
[defines.entity_status.waiting_for_space_in_destination] = EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
|
||||
[defines.entity_status.waiting_for_target_to_be_built] = EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
|
||||
[defines.entity_status.waiting_for_train] = EntityStatus.WAITING_FOR_TRAIN,
|
||||
[defines.entity_status.waiting_to_launch_rocket] = EntityStatus.WAITING_TO_LAUNCH_ROCKET,
|
||||
[defines.entity_status.working] = EntityStatus.WORKING
|
||||
}
|
||||
end
|
||||
return ____exports
|
||||
|
|
|
|||
|
|
@ -1,105 +1,203 @@
|
|||
local ____lualib = require("lualib_bundle")
|
||||
local __TS__Class = ____lualib.__TS__Class
|
||||
local __TS__New = ____lualib.__TS__New
|
||||
local ____exports = {}
|
||||
local handleBuiltEntityEvent, handleMinedEntityEvent
|
||||
local ____converters = require("main.events.converters")
|
||||
local Converters = ____converters.Converters
|
||||
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
|
||||
function handleBuiltEntityEvent(event)
|
||||
local eventName = Converters.eventNameString(event.name)
|
||||
if event.created_entity.unit_number == nil then
|
||||
____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 key = {name = event.created_entity.name, protoType = event.created_entity.prototype.name, unitNumber = event.created_entity.unit_number}
|
||||
EventDataCache:debounce(
|
||||
key,
|
||||
KafkatorioPacketData.Type.EntityUpdate,
|
||||
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_0, ____eventName_1 = data.events, eventName
|
||||
if ____data_events_0[____eventName_1] == nil then
|
||||
____data_events_0[____eventName_1] = {}
|
||||
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_2 = data.events[eventName]
|
||||
____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick
|
||||
data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position)
|
||||
data.graphicsVariation = event.created_entity.graphics_variation
|
||||
data.health = event.created_entity.health
|
||||
data.isActive = event.created_entity.active
|
||||
data.isRotatable = event.created_entity.rotatable
|
||||
local ____data_5 = data
|
||||
local ____event_created_entity_last_user_index_3 = event.created_entity.last_user
|
||||
if ____event_created_entity_last_user_index_3 ~= nil then
|
||||
____event_created_entity_last_user_index_3 = ____event_created_entity_last_user_index_3.index
|
||||
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_5.lastUser = ____event_created_entity_last_user_index_3
|
||||
data.prototype = event.created_entity.prototype.name
|
||||
data.distinctEntities[entityKey] = entityUpdate
|
||||
end
|
||||
)
|
||||
end
|
||||
function handleMinedEntityEvent(event)
|
||||
local eventName = Converters.eventNameString(event.name)
|
||||
if event.entity.unit_number == nil then
|
||||
return
|
||||
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
|
||||
local key = {name = event.entity.name, protoType = event.entity.prototype.name, unitNumber = event.entity.unit_number}
|
||||
EventDataCache:debounce(
|
||||
key,
|
||||
KafkatorioPacketData.Type.EntityUpdate,
|
||||
function(data)
|
||||
if data.events == nil then
|
||||
data.events = {}
|
||||
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
|
||||
local ____data_events_6, ____eventName_7 = data.events, eventName
|
||||
if ____data_events_6[____eventName_7] == nil then
|
||||
____data_events_6[____eventName_7] = {}
|
||||
end
|
||||
local ____data_events_eventName_8 = data.events[eventName]
|
||||
____data_events_eventName_8[#____data_events_eventName_8 + 1] = event.tick
|
||||
data.chunkPosition = Converters.convertMapTablePosition(event.entity.position)
|
||||
data.graphicsVariation = event.entity.graphics_variation
|
||||
data.health = event.entity.health
|
||||
data.isActive = event.entity.active
|
||||
data.isRotatable = event.entity.rotatable
|
||||
local ____data_11 = data
|
||||
local ____event_entity_last_user_index_9 = event.entity.last_user
|
||||
if ____event_entity_last_user_index_9 ~= nil then
|
||||
____event_entity_last_user_index_9 = ____event_entity_last_user_index_9.index
|
||||
end
|
||||
____data_11.lastUser = ____event_entity_last_user_index_9
|
||||
data.prototype = event.entity.prototype.name
|
||||
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(
|
||||
defines.events.on_built_entity,
|
||||
function(e)
|
||||
log("on_built_entity " .. tostring(e.tick))
|
||||
handleBuiltEntityEvent(e)
|
||||
EntityUpdates:handleBuiltEntityEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_robot_built_entity,
|
||||
function(e)
|
||||
log("on_robot_built_entity " .. tostring(e.tick))
|
||||
handleBuiltEntityEvent(e)
|
||||
EntityUpdates:handleBuiltEntityEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_player_mined_entity,
|
||||
function(e)
|
||||
log("on_player_mined_entity " .. tostring(e.tick))
|
||||
handleMinedEntityEvent(e)
|
||||
EntityUpdates:handleMinedEntityEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_robot_mined_entity,
|
||||
function(e)
|
||||
log("on_robot_mined_entity " .. tostring(e.tick))
|
||||
handleMinedEntityEvent(e)
|
||||
EntityUpdates:handleMinedEntityEvent(e)
|
||||
end
|
||||
)
|
||||
return ____exports
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
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 mapTilesUpdateDebounce, getTiles, getSurface, groupTiles, handleBuiltTileEvent, handleMinedTileEvent, Type
|
||||
local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
||||
local isEventType = ____eventTypeCheck.isEventType
|
||||
local ____converters = require("main.events.converters")
|
||||
|
|
@ -12,65 +12,16 @@ local ____EventDataCache = require("main.cache.EventDataCache")
|
|||
local EventUpdatesManager = ____EventDataCache.default
|
||||
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
|
||||
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
|
||||
function mapTilesUpdateDebounce(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.MapChunkUpdate,
|
||||
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 ____data_tileDictionary_protos_1, ____tile_name_2 = data.tileDictionary.protos, tile.name
|
||||
if ____data_tileDictionary_protos_1[____tile_name_2] == nil then
|
||||
local ____protosCount_0 = protosCount
|
||||
protosCount = ____protosCount_0 + 1
|
||||
____data_tileDictionary_protos_1[____tile_name_2] = ____protosCount_0
|
||||
end
|
||||
local protoKey = data.tileDictionary.protos[tile.name]
|
||||
local xString = tostring(tile.position.x)
|
||||
local yString = tostring(tile.position.y)
|
||||
local ____data_tileDictionary_tilesXY_3, ____xString_4 = data.tileDictionary.tilesXY, xString
|
||||
if ____data_tileDictionary_tilesXY_3[____xString_4] == nil then
|
||||
____data_tileDictionary_tilesXY_3[____xString_4] = {}
|
||||
end
|
||||
data.tileDictionary.tilesXY[xString][yString] = protoKey
|
||||
end
|
||||
if data.events == nil then
|
||||
data.events = {}
|
||||
end
|
||||
local ____data_events_5, ____eventName_6 = data.events, eventName
|
||||
if ____data_events_5[____eventName_6] == nil then
|
||||
____data_events_5[____eventName_6] = {}
|
||||
end
|
||||
local ____data_events_eventName_7 = data.events[eventName]
|
||||
____data_events_eventName_7[#____data_events_eventName_7 + 1] = event.tick
|
||||
if updater ~= nil then
|
||||
updater(data)
|
||||
end
|
||||
end,
|
||||
expirationDurationTicks
|
||||
)
|
||||
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 getTiles(surface, area)
|
||||
local ____surface_find_tiles_filtered_result_8 = surface
|
||||
if ____surface_find_tiles_filtered_result_8 ~= nil then
|
||||
____surface_find_tiles_filtered_result_8 = ____surface_find_tiles_filtered_result_8.find_tiles_filtered({area = area})
|
||||
end
|
||||
return ____surface_find_tiles_filtered_result_8 or ({})
|
||||
end
|
||||
function getSurface(surfaceIndex)
|
||||
return game.surfaces[surfaceIndex]
|
||||
end
|
||||
function ____exports.handleChunkGeneratedEvent(event, expirationDurationTicks)
|
||||
local tiles = getTiles(event.surface, event.area)
|
||||
mapTilesUpdateDebounce(
|
||||
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,
|
||||
|
|
@ -79,38 +30,19 @@ function ____exports.handleChunkGeneratedEvent(event, expirationDurationTicks)
|
|||
expirationDurationTicks
|
||||
)
|
||||
end
|
||||
function groupTiles(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_10 = mapChunkPositionToTiles:get(chunkPosition)
|
||||
if ____mapChunkPositionToTiles_get_result_push_result_10 ~= nil then
|
||||
local ____temp_11 = mapChunkPositionToTiles:get(chunkPosition)
|
||||
____temp_11[#____temp_11 + 1] = tile
|
||||
____mapChunkPositionToTiles_get_result_push_result_10 = nil
|
||||
end
|
||||
end
|
||||
return mapChunkPositionToTiles
|
||||
end
|
||||
function handleBuiltTileEvent(event)
|
||||
local surface = getSurface(event.surface_index)
|
||||
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 = groupTiles(tiles)
|
||||
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
|
||||
for ____, ____value in __TS__Iterator(groupedTiles) do
|
||||
local chunkPos = ____value[1]
|
||||
local tiles = ____value[2]
|
||||
mapTilesUpdateDebounce(
|
||||
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
||||
surface,
|
||||
chunkPos,
|
||||
tiles,
|
||||
|
|
@ -121,12 +53,15 @@ function handleBuiltTileEvent(event)
|
|||
return
|
||||
end
|
||||
if isEventType(event, defines.events.on_robot_built_tile) then
|
||||
local ____data_15 = data
|
||||
local ____event_robot_unit_number_13 = event.robot
|
||||
if ____event_robot_unit_number_13 ~= nil then
|
||||
____event_robot_unit_number_13 = ____event_robot_unit_number_13.unit_number
|
||||
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_15.robot = {unitNumber = ____event_robot_unit_number_13 or nil, name = event.robot.name, protoType = event.robot.type}
|
||||
____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
|
||||
|
|
@ -134,19 +69,19 @@ function handleBuiltTileEvent(event)
|
|||
)
|
||||
end
|
||||
end
|
||||
function handleMinedTileEvent(event)
|
||||
local surface = getSurface(event.surface_index)
|
||||
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 = groupTiles(tiles)
|
||||
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
|
||||
for ____, ____value in __TS__Iterator(groupedTiles) do
|
||||
local chunkPos = ____value[1]
|
||||
local tiles = ____value[2]
|
||||
mapTilesUpdateDebounce(
|
||||
MapChunkUpdateHandler:mapTilesUpdateDebounce(
|
||||
surface,
|
||||
chunkPos,
|
||||
tiles,
|
||||
|
|
@ -157,12 +92,15 @@ function handleMinedTileEvent(event)
|
|||
return
|
||||
end
|
||||
if isEventType(event, defines.events.on_robot_mined_tile) then
|
||||
local ____data_18 = data
|
||||
local ____event_robot_unit_number_16 = event.robot
|
||||
if ____event_robot_unit_number_16 ~= nil then
|
||||
____event_robot_unit_number_16 = ____event_robot_unit_number_16.unit_number
|
||||
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_18.robot = {unitNumber = ____event_robot_unit_number_16 or nil, name = event.robot.name, protoType = event.robot.type}
|
||||
____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
|
||||
|
|
@ -170,78 +108,155 @@ function handleMinedTileEvent(event)
|
|||
)
|
||||
end
|
||||
end
|
||||
Type = KafkatorioPacketData.Type
|
||||
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(
|
||||
defines.events.on_chunk_generated,
|
||||
function(e)
|
||||
log("on_chunk_generated " .. tostring(e.tick))
|
||||
____exports.handleChunkGeneratedEvent(e)
|
||||
MapChunkUpdate:handleChunkGeneratedEvent(e)
|
||||
EntityUpdates:handleChunkGeneratedEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.script_raised_set_tiles,
|
||||
function(event)
|
||||
log("script_raised_set_tiles " .. tostring(event.tick))
|
||||
local surface = getSurface(event.surface_index)
|
||||
if surface == nil then
|
||||
return
|
||||
end
|
||||
local groupedTiles = groupTiles(event.tiles)
|
||||
for ____, ____value in __TS__Iterator(groupedTiles) do
|
||||
local chunkPos = ____value[1]
|
||||
local tiles = ____value[2]
|
||||
mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
|
||||
end
|
||||
MapChunkUpdate:handleScriptSetTilesEvent(event)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_player_built_tile,
|
||||
function(e)
|
||||
log("on_player_built_tile " .. tostring(e.tick))
|
||||
handleBuiltTileEvent(e)
|
||||
MapChunkUpdate:handleBuiltTileEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_robot_built_tile,
|
||||
function(e)
|
||||
log("on_robot_built_tile " .. tostring(e.tick))
|
||||
handleBuiltTileEvent(e)
|
||||
MapChunkUpdate:handleBuiltTileEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_player_mined_tile,
|
||||
function(e)
|
||||
log("on_player_mined_tile " .. tostring(e.tick))
|
||||
handleMinedTileEvent(e)
|
||||
MapChunkUpdate:handleMinedTileEvent(e)
|
||||
EntityUpdates:handleMinedTileEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_robot_mined_tile,
|
||||
function(e)
|
||||
log("on_robot_mined_tile " .. tostring(e.tick))
|
||||
handleMinedTileEvent(e)
|
||||
MapChunkUpdate:handleMinedTileEvent(e)
|
||||
end
|
||||
)
|
||||
script.on_event(
|
||||
defines.events.on_pre_chunk_deleted,
|
||||
function(e)
|
||||
log("on_pre_chunk_deleted " .. tostring(e.tick))
|
||||
local surface = getSurface(e.surface_index)
|
||||
if surface == nil then
|
||||
return
|
||||
end
|
||||
for ____, position in ipairs(e.positions) do
|
||||
local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}}
|
||||
EventUpdatesManager:debounce(
|
||||
key,
|
||||
Type.MapChunkUpdate,
|
||||
function(data)
|
||||
data.isDeleted = true
|
||||
return true
|
||||
end,
|
||||
0
|
||||
)
|
||||
end
|
||||
MapChunkUpdate:handlePreChunkDeleted(e)
|
||||
end
|
||||
)
|
||||
return ____exports
|
||||
|
|
|
|||
|
|
@ -115,7 +115,10 @@ script.on_event(
|
|||
data.ticksToRespawn = player.ticks_to_respawn or nil
|
||||
playerOnlineInfo(player, data)
|
||||
if e.cause ~= nil then
|
||||
data.diedCause = {unitNumber = e.cause.unit_number or nil, name = e.cause.name, protoType = e.cause.type}
|
||||
data.diedCause = {
|
||||
unitNumber = e.cause.unit_number or nil,
|
||||
protoId = Converters.prototypeId(e.cause.type, e.cause.name)
|
||||
}
|
||||
end
|
||||
end
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ function getMapTilePrototypes()
|
|||
for ____, tile in pairs(game.tile_prototypes) do
|
||||
tiles[#tiles + 1] = {
|
||||
type = FactorioPrototype.Type.MapTile,
|
||||
name = tile.name,
|
||||
protoId = Converters.prototypeId("tile", tile.name),
|
||||
order = tile.order,
|
||||
layer = tile.layer,
|
||||
collisionMasks = Converters.convertCollisionMaskToNames(tile.collision_mask),
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ local ____eventTypeCheck = require("main.events.eventTypeCheck")
|
|||
local isEventType = ____eventTypeCheck.isEventType
|
||||
local ____converters = require("main.events.converters")
|
||||
local Converters = ____converters.Converters
|
||||
local ____mapChunkUpdates = require("main.events.mapChunkUpdates")
|
||||
local handleChunkGeneratedEvent = ____mapChunkUpdates.handleChunkGeneratedEvent
|
||||
local ____surfaceUpdates = require("main.events.surfaceUpdates")
|
||||
local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate
|
||||
local ____EventDataCache = require("main.cache.EventDataCache")
|
||||
local EventCacheService = ____EventDataCache.default
|
||||
local ____mapChunkUpdates = require("main.events.mapChunkUpdates")
|
||||
local MapChunkUpdate = ____mapChunkUpdates.default
|
||||
script.on_event(
|
||||
defines.events.on_tick,
|
||||
function(event)
|
||||
|
|
@ -38,7 +38,7 @@ script.on_event(
|
|||
if isEventType(event, defines.events.on_chunk_generated) then
|
||||
local eName = Converters.eventNameString(event.name)
|
||||
log((((("[on_tick:" .. tostring(event.tick)) .. "] dequed event ") .. eName) .. ", delay ") .. tostring(i))
|
||||
handleChunkGeneratedEvent(event, i)
|
||||
MapChunkUpdate:handleChunkGeneratedEvent(event, i)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
|
@ -34,7 +34,7 @@ end
|
|||
function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type)
|
||||
return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-")
|
||||
end
|
||||
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5}
|
||||
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30, ["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5}
|
||||
local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig)
|
||||
____exports.default = KafkatorioSettings
|
||||
return ____exports
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
[mod-setting-name]
|
||||
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds)
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=Map update rate (seconds)
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=Map tile update rate (seconds)
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=Entity update rate (seconds)
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds)
|
||||
|
||||
|
||||
[mod-setting-description]
|
||||
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine!
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine!
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkTileUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine!
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-MapChunkEntityUpdate=How frequently entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine!
|
||||
kafkatorio:cache-expiration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine!
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {initGlobal} from "./main/global-init";
|
||||
import {emitPrototypes} from "./main/events/prototypeUpdates";
|
||||
|
||||
require("./main/events/registerHandlers")
|
||||
require("./main/events/registerEventListeners")
|
||||
require("./main/events/mapChunkUpdates")
|
||||
require("./main/events/playerUpdates")
|
||||
require("./main/events/entityUpdates")
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ export type KafkatorioPacketData =
|
|||
| KafkatorioPacketData.ConsoleCommandUpdate
|
||||
| KafkatorioPacketData.EntityUpdate
|
||||
| KafkatorioPacketData.Error
|
||||
| KafkatorioPacketData.MapChunkUpdate
|
||||
| KafkatorioPacketData.MapChunkEntityUpdate
|
||||
| KafkatorioPacketData.MapChunkTileUpdate
|
||||
| KafkatorioPacketData.PlayerUpdate
|
||||
| KafkatorioPacketData.PrototypesUpdate
|
||||
| KafkatorioPacketData.SurfaceUpdate;
|
||||
|
|
@ -27,7 +28,8 @@ export namespace KafkatorioPacketData {
|
|||
PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate",
|
||||
SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate",
|
||||
EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate",
|
||||
MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate",
|
||||
MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate",
|
||||
MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate",
|
||||
PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate",
|
||||
Error = "kafkatorio.packet.KafkatorioPacketData.Error",
|
||||
}
|
||||
|
|
@ -77,12 +79,18 @@ export namespace KafkatorioPacketData {
|
|||
lastUser?: UInt | null;
|
||||
localisedDescription?: string | null;
|
||||
localisedName?: string | null;
|
||||
prototype?: PrototypeName | null;
|
||||
}
|
||||
|
||||
export interface MapChunkUpdate {
|
||||
type: KafkatorioPacketData.Type.MapChunkUpdate;
|
||||
key: MapChunkUpdateKey;
|
||||
export interface MapChunkEntityUpdate {
|
||||
type: KafkatorioPacketData.Type.MapChunkEntityUpdate;
|
||||
key: MapChunkEntityUpdateKey;
|
||||
events?: { [key: EventName]: Tick[] } | null;
|
||||
distinctEntities?: { [key: string]: FactorioEntityData } | null;
|
||||
}
|
||||
|
||||
export interface MapChunkTileUpdate {
|
||||
type: KafkatorioPacketData.Type.MapChunkTileUpdate;
|
||||
key: MapChunkTileUpdateKey;
|
||||
events?: { [key: EventName]: Tick[] } | null;
|
||||
player?: PlayerIndex | null;
|
||||
robot?: EntityIdentifiersData | null;
|
||||
|
|
@ -132,16 +140,11 @@ export interface ConfigurationUpdateGameData {
|
|||
newVersion?: string | null;
|
||||
}
|
||||
|
||||
export type PlayerIndex = UInt;
|
||||
|
||||
export type SurfaceIndex = UInt;
|
||||
|
||||
export type Double = double;
|
||||
|
||||
export interface EntityUpdateKey {
|
||||
unitNumber: UnitNumber;
|
||||
name: string;
|
||||
protoType: string;
|
||||
protoId: PrototypeId;
|
||||
}
|
||||
|
||||
export type MapEntityPosition = [
|
||||
|
|
@ -153,32 +156,33 @@ export type UByte = uint8;
|
|||
|
||||
export type Float = float;
|
||||
|
||||
export type PrototypeName = string;
|
||||
export interface MapChunkEntityUpdateKey {
|
||||
protoId: PrototypeId;
|
||||
surfaceIndex: SurfaceIndex;
|
||||
chunkPosition: MapChunkPosition;
|
||||
}
|
||||
|
||||
export interface MapChunkUpdateKey {
|
||||
export interface MapChunkTileUpdateKey {
|
||||
chunkPosition: MapChunkPosition;
|
||||
surfaceIndex: SurfaceIndex;
|
||||
}
|
||||
|
||||
export interface EntityIdentifiersData {
|
||||
unitNumber?: UnitNumber | null;
|
||||
name: string;
|
||||
protoType: string;
|
||||
protoId: PrototypeId;
|
||||
}
|
||||
|
||||
export type ForceIndex = UInt;
|
||||
export type ForceIndex = UInt & { __ForceIndex__: void };
|
||||
|
||||
export interface MapTileDictionary {
|
||||
tilesXY: { [key: string]: { [key: string]: PrototypeKey } };
|
||||
protos: { [key: PrototypeName]: PrototypeKey };
|
||||
protos: { [key: PrototypeId]: PrototypeKey };
|
||||
}
|
||||
|
||||
export interface PlayerUpdateKey {
|
||||
index: PlayerIndex;
|
||||
}
|
||||
|
||||
export type UnitNumber = UInt;
|
||||
|
||||
export type Colour = [
|
||||
red: Float,
|
||||
green: Float,
|
||||
|
|
@ -206,7 +210,7 @@ export namespace FactorioPrototype {
|
|||
|
||||
export interface Entity {
|
||||
type: FactorioPrototype.Type.Entity;
|
||||
name: PrototypeName;
|
||||
protoId: PrototypeId;
|
||||
mapColour: Colour;
|
||||
protoType: string;
|
||||
objectName: string;
|
||||
|
|
@ -220,7 +224,7 @@ export namespace FactorioPrototype {
|
|||
|
||||
export interface MapTile {
|
||||
type: FactorioPrototype.Type.MapTile;
|
||||
name: PrototypeName;
|
||||
protoId: PrototypeId;
|
||||
mapColour: Colour;
|
||||
layer: UInt;
|
||||
collisionMasks: List;
|
||||
|
|
@ -229,7 +233,9 @@ export namespace FactorioPrototype {
|
|||
}
|
||||
}
|
||||
|
||||
export type EventName = string;
|
||||
export type PrototypeId = string & { __PrototypeId__: void };
|
||||
|
||||
export type EventName = string & { __EventName__: void };
|
||||
|
||||
export type Byte = int8;
|
||||
|
||||
|
|
@ -238,22 +244,114 @@ export type MapChunkPosition = [
|
|||
y: Int,
|
||||
];
|
||||
|
||||
export type FactorioEntityData =
|
||||
| FactorioEntityData.Resource
|
||||
| FactorioEntityData.Standard;
|
||||
|
||||
export namespace FactorioEntityData {
|
||||
export enum Type {
|
||||
Resource = "kafkatorio.entity.FactorioEntityData.Resource",
|
||||
Standard = "kafkatorio.entity.FactorioEntityData.Standard",
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
type: FactorioEntityData.Type.Resource;
|
||||
protoId: PrototypeId;
|
||||
status?: EntityStatus | null;
|
||||
position: MapEntityPosition;
|
||||
amount: UInt;
|
||||
initialAmount?: UInt | null;
|
||||
}
|
||||
|
||||
export interface Standard {
|
||||
type: FactorioEntityData.Type.Standard;
|
||||
protoId: PrototypeId;
|
||||
status?: EntityStatus | null;
|
||||
position: MapEntityPosition;
|
||||
graphicsVariation?: UByte | null;
|
||||
health?: Float | null;
|
||||
isActive?: boolean | null;
|
||||
isRotatable?: boolean | null;
|
||||
lastUser?: UInt | null;
|
||||
localisedDescription?: string | null;
|
||||
localisedName?: string | null;
|
||||
}
|
||||
}
|
||||
|
||||
export interface MiningProperties {
|
||||
canBeMined: boolean;
|
||||
products: MinedProduct[] | null;
|
||||
}
|
||||
|
||||
export type List = any;
|
||||
export type List = any & { __List__: void };
|
||||
|
||||
export type PrototypeKey = Int;
|
||||
|
||||
export interface MinedProduct {
|
||||
type: MinedProductType;
|
||||
name: PrototypeName;
|
||||
amount: Double | null;
|
||||
export enum EntityStatus {
|
||||
CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS",
|
||||
CHARGING = "CHARGING",
|
||||
CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK",
|
||||
DISABLED = "DISABLED",
|
||||
DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR",
|
||||
DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT",
|
||||
DISCHARGING = "DISCHARGING",
|
||||
FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE",
|
||||
FULLY_CHARGED = "FULLY_CHARGED",
|
||||
FULL_OUTPUT = "FULL_OUTPUT",
|
||||
ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE",
|
||||
LAUNCHING_ROCKET = "LAUNCHING_ROCKET",
|
||||
LOW_INPUT_FLUID = "LOW_INPUT_FLUID",
|
||||
LOW_POWER = "LOW_POWER",
|
||||
LOW_TEMPERATURE = "LOW_TEMPERATURE",
|
||||
MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION",
|
||||
MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID",
|
||||
MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS",
|
||||
NETWORKS_CONNECTED = "NETWORKS_CONNECTED",
|
||||
NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED",
|
||||
NORMAL = "NORMAL",
|
||||
NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL",
|
||||
NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK",
|
||||
NO_AMMO = "NO_AMMO",
|
||||
NO_FUEL = "NO_FUEL",
|
||||
NO_INGREDIENTS = "NO_INGREDIENTS",
|
||||
NO_INPUT_FLUID = "NO_INPUT_FLUID",
|
||||
NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES",
|
||||
NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT",
|
||||
NO_POWER = "NO_POWER",
|
||||
NO_RECIPE = "NO_RECIPE",
|
||||
NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS",
|
||||
OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK",
|
||||
OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK",
|
||||
PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH",
|
||||
RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE",
|
||||
TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME",
|
||||
WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS",
|
||||
WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION",
|
||||
WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT",
|
||||
WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN",
|
||||
WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET",
|
||||
WORKING = "WORKING",
|
||||
}
|
||||
|
||||
export enum MinedProductType {
|
||||
item = "item",
|
||||
fluid = "fluid",
|
||||
export type PrototypeKey = Int & { __PrototypeKey__: void };
|
||||
|
||||
export type MinedProduct =
|
||||
| MinedProduct.MinedProductFluid
|
||||
| MinedProduct.MinedProductItem;
|
||||
|
||||
export namespace MinedProduct {
|
||||
export enum Type {
|
||||
MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid",
|
||||
MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem",
|
||||
}
|
||||
|
||||
export interface MinedProductFluid {
|
||||
type: MinedProduct.Type.MinedProductFluid;
|
||||
amount?: Double | null;
|
||||
resultProtoId: PrototypeId;
|
||||
}
|
||||
|
||||
export interface MinedProductItem {
|
||||
type: MinedProduct.Type.MinedProductItem;
|
||||
amount?: Double | null;
|
||||
resultProtoId: PrototypeId;
|
||||
}
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ export namespace EventUpdates {
|
|||
let countExpired = 0
|
||||
let countTotal = 0
|
||||
const expiredData: Array<KafkatorioKeyedPacketData> = []
|
||||
for (let [key, entry] of global.cache) {
|
||||
for (const [key, entry] of global.cache) {
|
||||
countTotal++
|
||||
if (this.isExpired(entry)) {
|
||||
countExpired++
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ script.on_event(
|
|||
const update: KafkatorioPacketData.ConsoleCommandUpdate = {
|
||||
type: Type.ConsoleCommandUpdate,
|
||||
|
||||
authorPlayerIndex: event.player_index ?? null,
|
||||
authorPlayerIndex: event.player_index ?? null,
|
||||
command: event.command,
|
||||
parameters: event.parameters,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,25 @@
|
|||
import {EventName} from "../types";
|
||||
import {Colour, MapChunkPosition} from "../../generated/kafkatorio-schema";
|
||||
import {DefinedEventName} from "../types";
|
||||
import {
|
||||
Colour,
|
||||
EntityStatus,
|
||||
EventName,
|
||||
FactorioEntityData,
|
||||
MapChunkPosition,
|
||||
PrototypeId,
|
||||
} from "../../generated/kafkatorio-schema";
|
||||
|
||||
export namespace Converters {
|
||||
|
||||
const mapEventIdToName = new LuaTable<defines.Events, EventName>()
|
||||
|
||||
import floor = math.floor;
|
||||
const mapEventIdToName = new LuaTable<defines.Events, DefinedEventName>()
|
||||
for (const [eventName, eventId] of pairs(defines.events)) {
|
||||
mapEventIdToName.set(eventId, eventName)
|
||||
}
|
||||
|
||||
|
||||
export function eventNameString(event: defines.Events): EventName {
|
||||
return mapEventIdToName.get(event)
|
||||
return mapEventIdToName.get(event) as EventName
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -60,10 +69,115 @@ export namespace Converters {
|
|||
|
||||
export function convertCollisionMaskToNames(cm: CollisionMask): string[] {
|
||||
let masks: string[] = []
|
||||
for (let [name] of pairs(cm)) {
|
||||
for (const [name] of pairs(cm)) {
|
||||
masks.push(name)
|
||||
}
|
||||
return masks
|
||||
}
|
||||
|
||||
|
||||
export function convertResourceEntity(
|
||||
entity: LuaEntity
|
||||
): FactorioEntityData.Resource | null {
|
||||
if (entity.type != "resource") {
|
||||
return null
|
||||
} else {
|
||||
return {
|
||||
type: FactorioEntityData.Type.Resource,
|
||||
protoId: prototypeId(entity.type, entity.name),
|
||||
status: convertEntityStatus(entity.status),
|
||||
amount: entity.amount,
|
||||
initialAmount: entity.initial_amount,
|
||||
position: convertMapTablePosition(entity.position),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function convertEntityStatus(
|
||||
status: defines.entity_status | undefined
|
||||
): EntityStatus | null {
|
||||
if (status == undefined) {
|
||||
return null
|
||||
} else {
|
||||
return EntityStatusRecord[status]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function prototypeIdEntity(entity: LuaEntity): PrototypeId {
|
||||
return prototypeId(entity.type, entity.name)
|
||||
}
|
||||
|
||||
|
||||
export function prototypeId(type: string, name: string): PrototypeId {
|
||||
return `${type}/${name}` as PrototypeId
|
||||
}
|
||||
|
||||
|
||||
export function tilePositionToChunkPosition(mapPosition: TilePositionTable): MapChunkPosition {
|
||||
return [floor(mapPosition.x / 32), floor(mapPosition.y)]
|
||||
}
|
||||
|
||||
export function mapPositionToChunkPosition(mapPosition: MapPositionTable): MapChunkPosition {
|
||||
return [floor(mapPosition.x / 32), floor(mapPosition.y)]
|
||||
}
|
||||
|
||||
|
||||
export function entityStatus(status: defines.entity_status | undefined): EntityStatus | undefined {
|
||||
if (status == undefined) {
|
||||
return undefined
|
||||
} else {
|
||||
return EntityStatusRecord[status]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const EntityStatusRecord: Record<defines.entity_status, EntityStatus> = {
|
||||
//@formatter:off
|
||||
[ defines.entity_status.cant_divide_segments ]: EntityStatus.CANT_DIVIDE_SEGMENTS,
|
||||
[ defines.entity_status.charging ]: EntityStatus.CHARGING,
|
||||
[ defines.entity_status.closed_by_circuit_network ]: EntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
|
||||
[ defines.entity_status.disabled ]: EntityStatus.DISABLED,
|
||||
[ defines.entity_status.disabled_by_control_behavior ]: EntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
|
||||
[ defines.entity_status.disabled_by_script ]: EntityStatus.DISABLED_BY_SCRIPT,
|
||||
[ defines.entity_status.discharging ]: EntityStatus.DISCHARGING,
|
||||
[ defines.entity_status.fluid_ingredient_shortage ]: EntityStatus.FLUID_INGREDIENT_SHORTAGE,
|
||||
[ defines.entity_status.fully_charged ]: EntityStatus.FULLY_CHARGED,
|
||||
[ defines.entity_status.full_output ]: EntityStatus.FULL_OUTPUT,
|
||||
[ defines.entity_status.item_ingredient_shortage ]: EntityStatus.ITEM_INGREDIENT_SHORTAGE,
|
||||
[ defines.entity_status.launching_rocket ]: EntityStatus.LAUNCHING_ROCKET,
|
||||
[ defines.entity_status.low_input_fluid ]: EntityStatus.LOW_INPUT_FLUID,
|
||||
[ defines.entity_status.low_power ]: EntityStatus.LOW_POWER,
|
||||
[ defines.entity_status.low_temperature ]: EntityStatus.LOW_TEMPERATURE,
|
||||
[ defines.entity_status.marked_for_deconstruction ]: EntityStatus.MARKED_FOR_DECONSTRUCTION,
|
||||
[ defines.entity_status.missing_required_fluid ]: EntityStatus.MISSING_REQUIRED_FLUID,
|
||||
[ defines.entity_status.missing_science_packs ]: EntityStatus.MISSING_SCIENCE_PACKS,
|
||||
[ defines.entity_status.networks_connected ]: EntityStatus.NETWORKS_CONNECTED,
|
||||
[ defines.entity_status.networks_disconnected ]: EntityStatus.NETWORKS_DISCONNECTED,
|
||||
[ defines.entity_status.normal ]: EntityStatus.NORMAL,
|
||||
[ defines.entity_status.not_connected_to_rail ]: EntityStatus.NOT_CONNECTED_TO_RAIL,
|
||||
[ defines.entity_status.not_plugged_in_electric_network ]: EntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
|
||||
[ defines.entity_status.no_ammo ]: EntityStatus.NO_AMMO,
|
||||
[ defines.entity_status.no_fuel ]: EntityStatus.NO_FUEL,
|
||||
[ defines.entity_status.no_ingredients ]: EntityStatus.NO_INGREDIENTS,
|
||||
[ defines.entity_status.no_input_fluid ]: EntityStatus.NO_INPUT_FLUID,
|
||||
[ defines.entity_status.no_minable_resources ]: EntityStatus.NO_MINABLE_RESOURCES,
|
||||
[ defines.entity_status.no_modules_to_transmit ]: EntityStatus.NO_MODULES_TO_TRANSMIT,
|
||||
[ defines.entity_status.no_power ]: EntityStatus.NO_POWER,
|
||||
[ defines.entity_status.no_recipe ]: EntityStatus.NO_RECIPE,
|
||||
[ defines.entity_status.no_research_in_progress ]: EntityStatus.NO_RESEARCH_IN_PROGRESS,
|
||||
[ defines.entity_status.opened_by_circuit_network ]: EntityStatus.OPENED_BY_CIRCUIT_NETWORK,
|
||||
[ defines.entity_status.out_of_logistic_network ]: EntityStatus.OUT_OF_LOGISTIC_NETWORK,
|
||||
[ defines.entity_status.preparing_rocket_for_launch ]: EntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
|
||||
[ defines.entity_status.recharging_after_power_outage ]: EntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
|
||||
[ defines.entity_status.turned_off_during_daytime ]: EntityStatus.TURNED_OFF_DURING_DAYTIME,
|
||||
[ defines.entity_status.waiting_for_source_items ]: EntityStatus.WAITING_FOR_SOURCE_ITEMS,
|
||||
[ defines.entity_status.waiting_for_space_in_destination ]: EntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
|
||||
[ defines.entity_status.waiting_for_target_to_be_built ]: EntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
|
||||
[ defines.entity_status.waiting_for_train ]: EntityStatus.WAITING_FOR_TRAIN,
|
||||
[ defines.entity_status.waiting_to_launch_rocket ]: EntityStatus.WAITING_TO_LAUNCH_ROCKET,
|
||||
[ defines.entity_status.working ]: EntityStatus.WORKING,
|
||||
//@formatter:on
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,97 +1,276 @@
|
|||
import {Converters} from "./converters";
|
||||
import EventDataCache from "../cache/EventDataCache";
|
||||
import {
|
||||
EntityUpdateKey,
|
||||
KafkatorioPacketData
|
||||
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) => {
|
||||
log(`on_built_entity ${e.tick}`)
|
||||
handleBuiltEntityEvent(e)
|
||||
EntityUpdates.handleBuiltEntityEvent(e)
|
||||
})
|
||||
|
||||
|
||||
script.on_event(defines.events.on_robot_built_entity, (e: OnRobotBuiltEntityEvent) => {
|
||||
log(`on_robot_built_entity ${e.tick}`)
|
||||
handleBuiltEntityEvent(e)
|
||||
EntityUpdates.handleBuiltEntityEvent(e)
|
||||
})
|
||||
|
||||
|
||||
function handleBuiltEntityEvent(event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent) {
|
||||
const eventName = Converters.eventNameString(event.name)
|
||||
|
||||
if (event.created_entity.unit_number == undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const key: EntityUpdateKey = {
|
||||
name: event.created_entity.name,
|
||||
protoType: event.created_entity.prototype.name,
|
||||
unitNumber: event.created_entity.unit_number
|
||||
}
|
||||
|
||||
EventDataCache.debounce<KafkatorioPacketData.EntityUpdate>(
|
||||
key,
|
||||
KafkatorioPacketData.Type.EntityUpdate,
|
||||
data => {
|
||||
|
||||
data.events ??= {}
|
||||
data.events[eventName] ??= []
|
||||
data.events[eventName].push(event.tick)
|
||||
|
||||
data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position)
|
||||
data.graphicsVariation = event.created_entity.graphics_variation
|
||||
data.health = event.created_entity.health
|
||||
data.isActive = event.created_entity.active
|
||||
data.isRotatable = event.created_entity.rotatable
|
||||
data.lastUser = event.created_entity.last_user?.index
|
||||
data.prototype = event.created_entity.prototype.name
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
script.on_event(defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => {
|
||||
log(`on_player_mined_entity ${e.tick}`)
|
||||
handleMinedEntityEvent(e)
|
||||
EntityUpdates.handleMinedEntityEvent(e)
|
||||
})
|
||||
|
||||
|
||||
script.on_event(defines.events.on_robot_mined_entity, (e: OnRobotMinedEntityEvent) => {
|
||||
log(`on_robot_mined_entity ${e.tick}`)
|
||||
handleMinedEntityEvent(e)
|
||||
EntityUpdates.handleMinedEntityEvent(e)
|
||||
})
|
||||
|
||||
|
||||
function handleMinedEntityEvent(event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent) {
|
||||
const eventName = Converters.eventNameString(event.name)
|
||||
type EntityUpdateEvent =
|
||||
| OnBuiltEntityEvent
|
||||
|
||||
if (event.entity.unit_number == undefined) {
|
||||
return
|
||||
}
|
||||
| OnEntityClonedEvent
|
||||
| OnEntityDamagedEvent
|
||||
| OnEntityDestroyedEvent
|
||||
| OnEntityDiedEvent
|
||||
| OnEntityLogisticSlotChangedEvent
|
||||
| OnEntityRenamedEvent
|
||||
| OnEntitySettingsPastedEvent
|
||||
| OnEntitySpawnedEvent
|
||||
|
||||
const key: EntityUpdateKey = {
|
||||
name: event.entity.name,
|
||||
protoType: event.entity.prototype.name,
|
||||
unitNumber: event.entity.unit_number
|
||||
}
|
||||
| OnPlayerMinedEntityEvent
|
||||
| OnPlayerRepairedEntityEvent
|
||||
| OnPlayerRotatedEntityEvent
|
||||
|
||||
EventDataCache.debounce<KafkatorioPacketData.EntityUpdate>(
|
||||
key,
|
||||
KafkatorioPacketData.Type.EntityUpdate,
|
||||
data => {
|
||||
| OnRobotMinedEntityEvent
|
||||
| OnRobotBuiltEntityEvent
|
||||
|
||||
data.events ??= {}
|
||||
data.events[eventName] ??= []
|
||||
data.events[eventName].push(event.tick)
|
||||
| OnPostEntityDiedEvent
|
||||
| OnPreEntitySettingsPastedEvent
|
||||
|
||||
data.chunkPosition = Converters.convertMapTablePosition(event.entity.position)
|
||||
data.graphicsVariation = event.entity.graphics_variation
|
||||
data.health = event.entity.health
|
||||
data.isActive = event.entity.active
|
||||
data.isRotatable = event.entity.rotatable
|
||||
data.lastUser = event.entity.last_user?.index
|
||||
data.prototype = event.entity.prototype.name
|
||||
}
|
||||
)
|
||||
}
|
||||
| OnSelectedEntityChangedEvent
|
||||
| OnTriggerCreatedEntityEvent
|
||||
|
|
|
|||
|
|
@ -3,129 +3,270 @@ import {Converters} from "./converters";
|
|||
import EventUpdatesManager, {EventUpdates} from "../cache/EventDataCache";
|
||||
import {
|
||||
KafkatorioPacketData,
|
||||
MapChunkPosition
|
||||
MapChunkPosition, PrototypeId,
|
||||
PrototypeKey,
|
||||
} from "../../generated/kafkatorio-schema";
|
||||
import EntityUpdates from "./entityUpdates";
|
||||
import CacheKey = EventUpdates.PacketKey;
|
||||
import Type = KafkatorioPacketData.Type;
|
||||
|
||||
|
||||
type MapChunkUpdater = (data: KafkatorioPacketData.MapChunkUpdate) => void
|
||||
type MapChunkTileUpdater = (data: KafkatorioPacketData.MapChunkTileUpdate) => void
|
||||
|
||||
|
||||
type MapTileUpdateEvent =
|
||||
| OnChunkGeneratedEvent
|
||||
export type MapTileChangeEvent =
|
||||
| OnPlayerBuiltTileEvent
|
||||
| OnPlayerMinedEntityEvent
|
||||
| OnPlayerMinedTileEvent
|
||||
| OnRobotBuiltTileEvent
|
||||
| OnRobotMinedEntityEvent
|
||||
| OnRobotMinedTileEvent
|
||||
| ScriptRaisedSetTilesEvent
|
||||
|
||||
|
||||
function mapTilesUpdateDebounce(
|
||||
surface: LuaSurface | undefined,
|
||||
chunkPosition: MapChunkPosition,
|
||||
tiles: TileRead[],
|
||||
event: MapTileUpdateEvent,
|
||||
updater?: MapChunkUpdater,
|
||||
expirationDurationTicks?: uint,
|
||||
) {
|
||||
export type MapChunkUpdateEvent =
|
||||
| OnChunkChartedEvent
|
||||
| OnChunkDeletedEvent
|
||||
| OnChunkGeneratedEvent
|
||||
| OnPreChunkDeletedEvent
|
||||
|
||||
if (surface == undefined) {
|
||||
return
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
const eventName = Converters.eventNameString(event.name)
|
||||
|
||||
const key: KafkatorioPacketData.MapChunkUpdate["key"] = {
|
||||
surfaceIndex: surface.index,
|
||||
chunkPosition: chunkPosition,
|
||||
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
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkUpdate>(
|
||||
key,
|
||||
Type.MapChunkUpdate,
|
||||
data => {
|
||||
|
||||
// tile dictionary update
|
||||
if (data.tileDictionary == undefined) {
|
||||
data.tileDictionary = {
|
||||
tilesXY: {},
|
||||
protos: {},
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
let protosCount: uint = table_size(data.tileDictionary.protos)
|
||||
for (const tile of tiles) {
|
||||
data.tileDictionary.protos[tile.name] ??= protosCount++
|
||||
const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles)
|
||||
const groupedTiles = MapChunkUpdateHandler.groupTiles(tiles)
|
||||
|
||||
const protoKey = data.tileDictionary.protos[tile.name]
|
||||
for (const [chunkPos, tiles] of groupedTiles) {
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
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
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getTiles(
|
||||
surface: LuaSurface | undefined,
|
||||
area: BoundingBoxTable
|
||||
): LuaTile[] {
|
||||
return surface?.find_tiles_filtered({
|
||||
area: area,
|
||||
// collision_mask: ["ground-tile", "water-tile"]
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function getSurface(surfaceIndex: uint): LuaSurface | undefined {
|
||||
return game.surfaces[surfaceIndex]
|
||||
}
|
||||
const MapChunkUpdate = new MapChunkUpdateHandler()
|
||||
|
||||
export default MapChunkUpdate
|
||||
|
||||
|
||||
script.on_event(
|
||||
defines.events.on_chunk_generated,
|
||||
(e: OnChunkGeneratedEvent) => {
|
||||
log(`on_chunk_generated ${e.tick}`)
|
||||
handleChunkGeneratedEvent(e)
|
||||
MapChunkUpdate.handleChunkGeneratedEvent(e)
|
||||
EntityUpdates.handleChunkGeneratedEvent(e)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
export function handleChunkGeneratedEvent(
|
||||
event: OnChunkGeneratedEvent,
|
||||
expirationDurationTicks?: uint,
|
||||
) {
|
||||
let tiles = getTiles(event.surface, event.area)
|
||||
mapTilesUpdateDebounce(
|
||||
event.surface,
|
||||
Converters.convertMapTablePosition(event.position),
|
||||
tiles,
|
||||
event,
|
||||
undefined,
|
||||
expirationDurationTicks,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// script.on_event(
|
||||
// defines.events.on_chunk_charted,
|
||||
// (e: OnChunkChartedEvent) => {
|
||||
|
|
@ -144,169 +285,38 @@ export function handleChunkGeneratedEvent(
|
|||
// )
|
||||
|
||||
|
||||
script.on_event(
|
||||
defines.events.script_raised_set_tiles,
|
||||
(event: ScriptRaisedSetTilesEvent) => {
|
||||
log(`script_raised_set_tiles ${event.tick}`)
|
||||
|
||||
const surface = getSurface(event.surface_index)
|
||||
if (surface == undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
const groupedTiles = groupTiles(event.tiles)
|
||||
|
||||
for (const [chunkPos, tiles] of groupedTiles) {
|
||||
mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
function 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, [])
|
||||
}
|
||||
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1256
|
||||
mapChunkPositionToTiles.get(chunkPosition)?.push(tile)
|
||||
// const tiles = mapChunkPositionToTiles.get(chunkPosition)
|
||||
// if (tiles != null) {
|
||||
// tiles.push(tile)
|
||||
// }
|
||||
}
|
||||
return mapChunkPositionToTiles
|
||||
}
|
||||
script.on_event(defines.events.script_raised_set_tiles, (event: ScriptRaisedSetTilesEvent) => {
|
||||
log(`script_raised_set_tiles ${event.tick}`)
|
||||
MapChunkUpdate.handleScriptSetTilesEvent(event)
|
||||
})
|
||||
|
||||
|
||||
script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => {
|
||||
log(`on_player_built_tile ${e.tick}`)
|
||||
handleBuiltTileEvent(e)
|
||||
MapChunkUpdate.handleBuiltTileEvent(e)
|
||||
})
|
||||
|
||||
|
||||
script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => {
|
||||
log(`on_robot_built_tile ${e.tick}`)
|
||||
handleBuiltTileEvent(e)
|
||||
MapChunkUpdate.handleBuiltTileEvent(e)
|
||||
})
|
||||
|
||||
function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) {
|
||||
|
||||
const surface = getSurface(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 = groupTiles(tiles)
|
||||
|
||||
for (const [chunkPos, tiles] of groupedTiles) {
|
||||
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,
|
||||
name: event.robot.name,
|
||||
protoType: event.robot.type,
|
||||
}
|
||||
return
|
||||
}
|
||||
// this line will not compile if the previous 'if' statements are not exhaustive
|
||||
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
|
||||
const exhaustiveCheck: never = event
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => {
|
||||
log(`on_player_mined_tile ${e.tick}`)
|
||||
handleMinedTileEvent(e)
|
||||
MapChunkUpdate.handleMinedTileEvent(e)
|
||||
EntityUpdates.handleMinedTileEvent(e)
|
||||
})
|
||||
|
||||
|
||||
script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => {
|
||||
log(`on_robot_mined_tile ${e.tick}`)
|
||||
handleMinedTileEvent(e)
|
||||
MapChunkUpdate.handleMinedTileEvent(e)
|
||||
})
|
||||
|
||||
function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
|
||||
const surface = getSurface(event.surface_index)
|
||||
if (surface == undefined) {
|
||||
const eventName = Converters.eventNameString(event.name)
|
||||
log(`[handleMinedTileEvent] undefined surface ${eventName}`)
|
||||
return
|
||||
}
|
||||
|
||||
const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles)
|
||||
const groupedTiles = groupTiles(tiles)
|
||||
|
||||
for (const [chunkPos, tiles] of groupedTiles) {
|
||||
mapTilesUpdateDebounce(
|
||||
surface,
|
||||
chunkPos,
|
||||
tiles,
|
||||
event,
|
||||
(data => {
|
||||
if (isEventType(event, defines.events.on_player_mined_tile)) {
|
||||
data.player = event.player_index
|
||||
return
|
||||
}
|
||||
if (isEventType(event, defines.events.on_robot_mined_tile)) {
|
||||
data.robot = {
|
||||
unitNumber: event.robot?.unit_number ?? null,
|
||||
name: event.robot.name,
|
||||
protoType: event.robot.type,
|
||||
}
|
||||
return
|
||||
}
|
||||
// this line will not compile if the previous 'if' statements are not exhaustive
|
||||
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
|
||||
const exhaustiveCheck: never = event
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
script.on_event(
|
||||
defines.events.on_pre_chunk_deleted,
|
||||
(e: OnPreChunkDeletedEvent) => {
|
||||
log(`on_pre_chunk_deleted ${e.tick}`)
|
||||
|
||||
const surface = getSurface(e.surface_index)
|
||||
if (surface == undefined) {
|
||||
return
|
||||
}
|
||||
|
||||
for (const position of e.positions) {
|
||||
const key: CacheKey<KafkatorioPacketData.MapChunkUpdate> = {
|
||||
surfaceIndex: surface.index,
|
||||
chunkPosition: [position.x, position.y],
|
||||
}
|
||||
|
||||
EventUpdatesManager.debounce<KafkatorioPacketData.MapChunkUpdate>(
|
||||
key,
|
||||
Type.MapChunkUpdate,
|
||||
data => data.isDeleted = true,
|
||||
0, // deletion is important - emit ASAP
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
script.on_event(defines.events.on_pre_chunk_deleted, (e: OnPreChunkDeletedEvent) => {
|
||||
log(`on_pre_chunk_deleted ${e.tick}`)
|
||||
MapChunkUpdate.handlePreChunkDeleted(e)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
import {Converters} from "./converters";
|
||||
import EventUpdatesManager from "../cache/EventDataCache";
|
||||
import {
|
||||
KafkatorioPacketData,
|
||||
PlayerUpdateKey
|
||||
} from "../../generated/kafkatorio-schema";
|
||||
import Type = KafkatorioPacketData.Type;
|
||||
import {ForceIndex, KafkatorioPacketData, PlayerUpdateKey} from "../../generated/kafkatorio-schema";
|
||||
import packetEmitter from "../PacketEmitter";
|
||||
import Type = KafkatorioPacketData.Type;
|
||||
|
||||
|
||||
type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void
|
||||
|
|
@ -36,7 +33,7 @@ function playerUpdateThrottle(
|
|||
const eventName = Converters.eventNameString(event.name)
|
||||
|
||||
EventUpdatesManager.throttle<KafkatorioPacketData.PlayerUpdate>(
|
||||
{index: playerIndex},
|
||||
{index: playerIndex },
|
||||
Type.PlayerUpdate,
|
||||
data => {
|
||||
const player = game.players[playerIndex]
|
||||
|
|
@ -88,7 +85,7 @@ script.on_event(
|
|||
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
|
||||
data.forceIndex = player.force.index as ForceIndex
|
||||
data.name = player.name
|
||||
data.isShowOnMap = player.show_on_map
|
||||
data.isSpectator = player.spectator
|
||||
|
|
@ -139,8 +136,7 @@ script.on_event(
|
|||
if (e.cause != undefined) {
|
||||
data.diedCause = {
|
||||
unitNumber: e.cause.unit_number ?? null,
|
||||
name: e.cause.name,
|
||||
protoType: e.cause.type
|
||||
protoId: Converters.prototypeId(e.cause.type, e.cause.name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -189,7 +185,7 @@ script.on_event(
|
|||
log(`on_pre_player_left_game ${event.tick} ${event.name}`)
|
||||
|
||||
const playerUpdateKey: PlayerUpdateKey = {
|
||||
index: event.player_index
|
||||
index: event.player_index ,
|
||||
}
|
||||
|
||||
const playerUpdate: KafkatorioPacketData.PlayerUpdate = {
|
||||
|
|
|
|||
|
|
@ -26,11 +26,11 @@ function prototypeUpdates(): FactorioPrototype[] {
|
|||
|
||||
function getMapTilePrototypes(): FactorioPrototype.MapTile[] {
|
||||
let tiles: FactorioPrototype.MapTile[] = []
|
||||
for (let [, tile] of game.tile_prototypes) {
|
||||
for (const [, tile] of game.tile_prototypes) {
|
||||
tiles.push({
|
||||
type: FactorioPrototype.Type.MapTile,
|
||||
|
||||
name: tile.name,
|
||||
protoId: Converters.prototypeId("tile", tile.name),
|
||||
order: tile.order,
|
||||
layer: tile.layer,
|
||||
collisionMasks: Converters.convertCollisionMaskToNames(tile.collision_mask),
|
||||
|
|
@ -44,7 +44,7 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] {
|
|||
|
||||
// function getEntityPrototypes(): FactorioPrototype.MapTile[] {
|
||||
// let tiles: FactorioPrototype.MapTile[] = []
|
||||
// for (let [, tile] of game.tile_prototypes) {
|
||||
// for (const [, tile] of game.tile_prototypes) {
|
||||
// tiles.push({
|
||||
// type: FactorioPrototype.Type.MapTile,
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {Queue} from "../queue/queue";
|
||||
import {isEventType} from "./eventTypeCheck";
|
||||
import {Converters} from "./converters";
|
||||
import {handleChunkGeneratedEvent} from "./mapChunkUpdates";
|
||||
import {handleSurfaceUpdate} from "./surfaceUpdates";
|
||||
import EventCacheService from "../cache/EventDataCache";
|
||||
import MapChunkUpdate from "./mapChunkUpdates";
|
||||
|
||||
|
||||
script.on_event(
|
||||
|
|
@ -35,7 +35,7 @@ script.on_event(
|
|||
let eName = Converters.eventNameString(event.name)
|
||||
|
||||
log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`)
|
||||
handleChunkGeneratedEvent(event, i)
|
||||
MapChunkUpdate.handleChunkGeneratedEvent(event, i)
|
||||
i += 1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// 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
|
||||
|
|
@ -13,7 +13,7 @@ export function handleSurfaceUpdate(
|
|||
|
||||
name: surface.name,
|
||||
index: surface.index,
|
||||
daytime: surface.daytime
|
||||
daytime: surface.daytime,
|
||||
}
|
||||
|
||||
PacketEmitter.emitInstantPacket(update)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ export class KafkatorioSettingsConfig {
|
|||
|
||||
private static eventCacheExpirationDefaultSeconds: Record<KafkatorioKeyedPacketTypes, double> = {
|
||||
"kafkatorio.packet.keyed.PlayerUpdate": 0.5,
|
||||
"kafkatorio.packet.keyed.MapChunkUpdate": 30,
|
||||
"kafkatorio.packet.keyed.MapChunkTileUpdate": 30,
|
||||
"kafkatorio.packet.keyed.MapChunkEntityUpdate": 30,
|
||||
"kafkatorio.packet.keyed.EntityUpdate": 5,
|
||||
}
|
||||
|
||||
|
|
@ -21,7 +22,7 @@ export class KafkatorioSettingsConfig {
|
|||
public initialiseSettings(data: Data): void {
|
||||
for (const [type,] of pairs(KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds)) {
|
||||
data.extend(
|
||||
[ KafkatorioSettingsConfig.createDefaultCacheDuration(type)]
|
||||
[KafkatorioSettingsConfig.createDefaultCacheDuration(type)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import {KafkatorioPacketData} from "../generated/kafkatorio-schema";
|
||||
|
||||
export type EventName = keyof typeof defines.events
|
||||
export type DefinedEventName = keyof typeof defines.events
|
||||
|
||||
|
||||
/** Get all keys of `TYPE` that are not nullable. */
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
"types": [
|
||||
"typescript-to-lua/language-extensions",
|
||||
"lua-types/5.2",
|
||||
"typed-factorio/runtime"
|
||||
"typed-factorio/runtime",
|
||||
"typed-factorio/strict-index-types"
|
||||
],
|
||||
"plugins": [
|
||||
{
|
||||
|
|
@ -32,8 +33,7 @@
|
|||
"traceResolution": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitOverride": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"skipLibCheck": true
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"tstl": {
|
||||
"luaTarget": "5.2",
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@ package dev.adamko.kafkatorio.server.processor
|
|||
|
||||
import com.github.palindromicity.syslog.dsl.SyslogFieldKeys
|
||||
import dev.adamko.kafkatorio.server.config.ApplicationProperties
|
||||
import dev.adamko.kafkatorio.server.processor.topology.broadcastToWebsocket
|
||||
import dev.adamko.kafkatorio.server.processor.topology.colourMapChunks
|
||||
import dev.adamko.kafkatorio.server.processor.topology.*
|
||||
import dev.adamko.kafkatorio.server.processor.topology.factorioServerPacketStream
|
||||
import dev.adamko.kafkatorio.server.processor.topology.saveMapTiles
|
||||
import dev.adamko.kafkatorio.server.processor.topology.splitFactorioServerPacketStream
|
||||
import dev.adamko.kafkatorio.server.socket.SyslogSocketServer
|
||||
import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer
|
||||
import dev.adamko.kafkatorio.server.web.websocket.broadcastToWebsocket
|
||||
import java.util.Properties
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package dev.adamko.kafkatorio.server.processor.admin
|
||||
|
||||
import dev.adamko.kafkatorio.server.processor.allTopics
|
||||
import dev.adamko.kafkatorio.server.config.ApplicationProperties
|
||||
import dev.adamko.kafkatorio.server.processor.allTopics
|
||||
import java.util.concurrent.TimeUnit
|
||||
import mu.KotlinLogging
|
||||
import org.apache.kafka.clients.admin.Admin
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package dev.adamko.kafkatorio.server.processor
|
||||
|
||||
|
||||
import dev.adamko.kafkatorio.server.socket.SyslogSocketServer
|
||||
import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin
|
||||
import dev.adamko.kafkatorio.server.config.ApplicationProperties
|
||||
import dev.adamko.kafkatorio.server.processor.admin.KafkatorioKafkaAdmin
|
||||
import dev.adamko.kafkatorio.server.socket.SyslogSocketServer
|
||||
import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
|
|
@ -27,11 +27,11 @@ suspend fun eventsProcessor(
|
|||
val topology = KafkatorioTopology(appProps, wsServer, syslogServer)
|
||||
|
||||
|
||||
launch {
|
||||
topology.start()
|
||||
launch {
|
||||
topology.start()
|
||||
|
||||
println("launched KafkatorioTopology")
|
||||
println("launched KafkatorioTopology")
|
||||
|
||||
awaitCancellation()
|
||||
}
|
||||
awaitCancellation()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate
|
|||
import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.EntityUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkEntityUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.PlayerUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate
|
||||
|
|
@ -54,9 +55,10 @@ val KafkatorioPacketData.topicName: String
|
|||
is PrototypesUpdate -> packetTopicNames.getValue(PrototypesUpdate::class)
|
||||
is SurfaceUpdate -> packetTopicNames.getValue(SurfaceUpdate::class)
|
||||
is EntityUpdate -> packetTopicNames.getValue(EntityUpdate::class)
|
||||
is MapChunkUpdate -> packetTopicNames.getValue(MapChunkUpdate::class)
|
||||
is MapChunkTileUpdate -> packetTopicNames.getValue(MapChunkTileUpdate::class)
|
||||
is PlayerUpdate -> packetTopicNames.getValue(PlayerUpdate::class)
|
||||
is KafkatorioPacketData.Error -> packetTopicNames.getValue(KafkatorioPacketData.Error::class)
|
||||
is MapChunkEntityUpdate -> packetTopicNames.getValue(MapChunkEntityUpdate::class)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -67,12 +69,14 @@ private val packetTopicNames: Map<KClass<out KafkatorioPacketData>, String> = ma
|
|||
PrototypesUpdate::class to "prototypes",
|
||||
SurfaceUpdate::class to "surface",
|
||||
EntityUpdate::class to "entity",
|
||||
MapChunkUpdate::class to "map-chunk",
|
||||
MapChunkTileUpdate::class to "map-chunk-tile",
|
||||
PlayerUpdate::class to "player",
|
||||
MapChunkEntityUpdate::class to "map-chunk-entity",
|
||||
KafkatorioPacketData.Error::class to "error",
|
||||
).mapValues { (_, v) ->
|
||||
"$DOMAIN.packet.$v"
|
||||
}
|
||||
|
||||
|
||||
val KClass<out KafkatorioPacketData>.topicName: String
|
||||
get() = packetTopicNames.getValue(this)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
package dev.adamko.kafkatorio.server.processor.topology
|
||||
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_032_STATE
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE
|
||||
import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor
|
||||
import dev.adamko.kafkatorio.library.kxsBinary
|
||||
import dev.adamko.kafkatorio.schema.common.ChunkSize
|
||||
import dev.adamko.kafkatorio.schema.common.ColourHex
|
||||
|
|
@ -10,8 +7,11 @@ import dev.adamko.kafkatorio.schema.common.FactorioServerId
|
|||
import dev.adamko.kafkatorio.schema.common.ServerMapChunkId
|
||||
import dev.adamko.kafkatorio.schema.common.leftTopTile
|
||||
import dev.adamko.kafkatorio.schema.common.toMapChunkPosition
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
|
||||
import dev.adamko.kafkatorio.server.processor.DebounceProcessor.Companion.addDebounceProcessor
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_032_STATE
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE
|
||||
import dev.adamko.kotka.extensions.consumedAs
|
||||
import dev.adamko.kotka.extensions.groupedAs
|
||||
import dev.adamko.kotka.extensions.materializedAs
|
||||
|
|
@ -39,10 +39,10 @@ import org.apache.kafka.streams.kstream.KTable
|
|||
private const val pid: String = "colourMapChunks"
|
||||
|
||||
|
||||
/** Add colour to each [MapChunkUpdate] */
|
||||
/** Add colour to each [MapChunkTileUpdate] */
|
||||
fun colourMapChunks(builder: StreamsBuilder): Topology {
|
||||
|
||||
val mapChunksStream: KStream<FactorioServerId, MapChunkUpdate> = builder.streamPacketData()
|
||||
val mapChunksStream: KStream<FactorioServerId, MapChunkTileUpdate> = builder.streamPacketData()
|
||||
val protosStream: KStream<FactorioServerId, PrototypesUpdate> = builder.streamPacketData()
|
||||
|
||||
val protosTable: KTable<FactorioServerId, TileColourDict> =
|
||||
|
|
@ -78,7 +78,7 @@ fun colourMapChunks(builder: StreamsBuilder): Topology {
|
|||
ChunkSize.CHUNK_032 to ChunkSize.CHUNK_256,
|
||||
ChunkSize.CHUNK_256 to ChunkSize.CHUNK_512,
|
||||
|
||||
).forEach { (from, to) ->
|
||||
).forEach { (from, to) ->
|
||||
chunkTilesColoured
|
||||
.filter("$pid.combine-chunks.filter-$from-to-$to") { key, _ ->
|
||||
key.chunkSize == from
|
||||
|
|
@ -98,12 +98,12 @@ fun colourMapChunks(builder: StreamsBuilder): Topology {
|
|||
}
|
||||
|
||||
|
||||
private fun KStream<FactorioServerId, MapChunkUpdate>.convertToServerMapChunkTiles()
|
||||
private fun KStream<FactorioServerId, MapChunkTileUpdate>.convertToServerMapChunkTiles()
|
||||
: KStream<ServerMapChunkId, ServerMapChunkTiles<TileProtoHashCode>> {
|
||||
|
||||
val pid = "$pid.convertToMapTiles"
|
||||
|
||||
return map("$pid.map") { serverId: FactorioServerId, update: MapChunkUpdate ->
|
||||
return map("$pid.map") { serverId: FactorioServerId, update: MapChunkTileUpdate ->
|
||||
|
||||
val mapTileList = update.tileDictionary?.toMapTileList() ?: emptyList()
|
||||
|
||||
|
|
@ -112,7 +112,7 @@ private fun KStream<FactorioServerId, MapChunkUpdate>.convertToServerMapChunkTil
|
|||
}
|
||||
|
||||
if (invalidMapTilesList.isNotEmpty()) {
|
||||
println("WARNING [reduceMapTilesToTable] MapChunkUpdate contained out-of-bounds tiles $invalidMapTilesList")
|
||||
println("WARNING [reduceMapTilesToTable] MapChunkTileUpdate contained out-of-bounds tiles $invalidMapTilesList")
|
||||
}
|
||||
|
||||
val validMapTilesToProtoHashCode =
|
||||
|
|
@ -232,7 +232,7 @@ fun KTable<ServerMapChunkId, ServerMapChunkTiles<ColourHex>>.streamMapChunkColou
|
|||
|
||||
|
||||
/**
|
||||
* Group [MapChunkUpdate]s by the Chunk position.
|
||||
* Group [MapChunkTileUpdate]s by the Chunk position.
|
||||
*
|
||||
* They should already be grouped, but do it again to make sure, and to filter out empty updates.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package dev.adamko.kafkatorio.server.processor.topology
|
||||
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG
|
||||
import dev.adamko.kafkatorio.server.processor.topicName
|
||||
import dev.adamko.kafkatorio.server.config.jsonMapper
|
||||
import dev.adamko.kafkatorio.schema.common.FactorioServerId
|
||||
import dev.adamko.kafkatorio.schema.common.Tick
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData
|
||||
import dev.adamko.kafkatorio.server.config.jsonMapper
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_SRC_SERVER_LOG
|
||||
import dev.adamko.kafkatorio.server.processor.topicName
|
||||
import dev.adamko.kotka.extensions.component1
|
||||
import dev.adamko.kotka.extensions.component2
|
||||
import dev.adamko.kotka.extensions.consumedAs
|
||||
|
|
@ -35,7 +35,7 @@ fun factorioServerPacketStream(
|
|||
val packet = runCatching {
|
||||
jsonMapper.decodeFromString<KafkatorioPacket>(value)
|
||||
}.getOrElse { e ->
|
||||
KafkatorioPacket(
|
||||
KafkatorioPacket(
|
||||
modVersion = "unknown",
|
||||
tick = Tick(0u),
|
||||
data = KafkatorioPacketData.Error(
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package dev.adamko.kafkatorio.server.processor.topology
|
||||
|
||||
import dev.adamko.kafkatorio.server.processor.topicName
|
||||
import dev.adamko.kafkatorio.server.config.jsonMapper
|
||||
import dev.adamko.kafkatorio.schema.common.FactorioServerId
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData
|
||||
import dev.adamko.kafkatorio.server.config.jsonMapper
|
||||
import dev.adamko.kafkatorio.server.processor.topicName
|
||||
import dev.adamko.kotka.extensions.consumedAs
|
||||
import dev.adamko.kotka.extensions.streams.filter
|
||||
import dev.adamko.kotka.extensions.streams.mapValues
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import org.apache.kafka.streams.kstream.KTable
|
|||
@JvmInline
|
||||
@Serializable
|
||||
value class TileProtoHashCode private constructor(val code: Int) {
|
||||
constructor(tile: MapTile) : this(tile.proto.hashCode())
|
||||
constructor(tile: FactorioPrototype.MapTile) : this(tile.name.hashCode())
|
||||
constructor(tile: MapTile) : this(tile.protoId.hashCode())
|
||||
constructor(tile: FactorioPrototype.MapTile) : this(tile.protoId.hashCode())
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ package dev.adamko.kafkatorio.server.processor.topology
|
|||
import com.sksamuel.scrimage.ImmutableImage
|
||||
import com.sksamuel.scrimage.ScaleMethod
|
||||
import com.sksamuel.scrimage.nio.PngWriter
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE
|
||||
import dev.adamko.kafkatorio.server.config.jsonMapper
|
||||
import dev.adamko.kafkatorio.library.kxsBinary
|
||||
import dev.adamko.kafkatorio.schema.common.ColourHex
|
||||
import dev.adamko.kafkatorio.schema.common.FactorioServerId
|
||||
import dev.adamko.kafkatorio.schema.common.ServerMapChunkId
|
||||
import dev.adamko.kafkatorio.schema.common.TilePngFilename
|
||||
import dev.adamko.kafkatorio.schema.packets.EventServerPacket
|
||||
import dev.adamko.kafkatorio.server.config.jsonMapper
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_MAP_CHUNK_COLOURED_STATE
|
||||
import dev.adamko.kotka.extensions.consumedAs
|
||||
import dev.adamko.kotka.extensions.producedAs
|
||||
import dev.adamko.kotka.extensions.streams.map
|
||||
|
|
@ -32,7 +32,7 @@ private const val WEB_MAP_TILE_SIZE_PX = 256
|
|||
|
||||
|
||||
/**
|
||||
* @param[serverDataDir] [dev.adamko.kafkatorio.processor.config.ApplicationProperties.serverDataDir]
|
||||
* @param[serverDataDir] [dev.adamko.kafkatorio.server.config.ApplicationProperties.serverDataDir]
|
||||
*/
|
||||
fun saveMapTiles(
|
||||
builder: StreamsBuilder,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
package dev.adamko.kafkatorio.server.web.websocket
|
||||
package dev.adamko.kafkatorio.server.processor.topology
|
||||
|
||||
import dev.adamko.kafkatorio.library.jsonMapperKafkatorio
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET
|
||||
import dev.adamko.kafkatorio.server.processor.topicName
|
||||
import dev.adamko.kafkatorio.schema.common.FactorioServerId
|
||||
import dev.adamko.kafkatorio.schema.packets.EventServerPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.PlayerUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate
|
||||
import dev.adamko.kafkatorio.server.processor.TOPIC_BROADCAST_TO_WEBSOCKET
|
||||
import dev.adamko.kafkatorio.server.processor.topicName
|
||||
import dev.adamko.kafkatorio.server.web.websocket.WebmapWebsocketServer
|
||||
import dev.adamko.kotka.extensions.consumedAs
|
||||
import dev.adamko.kotka.extensions.producedAs
|
||||
import dev.adamko.kotka.extensions.stream
|
||||
|
|
|
|||
|
|
@ -59,12 +59,14 @@ class SyslogSocketServer(
|
|||
launch {
|
||||
val channel = socket.openReadChannel()
|
||||
try {
|
||||
while (socket.socketContext.isActive) {
|
||||
while (socket.socketContext.isActive && !channel.isClosedForRead) {
|
||||
val line = runCatching {
|
||||
channel.readUTF8Line()
|
||||
}.fold(
|
||||
onSuccess = { line ->
|
||||
log("received '$line' from $socket")
|
||||
if (line != null) {
|
||||
log("received '$line' from ${socket.description()}")
|
||||
}
|
||||
line
|
||||
},
|
||||
onFailure = { e ->
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ import io.ktor.http.content.EntityTagVersion
|
|||
import io.ktor.http.content.versions
|
||||
import io.ktor.resources.Resource
|
||||
import io.ktor.server.application.ApplicationCall
|
||||
import io.ktor.server.application.application
|
||||
import io.ktor.server.application.call
|
||||
import io.ktor.server.application.log
|
||||
import io.ktor.server.http.content.LastModifiedVersion
|
||||
import io.ktor.server.resources.get
|
||||
import io.ktor.server.response.respond
|
||||
|
|
|
|||
|
|
@ -41,7 +41,9 @@ val deployModToLocalClient by tasks.registering(Copy::class) {
|
|||
description = "Copy the mod to the Factorio client"
|
||||
group = FactorioMod.TASK_GROUP
|
||||
|
||||
onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true }
|
||||
val clientModsDirectory123 = clientModsDirectory
|
||||
|
||||
onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true }
|
||||
|
||||
from(factorioMod)
|
||||
into(clientModsDirectory)
|
||||
|
|
@ -61,9 +63,12 @@ val clientLaunch by tasks.registering(Exec::class) {
|
|||
description = "Run local Factorio Steam game client"
|
||||
group = FactorioMod.TASK_GROUP
|
||||
|
||||
val steamExe123 = steamExe
|
||||
val clientModsDirectory444 = clientModsDirectory
|
||||
|
||||
onlyIf(!serviceOf<ExecOperations>().isFactorioRunning())
|
||||
onlyIf { steamExe.orNull?.asFile?.exists() == true }
|
||||
onlyIf { clientModsDirectory.orNull?.asFile?.exists() == true }
|
||||
onlyIf { steamExe123.orNull?.asFile?.exists() == true }
|
||||
onlyIf { clientModsDirectory444.orNull?.asFile?.exists() == true }
|
||||
|
||||
dependsOn(deployModToLocalClient)
|
||||
mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Do not edit manually. This file was created with task 'dockerEnv'
|
||||
COMPOSE_PROJECT_NAME=kafkatorio
|
||||
FACTORIO_VERSION=1.1.59
|
||||
FACTORIO_VERSION=1.1.61
|
||||
KAFKATORIO_VERSION=0.6.1
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ services:
|
|||
logging:
|
||||
driver: syslog
|
||||
options:
|
||||
syslog-address: "tcp://host.docker.internal:12092"
|
||||
syslog-address: "tcp://host.docker.internal:12034"
|
||||
syslog-format: "rfc5424"
|
||||
|
||||
# environment:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate
|
|||
import dev.adamko.kafkatorio.schema.packets.EntityUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.EventServerPacket
|
||||
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacketData
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.MapChunkTileUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.PlayerUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
|
||||
import dev.adamko.kafkatorio.schema.packets.SurfaceUpdate
|
||||
|
|
@ -84,7 +84,7 @@ class WebsocketService(
|
|||
is PrototypesUpdate,
|
||||
is SurfaceUpdate,
|
||||
is EntityUpdate,
|
||||
is MapChunkUpdate,
|
||||
is MapChunkTileUpdate,
|
||||
is KafkatorioPacketData.Error -> {
|
||||
// to be continued...
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue