fix EntityIdentifiers deserialization bug (kxs has polymorphism problems with interfaces)

This commit is contained in:
Adam 2022-03-14 00:01:51 +01:00
parent 057eee6a68
commit 1fbe0d87b0
4 changed files with 82 additions and 11 deletions

View file

@ -28,7 +28,7 @@ interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey {
characterUnitNumber: uint | null; characterUnitNumber: uint | null;
chatColour: Colour | null; chatColour: Colour | null;
colour: Colour | null; colour: Colour | null;
diedCause: EntityIdentifiers | null; diedCause: EntityIdentifiersData | null;
disconnectReason: string | null; disconnectReason: string | null;
eventCounts: { [key: string]: uint } | null; eventCounts: { [key: string]: uint } | null;
forceIndex: uint | null; forceIndex: uint | null;
@ -55,7 +55,7 @@ interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey {
unitNumber: uint; unitNumber: uint;
} }
interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey { interface EntityUpdate extends FactorioEventUpdate, EntityUpdateKey {
chunkPosition: MapChunkPosition | null; chunkPosition: MapChunkPosition | null;
eventCounts: { [key: string]: uint } | null; eventCounts: { [key: string]: uint } | null;
graphicsVariation: uint8 | null; graphicsVariation: uint8 | null;
@ -83,7 +83,7 @@ interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey {
force: uint | null; force: uint | null;
isDeleted: boolean | null; isDeleted: boolean | null;
player: uint | null; player: uint | null;
robot: EntityIdentifiers | null; robot: EntityIdentifiersData | null;
surfaceIndex: uint; surfaceIndex: uint;
tileDictionary: MapTileDictionary | null; tileDictionary: MapTileDictionary | null;
updateType: FactorioEventUpdateType; updateType: FactorioEventUpdateType;

View file

@ -102,6 +102,16 @@ interface EntityIdentifiers {
} }
// instant of EntityIdentifiers, because kxs needs a concrete instance
@Serializable
data class EntityIdentifiersData(
override val unitNumber: UnitNumber? = null,
override val name: String,
/** The prototype-type of the entity. */
override val type: String,
) : EntityIdentifiers
/** /**
* Size-optimised 2D map of x/y tile positions and prototype-name. * Size-optimised 2D map of x/y tile positions and prototype-name.
* *

View file

@ -113,7 +113,7 @@ data class PlayerUpdate(
val position: MapEntityPosition? = null, val position: MapEntityPosition? = null,
val surfaceIndex: SurfaceIndex? = null, val surfaceIndex: SurfaceIndex? = null,
val tag: String? = null, val tag: String? = null,
val diedCause: EntityIdentifiers? = null, val diedCause: EntityIdentifiersData? = null,
val bannedReason: String? = null, val bannedReason: String? = null,
val kickedReason: String? = null, val kickedReason: String? = null,
@ -154,7 +154,7 @@ data class EntityUpdate(
val localisedDescription: String? = null, val localisedDescription: String? = null,
val localisedName: String? = null, val localisedName: String? = null,
val prototype: PrototypeName? = null, val prototype: PrototypeName? = null,
) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey { ) : FactorioEventUpdate(), EntityUpdateKey {
@EncodeDefault @EncodeDefault
override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY
} }
@ -177,7 +177,7 @@ data class MapChunkUpdate(
override val eventCounts: Map<String, UInt>? = null, override val eventCounts: Map<String, UInt>? = null,
val player: PlayerIndex? = null, val player: PlayerIndex? = null,
val robot: EntityIdentifiers? = null, val robot: EntityIdentifiersData? = null,
val force: ForceIndex? = null, val force: ForceIndex? = null,
/** updated tiles - might be partial and not all tiles in the chunk */ /** updated tiles - might be partial and not all tiles in the chunk */
val tileDictionary: MapTileDictionary? = null, val tileDictionary: MapTileDictionary? = null,

View file

@ -141,9 +141,70 @@ class UpdatePacketsTest : FunSpec({
} }
} }
context("player died") {
// language=JSON
val json = """
{
"tick": 227934,
"modVersion": "0.3.2",
"packetType": "UPDATE",
"update": {
"index": 1,
"updateType": "PLAYER",
"lastOnline": 227932,
"onlineTime": 227888,
"afkTime": 324,
"isConnected": true,
"diedCause": {
"unitNumber": 66,
"name": "small-biter",
"type": "unit"
},
"eventCounts": {
"on_player_died": 2
}
}
}
""".trimIndent()
test("decode") {
val packet: FactorioEventUpdatePacket = jsonMapperKafkatorio.decodeFromString(json)
packet shouldBe FactorioEventUpdatePacket(
modVersion = "0.3.2",
tick = Tick(227934u),
update = PlayerUpdate(
afkTime = Tick(324u),
bannedReason = null,
characterUnitNumber = null,
chatColour = null,
colour = null,
diedCause = EntityIdentifiersData(
unitNumber = UnitNumber(66u),
name = "small-biter",
type = "unit",
),
disconnectReason = null,
eventCounts = mapOf("on_player_died" to 2u),
forceIndex = null,
index = PlayerIndex(1u),
isAdmin = null,
isConnected = true,
isRemoved = null,
isShowOnMap = null,
isSpectator = null,
kickedReason = null,
lastOnline = Tick(227932u),
name = null,
onlineTime = Tick(227888u),
position = null,
surfaceIndex = null,
tag = null,
ticksToRespawn = null,
)
)
}
}
}) })
/*
{"tick":66,"modVersion":"0.3.2","packetType":"UPDATE","update":{"index":1,"updateType":"PLAYER","position":{"y":13.5234375,"x":-58.9375},"eventCounts":{"on_player_changed_position":7,"on_player_joined_game":1},"isAdmin":true,"chatColour":{"red":1,"green":0.62999999523162841796875,"blue":0.259000003337860107421875,"alpha":1},"colour":{"red":0.869000017642974853515625,"green":0.5,"blue":0.12999999523162841796875,"alpha":0.5},"forceIndex":1,"name":"fredthedeadhead","isShowOnMap":true,"isSpectator":false,"tag":"","lastOnline":0,"onlineTime":0,"afkTime":0,"isConnected":true}}
*/