2026-02-17 16:37:36 +01:00
|
|
|
from __future__ import annotations
|
|
|
|
|
from typing import Dict, Any, TypeVar, Type, cast
|
2026-02-11 19:22:43 +01:00
|
|
|
from datetime import datetime
|
|
|
|
|
from uuid import uuid4
|
|
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
T = TypeVar("T", bound="WarEvent")
|
|
|
|
|
EVENT_REGISTRY: Dict[str, Type["WarEvent"]] = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def register_event(cls: Type[T]) -> Type[T]:
|
|
|
|
|
EVENT_REGISTRY[cls.TYPE] = cls
|
|
|
|
|
return cls
|
|
|
|
|
|
2026-02-11 19:22:43 +01:00
|
|
|
|
|
|
|
|
class WarEvent:
|
2026-02-17 16:37:36 +01:00
|
|
|
TYPE = "WarEvent"
|
|
|
|
|
|
2026-02-20 23:44:22 +01:00
|
|
|
def __init__(self, participant_id: str | None, context_type: str, context_id: str):
|
2026-02-11 19:22:43 +01:00
|
|
|
self.id: str = str(uuid4())
|
2026-02-17 16:37:36 +01:00
|
|
|
self.participant_id: str | None = participant_id
|
2026-02-20 23:44:22 +01:00
|
|
|
self.context_type = context_type # battle, round, campaign, war
|
|
|
|
|
self.context_id = context_id
|
2026-02-11 19:22:43 +01:00
|
|
|
self.timestamp: datetime = datetime.now()
|
|
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
def set_id(self, new_id: str) -> None:
|
|
|
|
|
self.id = new_id
|
|
|
|
|
|
|
|
|
|
def set_participant(self, new_war_part_id: str | None) -> None:
|
|
|
|
|
self.participant_id = new_war_part_id
|
|
|
|
|
|
|
|
|
|
def set_timestamp(self, new_timestamp: datetime) -> None:
|
|
|
|
|
self.timestamp = new_timestamp
|
|
|
|
|
|
|
|
|
|
def toDict(self) -> Dict[str, Any]:
|
|
|
|
|
return {
|
|
|
|
|
"type": self.TYPE,
|
|
|
|
|
"id": self.id,
|
|
|
|
|
"participant_id": self.participant_id,
|
2026-02-20 23:44:22 +01:00
|
|
|
"context_type": self.context_type,
|
|
|
|
|
"context_id": self.context_id,
|
2026-02-17 16:37:36 +01:00
|
|
|
"timestamp": self.timestamp.isoformat(),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def _base_fromDict(cls: Type[T], ev: T, data: Dict[str, Any]) -> T:
|
|
|
|
|
ev.id = data["id"]
|
|
|
|
|
ev.participant_id = data["participant_id"]
|
2026-02-20 23:44:22 +01:00
|
|
|
ev.context_type = data["context_type"]
|
|
|
|
|
ev.context_id = data["context_id"]
|
2026-02-17 16:37:36 +01:00
|
|
|
ev.timestamp = datetime.fromisoformat(data["timestamp"])
|
|
|
|
|
return ev
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def fromDict(data: Dict[str, Any]) -> "WarEvent":
|
|
|
|
|
ev_type = data["type"]
|
|
|
|
|
cls = cast(Type[WarEvent], EVENT_REGISTRY.get(ev_type))
|
|
|
|
|
if cls is None:
|
|
|
|
|
raise ValueError(f"Unknown event type: {ev_type}")
|
|
|
|
|
return cls.fromDict(data)
|
|
|
|
|
|
2026-02-11 19:22:43 +01:00
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
@register_event
|
2026-02-11 19:22:43 +01:00
|
|
|
class TieResolved(WarEvent):
|
2026-02-17 16:37:36 +01:00
|
|
|
TYPE = "TieResolved"
|
|
|
|
|
|
2026-02-25 16:54:21 +01:00
|
|
|
def __init__(
|
|
|
|
|
self,
|
|
|
|
|
participant_id: str | None,
|
|
|
|
|
context_type: str,
|
|
|
|
|
context_id: str,
|
|
|
|
|
score_value: int | None = None,
|
|
|
|
|
):
|
2026-02-20 23:44:22 +01:00
|
|
|
super().__init__(participant_id, context_type, context_id)
|
2026-02-25 16:54:21 +01:00
|
|
|
self.score_value = score_value
|
2026-02-11 19:22:43 +01:00
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
def toDict(self) -> Dict[str, Any]:
|
|
|
|
|
d = super().toDict()
|
2026-02-25 16:54:21 +01:00
|
|
|
d.update(
|
|
|
|
|
{
|
|
|
|
|
"score_value": self.score_value or None,
|
|
|
|
|
}
|
|
|
|
|
)
|
2026-02-17 16:37:36 +01:00
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def fromDict(cls, data: Dict[str, Any]) -> TieResolved:
|
|
|
|
|
ev = cls(
|
2026-02-25 16:54:21 +01:00
|
|
|
data["participant_id"] or None,
|
2026-02-17 16:37:36 +01:00
|
|
|
data["context_type"],
|
|
|
|
|
data["context_id"],
|
2026-02-25 16:54:21 +01:00
|
|
|
data["score_value"] or None,
|
2026-02-17 16:37:36 +01:00
|
|
|
)
|
|
|
|
|
return cls._base_fromDict(ev, data)
|
|
|
|
|
|
2026-02-11 19:22:43 +01:00
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
@register_event
|
2026-02-11 19:22:43 +01:00
|
|
|
class InfluenceGained(WarEvent):
|
2026-02-17 16:37:36 +01:00
|
|
|
TYPE = "InfluenceGained"
|
|
|
|
|
|
2026-02-20 23:44:22 +01:00
|
|
|
def __init__(
|
|
|
|
|
self, participant_id: str, amount: int, context_type: str, context_id: str
|
|
|
|
|
):
|
|
|
|
|
super().__init__(participant_id, context_type, context_id)
|
2026-02-11 19:22:43 +01:00
|
|
|
self.amount = amount
|
|
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
def toDict(self) -> Dict[str, Any]:
|
|
|
|
|
d = super().toDict()
|
|
|
|
|
d.update(
|
|
|
|
|
{
|
|
|
|
|
"amount": self.amount,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def fromDict(cls, data: Dict[str, Any]) -> InfluenceGained:
|
|
|
|
|
ev = cls(
|
|
|
|
|
data["participant_id"],
|
2026-02-20 23:44:22 +01:00
|
|
|
int(data["amount"]),
|
|
|
|
|
data["context_type"],
|
|
|
|
|
data["context_id"],
|
2026-02-17 16:37:36 +01:00
|
|
|
)
|
|
|
|
|
return cls._base_fromDict(ev, data)
|
2026-02-11 19:22:43 +01:00
|
|
|
|
2026-02-17 16:37:36 +01:00
|
|
|
|
|
|
|
|
@register_event
|
2026-02-11 19:22:43 +01:00
|
|
|
class InfluenceSpent(WarEvent):
|
2026-02-17 16:37:36 +01:00
|
|
|
TYPE = "InfluenceSpent"
|
|
|
|
|
|
2026-02-20 23:44:22 +01:00
|
|
|
def __init__(
|
|
|
|
|
self, participant_id: str, amount: int, context_type: str, context_id: str
|
|
|
|
|
):
|
|
|
|
|
super().__init__(participant_id, context_type, context_id)
|
2026-02-11 19:22:43 +01:00
|
|
|
self.amount = amount
|
2026-02-17 16:37:36 +01:00
|
|
|
|
|
|
|
|
def toDict(self) -> Dict[str, Any]:
|
|
|
|
|
d = super().toDict()
|
|
|
|
|
d.update(
|
|
|
|
|
{
|
|
|
|
|
"amount": self.amount,
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def fromDict(cls, data: Dict[str, Any]) -> InfluenceSpent:
|
|
|
|
|
ev = cls(
|
|
|
|
|
data["participant_id"],
|
2026-02-20 23:44:22 +01:00
|
|
|
int(data["amount"]),
|
2026-02-17 16:37:36 +01:00
|
|
|
data["context_type"],
|
2026-02-20 23:44:22 +01:00
|
|
|
data["context_id"],
|
2026-02-17 16:37:36 +01:00
|
|
|
)
|
|
|
|
|
return cls._base_fromDict(ev, data)
|