From 83b981917e35f218e6849cbb3f455b5edbbec6e5 Mon Sep 17 00:00:00 2001 From: Hay1tsme Date: Mon, 22 Jan 2024 17:42:58 -0500 Subject: [PATCH] sao: add logout_ticket_unpurchased, get_quest_hierarchy_progress_degrees_ranking_list and get_quest_popular_hero_log_ranking_list --- titles/sao/base.py | 18 ++++++++- titles/sao/handlers/base.py | 70 ++++++++++++++++++++++++++++++++ titles/sao/handlers/helpers.py | 73 ++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+), 2 deletions(-) diff --git a/titles/sao/base.py b/titles/sao/base.py index 03470d7..c329d38 100644 --- a/titles/sao/base.py +++ b/titles/sao/base.py @@ -48,7 +48,6 @@ class SaoBase: resp = SaoGiveFreeTicketResponse(header.cmd +1) return resp.make() - async def handle_c12e(self, header: SaoRequestHeader, request: bytes) -> bytes: #common/ac_cabinet_boot_notification resp = SaoCommonAcCabinetBootNotificationResponse(header.cmd +1) @@ -977,4 +976,19 @@ class SaoBase: async def handle_d606(self, header: SaoRequestHeader, request: bytes) -> bytes: # master_data_2/get_m_res_earn_campaign_shop_items - return SaoNoopResponse(header.cmd + 1).make() \ No newline at end of file + return SaoNoopResponse(header.cmd + 1).make() + + async def handle_c108(self, header: SaoRequestHeader, request: bytes) -> bytes: + # common/logout_ticket_unpurchased + req = SaoLogoutTicketUnpurchasedRequest(header, request) + return SaoLogoutTicketUnpurchasedResponse(header.cmd + 1).make() + + async def handle_cb02(self, header: SaoRequestHeader, request: bytes) -> bytes: + # quest_ranking/get_quest_hierarchy_progress_degrees_ranking_list + req = SaoGetQuestHierarchyProgressDegreesRankingListRequest(header, request) + return SaoGetQuestHierarchyProgressDegreesRankingListResponse(header.cmd + 1).make() + + async def handle_cb04(self, header: SaoRequestHeader, request: bytes) -> bytes: + # quest_ranking/get_quest_popular_hero_log_ranking_list + req = SaoGetQuestPopularHeroLogRankingListRequest(header, request) + return SaoGetQuestPopularHeroLogRankingListResponse(header.cmd + 1).make() diff --git a/titles/sao/handlers/base.py b/titles/sao/handlers/base.py index 81f30f8..2f2f13e 100644 --- a/titles/sao/handlers/base.py +++ b/titles/sao/handlers/base.py @@ -3252,3 +3252,73 @@ class SaoGiveFreeTicketResponse(SaoBaseResponse): def make(self) -> bytes: ret = encode_byte(self.result) return super().make() + ret + +class SaoLogoutTicketUnpurchasedRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + +class SaoLogoutTicketUnpurchasedResponse(SaoBaseResponse): + def __init__(self, cmd_id: int) -> None: + super().__init__(cmd_id) + self.result = 1 # byte + + def make(self) -> bytes: + ret = encode_byte(self.result) + return super().make() + ret + +class SaoGetQuestHierarchyProgressDegreesRankingListRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.get_rank_start_num = decode_short(data, off) + off += SHORT_OFF + + self.get_rank_end_num = decode_short(data, off) + off += SHORT_OFF + +class SaoGetQuestHierarchyProgressDegreesRankingListResponse(SaoBaseResponse): + def __init__(self, cmd_id: int) -> None: + super().__init__(cmd_id) + self.result = 1 # byte + self.quest_hierarchy_progress_degrees_ranking_data_list: List[QuestHierarchyProgressDegreesRankingData] = [] + + def make(self) -> bytes: + ret = encode_byte(self.result) + ret += encode_arr_cls(self.quest_hierarchy_progress_degrees_ranking_data_list) + return super().make() + ret + +class SaoGetQuestPopularHeroLogRankingListRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.get_rank_start_num = decode_short(data, off) + off += SHORT_OFF + + self.get_rank_end_num = decode_short(data, off) + off += SHORT_OFF + +class SaoGetQuestPopularHeroLogRankingListResponse(SaoBaseResponse): + def __init__(self, cmd_id: int) -> None: + super().__init__(cmd_id) + self.result = 1 # byte + self.quest_popular_hero_log_ranking_data_list: List[PopularHeroLogRankingData] = [] + + def make(self) -> bytes: + ret = encode_byte(self.result) + ret += encode_arr_cls(self.quest_popular_hero_log_ranking_data_list) + return super().make() + ret diff --git a/titles/sao/handlers/helpers.py b/titles/sao/handlers/helpers.py index 6e11146..97a15b2 100644 --- a/titles/sao/handlers/helpers.py +++ b/titles/sao/handlers/helpers.py @@ -915,3 +915,76 @@ class GashaMedalShop(BaseHelper): ret += encode_str(fmt_dt(self.sales_start_date)) ret += encode_str(fmt_dt(self.sales_end_date)) return ret + +class QuestHierarchyProgressDegreesRankingData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + self.rank = decode_int(data, offset + self._sz) + self._sz += INT_OFF + self.trial_tower_id = decode_int(data, offset + self._sz) + self._sz += INT_OFF + + user_id = decode_str(data, offset + self._sz) + self.user_id = user_id[0] + self._sz += user_id[1] + + nick_name = decode_str(data, offset + self._sz) + self.nick_name = nick_name[0] + self._sz += nick_name[1] + + self.setting_title_id = decode_int(data, offset + self._sz) + self._sz += INT_OFF + self.favorite_hero_log_id = decode_int(data, offset + self._sz) + self._sz += INT_OFF + self.favorite_hero_log_awakening_stage = decode_short(data, offset + self._sz) + self._sz += SHORT_OFF + self.favorite_support_log_id = decode_int(data, offset + self._sz) + self._sz += INT_OFF + self.favorite_support_log_awakening_stage = decode_short(data, offset + self._sz) + self._sz += SHORT_OFF + + clear_time = decode_str(data, offset + self._sz) + self.clear_time = clear_time[0] + self._sz += clear_time[1] + + @classmethod + def from_args(cls) -> "QuestHierarchyProgressDegreesRankingData": + ret = cls(b"\x00" * 36, 0) + return ret + + def make(self) -> bytes: + ret = encode_int(self.rank) + ret += encode_int(self.trial_tower_id) + ret += encode_str(self.user_id) + ret += encode_str(self.nick_name) + ret += encode_int(self.setting_title_id) + ret += encode_int(self.favorite_hero_log_id) + ret += encode_short(self.favorite_hero_log_awakening_stage) + ret += encode_int(self.favorite_support_log_id) + ret += encode_short(self.favorite_support_log_awakening_stage) + ret += encode_str(self.clear_time) + return ret + +class PopularHeroLogRankingData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + self.rank = decode_int(data, offset + self._sz) + self._sz += INT_OFF + self.hero_log_id = decode_int(data, offset + self._sz) + self._sz += INT_OFF + self.used_num = decode_int(data, offset + self._sz) + self._sz += INT_OFF + + @classmethod + def from_args(cls, ranking: int, hero_id: int, used_num: int) -> "PopularHeroLogRankingData": + ret = cls(b"\x00" * 12, 0) + cls.ranking = ranking + cls.hero_log_id = hero_id + cls.used_num = used_num + return ret + + def make(self) -> bytes: + ret = encode_int(self.rank) + ret += encode_int(self.hero_log_id) + ret += encode_int(self.used_num) + return ret