Defense¶
Castle defense setups behind client.defense.
defense.service¶
The defense of your own castles and of castles you could support.
The setters take the keep, wall and moat as get_own_defense returns them,
so a setup can be read, changed and sent back.
Classes:
| Name | Description |
|---|---|
DefenseService |
The defense of your own castles and of castles you could support. |
Attributes:
| Name | Type | Description |
|---|---|---|
logger |
|
DefenseService
¶
Bases: BaseService
The defense of your own castles and of castles you could support.
Reached as client.defense.
Methods:
| Name | Description |
|---|---|
get_own_defense |
Get the keep, wall and moat setup of one of your own castles. |
set_keep |
Set the keep's tools, support tools and unit settings of one of your castles. |
set_wall |
Set the wall's tools and unit split of one of your castles. |
set_moat |
Set the moat's tools of one of your castles. |
get_support_defense_info |
Get the defense of another alliance member's castle, as the client asks before sending support. |
get_own_defense
¶
get_own_defense(castle_x: int, castle_y: int, castle_id: int, kingdom: Kingdom | None = None, timeout: float = 5.0) -> GetDefenseResponse
Get the keep, wall and moat setup of one of your own castles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
castle_x
|
int
|
The castle's map x |
required |
castle_y
|
int
|
The castle's map y |
required |
castle_id
|
int
|
The castle's id: |
required |
kingdom
|
Kingdom | None
|
The castle's kingdom; None sends -1, as the client does |
None
|
timeout
|
float
|
Timeout in seconds |
5.0
|
Returns:
| Type | Description |
|---|---|
GetDefenseResponse
|
The |
Raises:
| Type | Description |
|---|---|
CommandError / EmpireTimeoutError / ConnectionClosedError
|
see |
Client: C2SDefenceCompleteVO (bundle line 32769), sent by
CastleDefenceDialog.updateDefenceData (bundle line 15978)
set_keep
¶
set_keep(castle_x: int, castle_y: int, castle_id: int, keep: KeepDefense, timeout: float = 5.0) -> KeepDefense
Set the keep's tools, support tools and unit settings of one of your castles.
Sends keep.slots, keep.support_tool_slots,
keep.min_attacking_units_for_tools and keep.unit_composition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
castle_x
|
int
|
The castle's map x |
required |
castle_y
|
int
|
The castle's map y |
required |
castle_id
|
int
|
The castle's id, as for |
required |
keep
|
KeepDefense
|
The keep setup, |
required |
timeout
|
float
|
Timeout in seconds |
5.0
|
Returns:
| Type | Description |
|---|---|
KeepDefense
|
The |
Raises:
| Type | Description |
|---|---|
CommandError / EmpireTimeoutError / ConnectionClosedError
|
see |
Client: C2SDefenceKeepVO (bundle line 66597), sent by
CastleDefenceDialog.sendKeepData (bundle line 16041); DFKCommand
(bundle line 123495)
set_wall
¶
set_wall(castle_x: int, castle_y: int, castle_id: int, wall: WallDefense, timeout: float = 5.0) -> WallDefense
Set the wall's tools and unit split of one of your castles.
Sends each section's slots, unit_percent (a whole percent, as
the client rounds its slider) and unit_composition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
castle_x
|
int
|
The castle's map x |
required |
castle_y
|
int
|
The castle's map y |
required |
castle_id
|
int
|
The castle's id, as for |
required |
wall
|
WallDefense
|
The wall setup, |
required |
timeout
|
float
|
Timeout in seconds |
5.0
|
Returns:
| Type | Description |
|---|---|
WallDefense
|
The |
Raises:
| Type | Description |
|---|---|
CommandError / EmpireTimeoutError / ConnectionClosedError
|
see |
Client: C2SDefenceWallVO (bundle line 66616), sent by
CastleDefenceDialog.sendWallData (bundle line 16045) with
calcUnitPercentArray (bundle line 15985); DFWCommand (bundle line 123525)
set_moat
¶
set_moat(castle_x: int, castle_y: int, castle_id: int, moat: MoatDefense, timeout: float = 5.0) -> MoatDefense
Set the moat's tools of one of your castles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
castle_x
|
int
|
The castle's map x |
required |
castle_y
|
int
|
The castle's map y |
required |
castle_id
|
int
|
The castle's id, as for |
required |
moat
|
MoatDefense
|
The moat setup, |
required |
timeout
|
float
|
Timeout in seconds |
5.0
|
Returns:
| Type | Description |
|---|---|
MoatDefense
|
The |
Raises:
| Type | Description |
|---|---|
CommandError / EmpireTimeoutError / ConnectionClosedError
|
see |
Client: C2SDefenceMoatVO (bundle line 66607), sent by
CastleDefenceDialog.sendMoatData (bundle line 16049); DFMCommand
(bundle line 123510)
get_support_defense_info
¶
get_support_defense_info(target_x: int, target_y: int, source_x: int | None = None, source_y: int | None = None, timeout: float = 5.0) -> GetSupportDefenseResponse
Get the defense of another alliance member's castle, as the client asks before sending support.
The server rejects your own castle with NO_SELF_DESTRUCTION (92); use
get_own_defense for that.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_x
|
int
|
Map x of the castle to support |
required |
target_y
|
int
|
Map y of the castle to support |
required |
source_x
|
int | None
|
Map x of your castle the support would leave from (defaults to your first castle) |
None
|
source_y
|
int | None
|
Map y of your castle the support would leave from (defaults to your first castle) |
None
|
timeout
|
float
|
Timeout in seconds |
5.0
|
Returns:
| Type | Description |
|---|---|
GetSupportDefenseResponse
|
GetSupportDefenseResponse with defense info: |
GetSupportDefenseResponse
|
counts every defender. |
Raises:
| Type | Description |
|---|---|
ValueError
|
No source coordinates given and no own castle known |
CommandError / EmpireTimeoutError / ConnectionClosedError
|
see |
Client: C2SSupportDefenceInfoVO (bundle line 72078), sent by
CastleStartAttackDialog.supportDefence (bundle line 14833)
defense.models¶
Defense protocol models.
Commands:
- dfc: Read a castle's keep, wall and moat setup
- dfk: Set the keep's tools and unit settings
- dfw: Set the wall's tools and unit split
- dfm: Set the moat's tools
- sdi: Defense of a castle you could send support to
Classes:
| Name | Description |
|---|---|
GetDefenseRequest |
Read the defense setup of one of your castles. |
WallSection |
One wall section's setup as the |
WallDefense |
The wall setup: the |
KeepDefense |
The keep setup: the |
MoatDefense |
The moat setup: the |
GetDefenseResponse |
A castle's whole defense setup. |
ChangeKeepDefenseRequest |
Set the keep's tools, support tools and unit settings. |
WallSectionSetup |
One wall section in a |
ChangeWallDefenseRequest |
Set the wall's tools and unit split per section. |
ChangeMoatDefenseRequest |
Set the moat's tools. |
GetSupportDefenseRequest |
Get the defense of a castle you could send support to, before sending it. |
GetSupportDefenseResponse |
Defense information for an alliance member's castle. |
GetDefenseRequest
pydantic-model
¶
Bases: BaseRequest
Read the defense setup of one of your castles.
Command: dfc Payload: {"CX": castle_x, "CY": castle_y, "AID": area_id, "KID": kingdom}
KID is -1 unless a kingdom is given: the VO defaults it to -1, and
every call site passes -1 or leaves it out.
Client: C2SDefenceCompleteVO (bundle line 32769); every call site
passes the castle's absAreaPos and objectId, with KID -1 or
omitted (CastleDefenceDialog.updateDefenceData, bundle line 15978)
Fields:
Validators:
-
_no_kingdom→kingdom_id
WallSection
pydantic-model
¶
Bases: BasePayload
One wall section's setup as the dfw reply carries it; a missing
number reads as 0, as the client's int() gives.
Client: CastleDefenceData.parse_DFW (bundle line 134250)
Fields:
-
slots(WodAmountSlots) -
unit_percent(ClientInt) -
unit_composition(ClientInt)
WallDefense
pydantic-model
¶
Bases: BaseResponse
The wall setup: the dfw reply, also nested in dfc.
Command: dfw
Client: DFWCommand.executeCommand (bundle line 123525),
CastleDefenceData.parse_DFW (bundle line 134250)
Fields:
-
error_code(int) -
left(WallSection) -
middle(WallSection) -
right(WallSection) -
unit_count(ClientInt) -
unit_slot_count(ClientInt) -
defense(ClientInt)
KeepDefense
pydantic-model
¶
Bases: BaseResponse
The keep setup: the dfk reply, also nested in dfc.
Command: dfk
Client: DFKCommand.executeCommand (bundle line 123495),
CastleDefenceData.parse_DFK (bundle line 134251)
Fields:
-
error_code(int) -
slots(WodAmountSlots) -
support_tool_slots(WodAmountSlots) -
alliance_unit_yard_limit(ClientInt) -
unit_yard_limit(ClientInt) -
unit_count(ClientInt) -
unit_composition(ClientInt) -
min_attacking_units_for_tools(ClientInt)
support_tool_slots
pydantic-field
¶
Wire key STS
Keep support-tool slots
alliance_unit_yard_limit
pydantic-field
¶
alliance_unit_yard_limit: ClientInt = 0
Wire key AUYL
Alliance unit yard limit
MoatDefense
pydantic-model
¶
Bases: BaseResponse
The moat setup: the dfm reply, also nested in dfc.
Command: dfm
Client: DFMCommand.executeCommand (bundle line 123510),
CastleDefenceData.parse_DFM (bundle line 134252)
Fields:
-
error_code(int) -
left_slots(WodAmountSlots) -
middle_slots(WodAmountSlots) -
right_slots(WodAmountSlots) -
defense(ClientInt)
GetDefenseResponse
pydantic-model
¶
Bases: BaseResponse
A castle's whole defense setup.
Command: dfc
Client: DFCCommand.executeCommand (bundle line 123480),
CastleDefenceData.parse_DFC (bundle line 134243). The server also
sends MDS and RDS, which the client does not read.
Fields:
-
error_code(int) -
unit_inventory(UnitInventory) -
area(MovementArea | None) -
home_defense_workshop_level(int | None) -
wall(WallDefense | None) -
keep(KeepDefense | None) -
moat(MoatDefense | None) -
range_priority(tuple[EnumOrInt['Unit'], ...]) -
melee_priority(tuple[EnumOrInt['Unit'], ...]) -
gate_defense(ClientInt) -
castellan(Castellan | None) -
listed_castellan_id(ClientInt)
Validators:
-
_castellan_id_from_l -
_castellan_or_none→castellan
unit_inventory
pydantic-field
¶
unit_inventory: UnitInventory
Wire key gui
The castle's unit inventory
home_defense_workshop_level
pydantic-field
¶
home_defense_workshop_level: int | None = None
Wire key HDWL
Defense workshop level, which unlocks the keep's support-tool slots
range_priority
pydantic-field
¶
Wire key PR
The ranged units in the order the castle places them on the wall
melee_priority
pydantic-field
¶
Wire key PM
The melee units in the order the castle places them on the wall
gate_defense
pydantic-field
¶
gate_defense: ClientInt = 0
Wire key GD
Gate defence, as a whole number
castellan
pydantic-field
¶
castellan: Castellan | None = None
Wire key L
The castle's castellan; None when there is none
listed_castellan_id
pydantic-field
¶
listed_castellan_id: ClientInt = -1
The listed castellan's id; -1 when none is listed
ChangeKeepDefenseRequest
pydantic-model
¶
Bases: BaseRequest
Set the keep's tools, support tools and unit settings.
The client builds the slot lists from its keep containers, one pair per
slot; start from the dfc reply's dfk lists. Fields follow the
client's key order.
Command: dfk
Client: C2SDefenceKeepVO (bundle line 66597), built by
CastleDefenceDialog.sendKeepData (bundle line 16041), which sends an
empty STS when there is no support-tool container
Fields:
-
castle_x(int) -
castle_y(int) -
area_id(int) -
min_attacking_units_for_tools(int) -
unit_composition(int) -
slots(WodAmountSlots) -
support_tool_slots(WodAmountSlots)
area_id
pydantic-field
¶
area_id: int
Wire key AID
The castle's id: CastleInfo.castle_id from client.castle.get_all() or Castle.id
min_attacking_units_for_tools
pydantic-field
¶
min_attacking_units_for_tools: int = 0
Wire key MAUCT
Minimum attacking units before the keep's tools are used
support_tool_slots
pydantic-field
¶
Wire key STS
Keep support-tool slots
WallSectionSetup
pydantic-model
¶
Bases: BasePayload
One wall section in a dfw request; the client has no defaults.
Client: C2SDefenceWallVO (bundle line 66616)
Fields:
-
slots(WodAmountSlots) -
unit_percent(int) -
unit_composition(int)
ChangeWallDefenseRequest
pydantic-model
¶
Bases: BaseRequest
Set the wall's tools and unit split per section.
Every section needs its slots, unit percent and unit composition; the
client has no defaults for them. Start from the dfc reply's dfw.
Command: dfw
Client: C2SDefenceWallVO (bundle line 66616), built by
CastleDefenceDialog.sendWallData (bundle line 16045)
Fields:
ChangeMoatDefenseRequest
pydantic-model
¶
Bases: BaseRequest
Set the moat's tools.
Start from the dfc reply's dfm lists.
Command: dfm
Client: C2SDefenceMoatVO (bundle line 66607), built by
CastleDefenceDialog.sendMoatData (bundle line 16049)
Fields:
-
castle_x(int) -
castle_y(int) -
area_id(int) -
left_slots(WodAmountSlots) -
middle_slots(WodAmountSlots) -
right_slots(WodAmountSlots)
GetSupportDefenseRequest
pydantic-model
¶
Bases: BaseRequest
Get the defense of a castle you could send support to, before sending it.
Command: sdi Payload: {"TX": target_x, "TY": target_y, "SX": source_x, "SY": source_y}
The client sends it from the Support button, which it shows for a castle
of another member of your alliance (and a few other areas, such as your
own outposts), never for your own castle; the server answers your own
castle with NO_SELF_DESTRUCTION (92). Read your own castle with dfc.
Client: C2SSupportDefenceInfoVO (bundle line 72078), sent by
CastleStartAttackDialog.supportDefence (bundle line 14833);
CastleMapobjectVO.canBeSupported (bundle line 18918),
OutpostMapobjectVO.canBeSupported (bundle line 18820)
Fields:
GetSupportDefenseResponse
pydantic-model
¶
Bases: BaseResponse
Defense information for an alliance member's castle.
Command: sdi Payload:
{"SCID": source_castle_id,
"S": [left, middle, right, keep, stronghold, support, reserve],
"AS": spy_age_seconds, "B": {castellan}, "abe": {castellan}, "LS": [...],
"gaa": {"AI": [...], "OI": [...]},
"gui": {"I": [[wod_id, count], ...], "SHI": [...]},
"gli": {"C": [...], "B": [...]},
"UYL": yard_limit, "AUYL": alliance_yard_limit, "UWL": wall_limit}
The client reads S, AS, the castellan and LS into the same
CastleSpyArmyInfoVO a spy report and an attack pre-calculation use. It
takes the castellan from abe when the target is an alliance
battleground tower and from B otherwise.
Client: SDICommand.executeCommand (bundle line 122352), which passes
gli to CastleLordData.parse_GLI;
CastleSupportDefenceVO.fillFromParamObject (bundle line 140066);
CastleSpyArmyInfoVO.parseArmyInfo (bundle line 30699).
Fields:
-
error_code(int) -
castle_id(int) -
defense_positions(SpyArmyBlock) -
castellan(Castellan | None) -
tower_castellan(Castellan | None) -
unit_inventory(UnitInventory) -
commander_roster(CommanderRoster) -
yard_limit(int) -
available_yard_limit(int) -
wall_limit(int)
Validators:
-
_castellan_or_none→castellan,tower_castellan
defense_positions
pydantic-field
¶
defense_positions: SpyArmyBlock = None
Wire key S
The castle's defenders by the position they hold; None when the reply lists none
castellan
pydantic-field
¶
castellan: Castellan | None = None
Wire key B
The castle's castellan, without its equipment; None when there is none
tower_castellan
pydantic-field
¶
tower_castellan: Castellan | None = None
Wire key abe
The castellan of an alliance battleground tower, in place of castellan
unit_inventory
pydantic-field
¶
unit_inventory: UnitInventory
Wire key gui
Your own units and tools, and your stronghold units
commander_roster
pydantic-field
¶
commander_roster: CommanderRoster
Wire key gli
Your commanders and castellans
yard_limit
pydantic-field
¶
yard_limit: int = 0
Wire key UYL
Courtyard unit limit, the alliance share (available_yard_limit) included