diff --git a/app/core/nice/common_release.py b/app/core/nice/common_release.py index ea049ac7..55a2be36 100644 --- a/app/core/nice/common_release.py +++ b/app/core/nice/common_release.py @@ -17,6 +17,20 @@ def get_nice_common_release(release: MstCommonRelease) -> NiceCommonRelease: ) +def get_sorted_common_releases( + raw_releases: list[MstCommonRelease], release_id: int | None = None +) -> list[NiceCommonRelease]: + sorted_raw_releases = sorted( + raw_releases, + key=lambda release: (release.priority, release.condType, release.condNum), + ) + return [ + get_nice_common_release(release) + for release in sorted_raw_releases + if release_id is None or release.id == release_id + ] + + async def get_nice_common_releases_from_id( conn: AsyncConnection, common_release_id: int ) -> list[NiceCommonRelease]: diff --git a/app/core/nice/event/event.py b/app/core/nice/event/event.py index 52feed62..0214afec 100644 --- a/app/core/nice/event/event.py +++ b/app/core/nice/event/event.py @@ -34,6 +34,7 @@ from .command_assist import get_nice_command_assist from .cooltime import get_nice_event_cooltime from .digging import get_nice_digging +from .event_svt import get_nice_event_svt from .fortification import get_nice_fortification from .heel_portrait import get_nice_heel_portrait from .lottery import get_nice_lottery @@ -237,6 +238,10 @@ async def get_nice_event( eventAdds=[ get_nice_event_add(region, event_add) for event_add in raw_event.mstEventAdd ], + svts=[ + get_nice_event_svt(event_svt, raw_event.mstCommonRelease) + for event_svt in raw_event.mstEventSvt + ], shop=[ get_nice_shop( region, diff --git a/app/core/nice/event/event_svt.py b/app/core/nice/event/event_svt.py new file mode 100644 index 00000000..845d4218 --- /dev/null +++ b/app/core/nice/event/event_svt.py @@ -0,0 +1,54 @@ +from typing import Any + +from ....schemas.gameenums import EVENT_SVT_TYPE_NAME +from ....schemas.nice import NiceEventSvt, NiceEventSvtScript +from ....schemas.raw import MstCommonRelease, MstEventSvt +from ..common_release import get_sorted_common_releases + + +def get_nice_event_svt_script( + script: dict[str, Any], raw_releases: list[MstCommonRelease] +) -> NiceEventSvtScript: + out: dict[str, Any] = {} + + for unchanged_key in ( + "addGetMessage", + "joinQuestId", + "joinShopId", + "notPresentRarePri", + "ruby", + ): + if unchanged_key in script: + out[unchanged_key] = script[unchanged_key] + + for bool_key in ("isProtectedDuringEvent", "notPresentAnonymous"): + if bool_key in script: + out[bool_key] = script[bool_key] == 1 + + if "addMessageCommonReleaseId" in script: + out["addMessageReleaseConditions"] = get_sorted_common_releases( + raw_releases, script["addMessageCommonReleaseId"] + ) + + return NiceEventSvtScript.parse_obj(out) + + +def get_nice_event_svt( + event_svt: MstEventSvt, raw_releases: list[MstCommonRelease] +) -> NiceEventSvt: + return NiceEventSvt( + svtId=event_svt.svtId, + script=get_nice_event_svt_script(event_svt.script, raw_releases), + originalScript=event_svt.script, + type=EVENT_SVT_TYPE_NAME[event_svt.type], + joinMessage=event_svt.joinMessage, + getMessage=event_svt.getMessage, + leaveMessage=event_svt.leaveMessage, + name=event_svt.name, + battleName=event_svt.battleName, + releaseConditions=get_sorted_common_releases( + raw_releases, event_svt.commonReleaseId + ), + startedAt=event_svt.startedAt, + endedAt=event_svt.endedAt, + ) diff --git a/app/core/raw.py b/app/core/raw.py index 3678260d..0e8222e3 100644 --- a/app/core/raw.py +++ b/app/core/raw.py @@ -111,6 +111,7 @@ MstEventReward, MstEventRewardScene, MstEventRewardSet, + MstEventSvt, MstEventTower, MstEventVoicePlay, MstFriendship, @@ -1072,11 +1073,19 @@ async def get_event_entity(conn: AsyncConnection, event_id: int) -> EventEntity: }, ) + event_svts = await fetch.get_all(conn, MstEventSvt, event_id) + event_svt_release_ids = {svt.commonReleaseId for svt in event_svts} | { + svt.script["addMessageCommonReleaseId"] + for svt in event_svts + if "addMessageCommonReleaseId" in svt.script + } + common_release_ids = ( cooltime_release_ids | recipe_release_ids | fortification_release_ids | command_assist_release_ids + | event_svt_release_ids ) common_releases = await fetch.get_all_multiple( conn, MstCommonRelease, common_release_ids @@ -1183,6 +1192,7 @@ async def get_event_entity(conn: AsyncConnection, event_id: int) -> EventEntity: mstEventPointActivity=await fetch.get_all( conn, MstEventPointActivity, event_id ), + mstEventSvt=event_svts, mstWarBoard=warboards, mstWarBoardStage=warboard_stages, mstWarBoardQuest=warboard_quests, diff --git a/app/db/helpers/fetch.py b/app/db/helpers/fetch.py index 69e57fc9..128f73bd 100644 --- a/app/db/helpers/fetch.py +++ b/app/db/helpers/fetch.py @@ -68,6 +68,7 @@ mstEventReward, mstEventRewardScene, mstEventRewardSet, + mstEventSvt, mstEventTower, mstEventVoicePlay, mstFriendship, @@ -188,6 +189,7 @@ MstEventReward, MstEventRewardScene, MstEventRewardSet, + MstEventSvt, MstEventTower, MstEventVoicePlay, MstFriendship, @@ -532,6 +534,11 @@ async def get_one( mstSvtOverwrite.c.svtId, mstSvtOverwrite.c.priority, ), + MstEventSvt: ( + mstEventSvt, + mstEventSvt.c.eventId, + mstEventSvt.c.svtId, + ), } TFetchAll = TypeVar("TFetchAll", bound=BaseModelORJson) diff --git a/app/models/raw.py b/app/models/raw.py index 092b20d6..8baa38a3 100644 --- a/app/models/raw.py +++ b/app/models/raw.py @@ -1765,6 +1765,24 @@ ) +mstEventSvt = Table( + "mstEventSvt", + metadata, + Column("script", JSONB), + Column("eventId", Integer), + Column("svtId", Integer), + Column("type", Integer), + Column("joinMessage", String), + Column("getMessage", String), + Column("leaveMessage", String), + Column("name", String), + Column("battleName", String), + Column("commonReleaseId", Integer), + Column("startedAt", Integer), + Column("endedAt", Integer), +) + + mstWarBoard = Table( "mstWarBoard", metadata, @@ -2646,6 +2664,7 @@ [mstEventBulletinBoard, mstEventBulletinBoardRelease], [mstEventRecipe, mstEventRecipeGift], [mstEventFortification, mstEventFortificationDetail, mstEventFortificationSvt], + [mstEventSvt], [mstVoice], [mstVoicePlayCond], [mstSvt], diff --git a/app/schemas/gameenums.py b/app/schemas/gameenums.py index 323e0341..83a913c5 100644 --- a/app/schemas/gameenums.py +++ b/app/schemas/gameenums.py @@ -5406,3 +5406,27 @@ class NiceGachaFlag(StrEnum): 2: NiceGachaFlag.pcMessage, 8: NiceGachaFlag.bonusSelect, } + + +class EventSvtType(IntEnum): + NONE = 0 + JOIN = 1 + COND_JOIN = 2 + DIRECT_JOIN = 3 + + +class NiceEventSvtType(StrEnum): + """Event Svt Type""" + + none = "none" + join_ = "join" + condJoin = "condJoin" + directJoin = "directJoin" + + +EVENT_SVT_TYPE_NAME: dict[int, NiceEventSvtType] = { + 0: NiceEventSvtType.none, + 1: NiceEventSvtType.join_, + 2: NiceEventSvtType.condJoin, + 3: NiceEventSvtType.directJoin, +} diff --git a/app/schemas/nice.py b/app/schemas/nice.py index a1908511..64e1c912 100644 --- a/app/schemas/nice.py +++ b/app/schemas/nice.py @@ -59,6 +59,7 @@ NiceEventFortificationSvtType, NiceEventOverwriteType, NiceEventRewardSceneFlag, + NiceEventSvtType, NiceEventType, NiceEventWorkType, NiceFrequencyType, @@ -2037,6 +2038,32 @@ class NiceEventAdd(BaseModelORJson): endedAt: int +class NiceEventSvtScript(BaseModelORJson): + addGetMessage: str | None = None + addMessageReleaseConditions: list[NiceCommonRelease] | None = None + isProtectedDuringEvent: bool | None = None + joinQuestId: int | None = None + joinShopId: int | None = None + notPresentAnonymous: bool | None = None + notPresentRarePri: int | None = None + ruby: str | None = None + + +class NiceEventSvt(BaseModelORJson): + svtId: int + script: NiceEventSvtScript + originalScript: dict[str, Any] + type: NiceEventSvtType + joinMessage: str + getMessage: str + leaveMessage: str + name: str + battleName: str + releaseConditions: list[NiceCommonRelease] + startedAt: int + endedAt: int + + class NiceWarBoardTreasure(BaseModelORJson): warBoardTreasureId: int rarity: NiceWarBoardTreasureRarity @@ -2082,6 +2109,7 @@ class NiceEvent(BaseModelORJson): materialOpenedAt: int warIds: list[int] eventAdds: list[NiceEventAdd] + svts: list[NiceEventSvt] shop: list[NiceShop] rewards: list[NiceEventReward] rewardScenes: list[NiceEventRewardScene] diff --git a/app/schemas/raw.py b/app/schemas/raw.py index 44d2ca67..e90fdd31 100644 --- a/app/schemas/raw.py +++ b/app/schemas/raw.py @@ -1475,6 +1475,21 @@ class MstEventAdd(BaseModelORJson): endedAt: int +class MstEventSvt(BaseModelORJson): + script: dict[str, Any] + eventId: int + svtId: int + type: int + joinMessage: str + getMessage: str + leaveMessage: str + name: str + battleName: str + commonReleaseId: int + startedAt: int + endedAt: int + + class MstWarBoard(BaseModelORJson): id: int backGroundId: int @@ -2198,6 +2213,7 @@ class EventEntity(BaseModelORJson): mstHeelPortrait: list[MstHeelPortrait] mstEventMural: list[MstEventMural] mstEventPointActivity: list[MstEventPointActivity] + mstEventSvt: list[MstEventSvt] mstWarBoard: list[MstWarBoard] mstWarBoardStage: list[MstWarBoardStage] mstWarBoardQuest: list[MstWarBoardQuest] diff --git a/scripts/enum.ts b/scripts/enum.ts index 41404bb3..16262737 100644 --- a/scripts/enum.ts +++ b/scripts/enum.ts @@ -1833,3 +1833,10 @@ export enum NiceGachaFlag { PC_MESSAGE = "pcMessage", BONUS_SELECT = "bonusSelect", } + +export enum NiceEventSvtType { + NONE = "none", + JOIN = "join", + COND_JOIN = "condJoin", + DIRECT_JOIN = "directJoin", +} diff --git a/scripts/extract_enums.py b/scripts/extract_enums.py index 54c79b66..372d8c36 100644 --- a/scripts/extract_enums.py +++ b/scripts/extract_enums.py @@ -10,6 +10,7 @@ "CENTER": "center_", "SET": "set_", "NAME": "name_", + "JOIN": "join_", } @@ -602,6 +603,13 @@ def cs_enum_to_ts(cs_enums: list[str], raw_class: str, nice_class: str) -> list[ "Gacha Flag", "GACHA_FLAG_NAME", ), + ( + "EventServantEntity.TYPE", + "EventSvtType", + "NiceEventSvtType", + "Event Svt Type", + "EVENT_SVT_TYPE_NAME", + ), ]