Merge branch 'starlette_cleanup' into develop

This commit is contained in:
Kevin Trocolli
2024-01-11 20:24:59 -05:00
177 changed files with 5251 additions and 4978 deletions

View File

@@ -7,4 +7,3 @@ index = SaoServlet
database = SaoData
reader = SaoReader
game_codes = [SaoConstants.GAME_CODE]
current_schema_version = 1

View File

@@ -32,12 +32,12 @@ class SaoBase:
self.logger.warning(f"Failed to find csv file {file}.csv")
return ret
def handle_noop(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_noop(self, header: SaoRequestHeader, request: bytes) -> bytes:
self.logger.info(f"Using Generic handler")
resp_thing = SaoNoopResponse(header.cmd + 1)
return resp_thing.make()
def handle_c122(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c122(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/get_maintenance_info
resp = SaoGetMaintResponse(header.cmd +1)
return resp.make()
@@ -50,32 +50,32 @@ class SaoBase:
return resp.make()
def handle_c12e(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c12e(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/ac_cabinet_boot_notification
resp = SaoCommonAcCabinetBootNotificationResponse(header.cmd +1)
return resp.make()
def handle_c100(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c100(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/get_app_versions
resp = SaoCommonGetAppVersionsRequest(header.cmd +1)
return resp.make()
def handle_c102(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c102(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/master_data_version_check
resp = SaoMasterDataVersionCheckResponse(header.cmd +1)
return resp.make()
def handle_c10a(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c10a(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/paying_play_start
resp = SaoCommonPayingPlayStartRequest(header.cmd +1)
return resp.make()
def handle_ca02(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_ca02(self, header: SaoRequestHeader, request: bytes) -> bytes:
#quest_multi_play_room/get_quest_scene_multi_play_photon_server
resp = SaoGetQuestSceneMultiPlayPhotonServerResponse(header.cmd +1)
return resp.make()
def handle_c11e(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c11e(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/get_auth_card_data
req = SaoGetAuthCardDataRequest(header, request)
@@ -128,12 +128,12 @@ class SaoBase:
resp = SaoGetAuthCardDataResponse(header.cmd +1, profile_data)
return resp.make()
def handle_c40c(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c40c(self, header: SaoRequestHeader, request: bytes) -> bytes:
#home/check_ac_login_bonus
resp = SaoHomeCheckAcLoginBonusResponse(header.cmd +1)
return resp.make()
def handle_c104(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c104(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/login
req = SaoCommonLoginRequest(header, request)
@@ -143,17 +143,17 @@ class SaoBase:
resp = SaoCommonLoginResponse(header.cmd +1, profile_data)
return resp.make()
def handle_c404(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c404(self, header: SaoRequestHeader, request: bytes) -> bytes:
#home/check_comeback_event
resp = SaoCheckComebackEventRequest(header.cmd +1)
return resp.make()
def handle_c000(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c000(self, header: SaoRequestHeader, request: bytes) -> bytes:
#ticket/ticket
resp = SaoTicketResponse(header.cmd +1)
return resp.make()
def handle_c500(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c500(self, header: SaoRequestHeader, request: bytes) -> bytes:
#user_info/get_user_basic_data
req = SaoGetUserBasicDataRequest(header, request)
@@ -162,7 +162,7 @@ class SaoBase:
resp = SaoGetUserBasicDataResponse(header.cmd +1, profile_data)
return resp.make()
def handle_c600(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c600(self, header: SaoRequestHeader, request: bytes) -> bytes:
#have_object/get_hero_log_user_data_list
req = SaoGetHeroLogUserDataListRequest(header, request)
@@ -171,7 +171,7 @@ class SaoBase:
resp = SaoGetHeroLogUserDataListResponse(header.cmd +1, hero_data)
return resp.make()
def handle_c602(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c602(self, header: SaoRequestHeader, request: bytes) -> bytes:
#have_object/get_equipment_user_data_list
req = SaoGetEquipmentUserDataListRequest(header, request)
@@ -180,7 +180,7 @@ class SaoBase:
resp = SaoGetEquipmentUserDataListResponse(header.cmd +1, equipment_data)
return resp.make()
def handle_c604(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c604(self, header: SaoRequestHeader, request: bytes) -> bytes:
#have_object/get_item_user_data_list
req = SaoGetItemUserDataListRequest(header, request)
@@ -189,21 +189,21 @@ class SaoBase:
resp = SaoGetItemUserDataListResponse(header.cmd +1, item_data)
return resp.make()
def handle_c606(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c606(self, header: SaoRequestHeader, request: bytes) -> bytes:
#have_object/get_support_log_user_data_list
supportIdsData = self.game_data.static.get_support_log_ids(0, True)
resp = SaoGetSupportLogUserDataListResponse(header.cmd +1, supportIdsData)
return resp.make()
def handle_c800(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c800(self, header: SaoRequestHeader, request: bytes) -> bytes:
#custom/get_title_user_data_list
titleIdsData = self.game_data.static.get_title_ids(0, True)
resp = SaoGetTitleUserDataListResponse(header.cmd +1, titleIdsData)
return resp.make()
def handle_c608(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c608(self, header: SaoRequestHeader, request: bytes) -> bytes:
#have_object/get_episode_append_data_list
req = SaoGetEpisodeAppendDataListRequest(header, request)
@@ -212,7 +212,7 @@ class SaoBase:
resp = SaoGetEpisodeAppendDataListResponse(header.cmd +1, profile_data)
return resp.make()
def handle_c804(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c804(self, header: SaoRequestHeader, request: bytes) -> bytes:
#custom/get_party_data_list
req = SaoGetPartyDataListRequest(header, request)
@@ -224,17 +224,17 @@ class SaoBase:
resp = SaoGetPartyDataListResponse(header.cmd +1, hero1_data, hero2_data, hero3_data)
return resp.make()
def handle_c902(self, header: SaoRequestHeader, request: bytes) -> bytes: # for whatever reason, having all entries empty or filled changes nothing
async def handle_c902(self, header: SaoRequestHeader, request: bytes) -> bytes: # for whatever reason, having all entries empty or filled changes nothing
#quest/get_quest_scene_prev_scan_profile_card
resp = SaoGetQuestScenePrevScanProfileCardResponse(header.cmd +1)
return resp.make()
def handle_c124(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c124(self, header: SaoRequestHeader, request: bytes) -> bytes:
#common/get_resource_path_info
resp = SaoGetResourcePathInfoResponse(header.cmd +1)
return resp.make()
def handle_c900(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c900(self, header: SaoRequestHeader, request: bytes) -> bytes:
#quest/get_quest_scene_user_data_list // QuestScene.csv
req = SaoGetQuestSceneUserDataListRequest(header, request)
@@ -243,22 +243,22 @@ class SaoBase:
resp = SaoGetQuestSceneUserDataListResponse(header.cmd +1, quest_data)
return resp.make()
def handle_c400(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c400(self, header: SaoRequestHeader, request: bytes) -> bytes:
#home/check_yui_medal_get_condition
resp = SaoCheckYuiMedalGetConditionResponse(header.cmd +1)
return resp.make()
def handle_c402(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c402(self, header: SaoRequestHeader, request: bytes) -> bytes:
#home/get_yui_medal_bonus_user_data
resp = SaoGetYuiMedalBonusUserDataResponse(header.cmd +1)
return resp.make()
def handle_c40a(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c40a(self, header: SaoRequestHeader, request: bytes) -> bytes:
#home/check_profile_card_used_reward
resp = SaoCheckProfileCardUsedRewardResponse(header.cmd +1)
return resp.make()
def handle_c814(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c814(self, header: SaoRequestHeader, request: bytes) -> bytes:
#custom/synthesize_enhancement_hero_log
req = SaoSynthesizeEnhancementHeroLogRequest(header, request)
@@ -332,7 +332,7 @@ class SaoBase:
resp = SaoSynthesizeEnhancementHeroLogResponse(header.cmd +1, synthesize_hero_log_data)
return resp.make()
def handle_c816(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c816(self, header: SaoRequestHeader, request: bytes) -> bytes:
#custom/synthesize_enhancement_equipment
req_data = SaoSynthesizeEnhancementEquipmentRequest(header, request)
synthesize_equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id)
@@ -394,7 +394,7 @@ class SaoBase:
resp = SaoSynthesizeEnhancementEquipmentResponse(header.cmd +1, synthesize_equipment_data)
return resp.make()
def handle_c806(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c806(self, header: SaoRequestHeader, request: bytes) -> bytes:
#custom/change_party
req_data = SaoChangePartyRequest(header, request)
party_hero_list = []
@@ -429,7 +429,7 @@ class SaoBase:
resp = SaoNoopResponse(header.cmd +1)
return resp.make()
def handle_c904(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c904(self, header: SaoRequestHeader, request: bytes) -> bytes:
#quest/episode_play_start
req_data = SaoEpisodePlayStartRequest(header, request)
@@ -447,7 +447,7 @@ class SaoBase:
resp = SaoEpisodePlayStartResponse(header.cmd +1, profile_data)
return resp.make()
def handle_c908(self, header: SaoRequestHeader, request: bytes) -> bytes: # Level calculation missing for the profile and heroes
async def handle_c908(self, header: SaoRequestHeader, request: bytes) -> bytes: # Level calculation missing for the profile and heroes
#quest/episode_play_end
req_data = SaoEpisodePlayEndRequest(header, request)
@@ -607,7 +607,7 @@ class SaoBase:
resp = SaoEpisodePlayEndResponse(header.cmd +1)
return resp.make()
def handle_c914(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c914(self, header: SaoRequestHeader, request: bytes) -> bytes:
#quest/trial_tower_play_start
req_data = SaoTrialTowerPlayStartRequest(header, request)
@@ -626,7 +626,7 @@ class SaoBase:
resp = SaoEpisodePlayStartResponse(header.cmd +1, profile_data)
return resp.make()
def handle_c918(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c918(self, header: SaoRequestHeader, request: bytes) -> bytes:
#quest/trial_tower_play_end
req_data = SaoTrialTowerPlayEndRequest(header, request)
@@ -807,7 +807,7 @@ class SaoBase:
resp = SaoTrialTowerPlayEndResponse(header.cmd +1)
return resp.make()
def handle_c90a(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c90a(self, header: SaoRequestHeader, request: bytes) -> bytes:
#quest/episode_play_end_unanalyzed_log_fixed
req = SaoEpisodePlayEndUnanalyzedLogFixedRequest(header, request)
@@ -817,7 +817,7 @@ class SaoBase:
resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse(header.cmd +1, end_session_data[4])
return resp.make()
def handle_c91a(self, header: SaoRequestHeader, request: bytes) -> bytes: # handler is identical to the episode
async def handle_c91a(self, header: SaoRequestHeader, request: bytes) -> bytes: # handler is identical to the episode
#quest/trial_tower_play_end_unanalyzed_log_fixed
req = TrialTowerPlayEndUnanalyzedLogFixed(header, request)
@@ -826,58 +826,58 @@ class SaoBase:
resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse(header.cmd +1, end_session_data[4])
return resp.make()
def handle_cd00(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_cd00(self, header: SaoRequestHeader, request: bytes) -> bytes:
#defrag_match/get_defrag_match_basic_data
resp = SaoGetDefragMatchBasicDataResponse(header.cmd +1)
return resp.make()
def handle_cd02(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_cd02(self, header: SaoRequestHeader, request: bytes) -> bytes:
#defrag_match/get_defrag_match_ranking_user_data
resp = SaoGetDefragMatchRankingUserDataResponse(header.cmd +1)
return resp.make()
def handle_cd04(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_cd04(self, header: SaoRequestHeader, request: bytes) -> bytes:
#defrag_match/get_defrag_match_league_point_ranking_list
resp = SaoGetDefragMatchLeaguePointRankingListResponse(header.cmd +1)
return resp.make()
def handle_cd06(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_cd06(self, header: SaoRequestHeader, request: bytes) -> bytes:
#defrag_match/get_defrag_match_league_score_ranking_list
resp = SaoGetDefragMatchLeagueScoreRankingListResponse(header.cmd +1)
return resp.make()
def handle_d404(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d404(self, header: SaoRequestHeader, request: bytes) -> bytes:
#other/bnid_serial_code_check
resp = SaoBnidSerialCodeCheckResponse(header.cmd +1)
return resp.make()
def handle_c306(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c306(self, header: SaoRequestHeader, request: bytes) -> bytes:
#card/scan_qr_quest_profile_card
resp = SaoScanQrQuestProfileCardResponse(header.cmd +1)
return resp.make()
def handle_c700(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_c700(self, header: SaoRequestHeader, request: bytes) -> bytes:
# shop/get_shop_resource_sales_data_list
# TODO: Get user shop data
req = GetShopResourceSalesDataListRequest(header, request)
resp = GetShopResourceSalesDataListResponse(header.cmd + 1)
return resp.make()
def handle_d100(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d100(self, header: SaoRequestHeader, request: bytes) -> bytes:
# shop/get_yui_medal_shop_user_data_list
# TODO: Get user shop data
req = GetYuiMedalShopUserDataListRequest(header, request)
resp = GetYuiMedalShopUserDataListResponse(header.cmd + 1)
return resp.make()
def handle_cf0e(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_cf0e(self, header: SaoRequestHeader, request: bytes) -> bytes:
# gasha/get_gasha_medal_shop_user_data_list
# TODO: Get user shop data
req = GetGashaMedalShopUserDataListRequest(header, request)
resp = GetGashaMedalShopUserDataListResponse(header.cmd + 1)
return resp.make()
def handle_d5da(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d5da(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_yui_medal_shops
req = GetMYuiMedalShopDataRequest(header, request)
resp = GetMYuiMedalShopDataResponse(header.cmd + 1)
@@ -905,7 +905,7 @@ class SaoBase:
self.logger.debug(f"Load {len(resp.data_list)} Yui Medal Shops")
return resp.make()
def handle_d5dc(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d5dc(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_yui_medal_shop_items
req = GetMYuiMedalShopItemsRequest(header, request)
resp = GetMYuiMedalShopItemsResponse(header.cmd + 1)
@@ -935,7 +935,7 @@ class SaoBase:
self.logger.debug(f"Load {len(resp.data_list)} Yui Medal Shop Items")
return resp.make()
def handle_d5fc(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d5fc(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_gasha_medal_shops
req = GetMGashaMedalShopsRequest(header, request)
resp = GetMGashaMedalShopsResponse(header.cmd + 1)
@@ -950,11 +950,11 @@ class SaoBase:
self.logger.debug(f"Load {len(resp.data_list)} Gasha Medal Shops")
return resp.make()
def handle_d5fe(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d5fe(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_gasha_medal_shop_items
return SaoNoopResponse(header.cmd + 1).make()
def handle_d604(self, header: SaoRequestHeader, request: bytes) -> bytes:
async def handle_d604(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data_2/get_m_res_earn_campaign_shops
req = GetMResEarnCampaignShopsRequest(header, request)
resp = GetMResEarnCampaignShopsResponse(header.cmd + 1)
@@ -976,6 +976,6 @@ class SaoBase:
#self.logger.debug(f"Load {len(resp.data_list)} Res Earn Campaign Shops")
return SaoNoopResponse(header.cmd + 1).make()
def handle_d606(self, header: SaoRequestHeader, request: bytes) -> bytes:
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()

View File

@@ -3,12 +3,22 @@ from enum import Enum
class SaoConstants:
GAME_CODE = "SDEW"
GAME_CDS = ["SAO1"]
CONFIG_NAME = "sao.yaml"
VER_SAO = 0
VERSION_NAMES = ("Sword Art Online Arcade")
SERIAL_IDENT_SATALITE = 4
SERIAL_IDENT_TERMINAL = 5
SERIAL_IDENT = [2825]
NETID_PREFIX = ["ABLN"]
SERIAL_REGIONS = [1]
SERIAL_ROLES = [3]
SERIAL_CAB_IDENTS = [SERIAL_IDENT_SATALITE, SERIAL_IDENT_TERMINAL]
@classmethod
def game_ver_to_string(cls, ver: int):

View File

@@ -16,7 +16,7 @@ class SaoRequestHeader:
self.game_id: int = collection[4]
self.version_id: int = collection[5]
self.hash: str = collection[6]
self.data_len: str = collection[7]
self.data._len: str = collection[7]
class SaoBaseRequest:
def __init__(self, header: SaoRequestHeader, data: bytes) -> None:
@@ -118,7 +118,7 @@ class SaoMasterDataVersionCheckResponse(SaoBaseResponse):
super().__init__(cmd)
self.result = 1
self.update_flag = 0
self.data_version = 100
self.data._version = 100
def make(self) -> bytes:
# create a resp struct
@@ -131,7 +131,7 @@ class SaoMasterDataVersionCheckResponse(SaoBaseResponse):
resp_data = resp_struct.build(dict(
result=self.result,
update_flag=self.update_flag,
data_version=self.data_version,
data_version=self.data._version,
))
self.length = len(resp_data)
@@ -145,7 +145,7 @@ class SaoCommonGetAppVersionsRequest(SaoBaseResponse):
def __init__(self, cmd) -> None:
super().__init__(cmd)
self.result = 1
self.data_list_size = 1 # Number of arrays
self.data._list_size = 1 # Number of arrays
self.version_app_id = 1
self.applying_start_date = "20230520193000"
@@ -163,7 +163,7 @@ class SaoCommonGetAppVersionsRequest(SaoBaseResponse):
resp_data = resp_struct.build(dict(
result=self.result,
data_list_size=self.data_list_size,
data_list_size=self.data._list_size,
version_app_id=self.version_app_id,
applying_start_date_size=len(self.applying_start_date) * 2,
@@ -2121,7 +2121,7 @@ class SaoGetYuiMedalBonusUserDataResponse(SaoBaseResponse):
def __init__(self, cmd) -> None:
super().__init__(cmd)
self.result = 1
self.data_size = 1 # number of arrays
self.data._size = 1 # number of arrays
self.elapsed_days = 1
self.loop_num = 1
@@ -2144,7 +2144,7 @@ class SaoGetYuiMedalBonusUserDataResponse(SaoBaseResponse):
resp_data = resp_struct.build(dict(
result=self.result,
data_size=self.data_size,
data_size=self.data._size,
elapsed_days=self.elapsed_days,
loop_num=self.loop_num,
@@ -3150,11 +3150,11 @@ class GetGashaMedalShopUserDataListResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[GashaMedalShopUserData] = []
self.data._list: List[GashaMedalShopUserData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
ret += encode_arr_cls(self.data._list)
self.header.length = len(ret)
return super().make() + ret
@@ -3168,11 +3168,11 @@ class GetMYuiMedalShopDataResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[YuiMedalShopData] = []
self.data._list: List[YuiMedalShopData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
ret += encode_arr_cls(self.data._list)
self.header.length = len(ret)
return super().make() + ret
@@ -3186,11 +3186,11 @@ class GetMYuiMedalShopItemsResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[YuiMedalShopItemData] = []
self.data._list: List[YuiMedalShopItemData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
ret += encode_arr_cls(self.data._list)
self.header.length = len(ret)
return super().make() + ret
@@ -3204,11 +3204,11 @@ class GetMGashaMedalShopsResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[GashaMedalShop] = []
self.data._list: List[GashaMedalShop] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
ret += encode_arr_cls(self.data._list)
self.header.length = len(ret)
return super().make() + ret
@@ -3222,11 +3222,11 @@ class GetMResEarnCampaignShopsResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[ResEarnCampaignShop] = []
self.data._list: List[ResEarnCampaignShop] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
ret += encode_arr_cls(self.data._list)
self.header.length = len(ret)
return super().make() + ret

View File

@@ -1,5 +1,7 @@
from typing import Tuple, Dict, List
from twisted.web.http import Request
from starlette.requests import Request
from starlette.responses import Response
from starlette.routing import Route
import yaml
import logging, coloredlogs
from logging.handlers import TimedRotatingFileHandler
@@ -55,11 +57,10 @@ class SaoServlet(BaseServlet):
if self.game_cfg.hash.verify_hash:
self.static_hash = md5(self.game_cfg.hash.hash_base.encode()).digest() # Greate hashing guys, really validates the data
def get_endpoint_matchers(self) -> Tuple[List[Tuple[str, str, Dict]], List[Tuple[str, str, Dict]]]:
return (
[],
[("render_POST", "/{datecode}/proto/if/{category}/{endpoint}", {})]
)
def get_routes(self) -> List[Route]:
return [
Route("/{datecode:int}/proto/if/{category:str}/{endpoint:str}", self.render_POST, methods=['POST'])
]
@classmethod
def is_game_enabled(cls, game_code: str, core_cfg: CoreConfig, cfg_dir: str) -> bool:
@@ -80,36 +81,36 @@ class SaoServlet(BaseServlet):
port_normal = Utils.get_title_port(self.core_cfg)
proto = "http"
port = f":{port_normal}" if not self.core_cfg.server.is_using_proxy and port_normal != 80 else ""
port = f":{port_normal}" if port_normal != 80 else ""
if self.game_cfg.server.use_https:
proto = "https"
port = f":{port_ssl}" if not self.core_cfg.server.is_using_proxy and port_ssl != 443 else ""
port = f":{port_ssl}" if port_ssl != 443 else ""
return (f"{proto}://{self.core_cfg.title.hostname}{port}/", "")
def get_mucha_info(self, core_cfg: CoreConfig, cfg_dir: str) -> Tuple[bool, str]:
if not self.game_cfg.server.enable:
return (False, "")
return (False, [], [])
return (True, "SAO1")
return (True, SaoConstants.GAME_CDS, SaoConstants.NETID_PREFIX)
def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
endpoint = matchers.get('endpoint', '')
request.responseHeaders.addRawHeader(b"content-type", b"text/html; charset=utf-8")
async def render_POST(self, request: Request) -> bytes:
endpoint = request.path_params.get('endpoint', '')
iv = b""
req_raw = request.content.read()
req_raw = await request.body()
if len(req_raw) < 40:
self.logger.warn(f"Malformed request to {endpoint} - {req_raw.hex()}")
return b""
return Response()
req_header = SaoRequestHeader(req_raw)
cmd_str = f"{req_header.cmd:04x}"
if self.game_cfg.hash.verify_hash and self.static_hash != req_header.hash:
self.logger.error(f"Hash mismatch! Expecting {self.static_hash} but recieved {req_header.hash}")
return b""
return Response()
if self.game_cfg.crypt.enable:
iv = req_raw[40:48]
@@ -124,7 +125,7 @@ class SaoServlet(BaseServlet):
handler = getattr(self.base, f"handle_{cmd_str}", self.base.handle_noop)
self.logger.info(f"{endpoint} - {cmd_str} request")
self.logger.debug(f"Request: {req_raw.hex()}")
resp = handler(req_header, req_data)
resp = await handler(req_header, req_data)
if resp is None:
resp = SaoNoopResponse(req_header.cmd + 1).make()
@@ -137,7 +138,7 @@ class SaoServlet(BaseServlet):
else:
self.logger.error(f"Unknown response type {type(resp)}")
return b""
return Response()
self.logger.debug(f"Response: {resp.hex()}")
@@ -153,5 +154,6 @@ class SaoServlet(BaseServlet):
tmp = struct.pack("!I", crypt_data_len) # does it want the length of the encrypted response??
resp = resp[:20] + tmp + iv + data_crypt
self.logger.debug(f"Encrypted Response: {resp.hex()}")
return resp
return Response(resp, media_type="text/html; charset=utf-8")

View File

@@ -29,17 +29,15 @@ class SaoReader(BaseReader):
self.logger.error(f"Invalid project SAO version {version}")
exit(1)
def read(self) -> None:
pull_bin_ram = True
async def read(self) -> None:
if path.exists(self.bin_dir):
await self.read_csv(f"{self.bin_dir}")
if not path.exists(f"{self.bin_dir}"):
self.logger.warning(f"Couldn't find csv file in {self.bin_dir}, skipping")
pull_bin_ram = False
else:
self.logger.warn("Directory not found, nothing to import")
if pull_bin_ram:
self.read_csv(f"{self.bin_dir}")
def read_csv(self, bin_dir: str) -> None:
async def read_csv(self, bin_dir: str) -> None:
self.logger.info(f"Read csv from {bin_dir}")
self.logger.info("Now reading QuestScene.csv")
@@ -56,7 +54,7 @@ class SaoReader(BaseReader):
self.logger.info(f"Added quest {questSceneId} | Name: {name}")
try:
self.data.static.put_quest(
await self.data.static.put_quest(
questSceneId,
0,
sortNo,
@@ -86,7 +84,7 @@ class SaoReader(BaseReader):
self.logger.info(f"Added hero {heroLogId} | Name: {name}")
try:
self.data.static.put_hero(
await self.data.static.put_hero(
0,
heroLogId,
name,
@@ -119,7 +117,7 @@ class SaoReader(BaseReader):
self.logger.info(f"Added equipment {equipmentId} | Name: {name}")
try:
self.data.static.put_equipment(
await self.data.static.put_equipment(
0,
equipmentId,
name,
@@ -150,7 +148,7 @@ class SaoReader(BaseReader):
self.logger.info(f"Added item {itemId} | Name: {name}")
try:
self.data.static.put_item(
await self.data.static.put_item(
0,
itemId,
name,
@@ -181,7 +179,7 @@ class SaoReader(BaseReader):
self.logger.info(f"Added support log {supportLogId} | Name: {name}")
try:
self.data.static.put_support_log(
await self.data.static.put_support_log(
0,
supportLogId,
charaId,
@@ -213,7 +211,7 @@ class SaoReader(BaseReader):
if len(titleId) > 5:
try:
self.data.static.put_title(
await self.data.static.put_title(
0,
titleId,
displayName,
@@ -242,7 +240,7 @@ class SaoReader(BaseReader):
self.logger.info(f"Added rare drop {questRareDropId} | Reward: {commonRewardId}")
try:
self.data.static.put_rare_drop(
await self.data.static.put_rare_drop(
0,
questRareDropId,
commonRewardId,

View File

@@ -139,7 +139,7 @@ end_sessions = Table(
)
class SaoItemData(BaseData):
def create_session(self, user_id: int, user_party_team_id: int, episode_id: int, play_mode: int, quest_drop_boost_apply_flag: int) -> Optional[int]:
async def create_session(self, user_id: int, user_party_team_id: int, episode_id: int, play_mode: int, quest_drop_boost_apply_flag: int) -> Optional[int]:
sql = insert(sessions).values(
user=user_id,
user_party_team_id=user_party_team_id,
@@ -150,13 +150,13 @@ class SaoItemData(BaseData):
conflict = sql.on_duplicate_key_update(user=user_id)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(f"Failed to create SAO session for user {user_id}!")
return None
return result.lastrowid
def create_end_session(self, user_id: int, quest_id: int, play_result_flag: bool, reward_data: JSON) -> Optional[int]:
async def create_end_session(self, user_id: int, quest_id: int, play_result_flag: bool, reward_data: JSON) -> Optional[int]:
sql = insert(end_sessions).values(
user=user_id,
quest_id=quest_id,
@@ -166,13 +166,13 @@ class SaoItemData(BaseData):
conflict = sql.on_duplicate_key_update(user=user_id)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(f"Failed to create SAO end session for user {user_id}!")
return None
return result.lastrowid
def put_item(self, user_id: int, item_id: int) -> Optional[int]:
async def put_item(self, user_id: int, item_id: int) -> Optional[int]:
sql = insert(item_data).values(
user=user_id,
item_id=item_id,
@@ -182,7 +182,7 @@ class SaoItemData(BaseData):
item_id=item_id,
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(
f"{__name__} failed to insert item! user: {user_id}, item_id: {item_id}"
@@ -191,7 +191,7 @@ class SaoItemData(BaseData):
return result.lastrowid
def put_equipment_data(self, user_id: int, equipment_id: int, enhancement_value: int, enhancement_exp: int, awakening_exp: int, awakening_stage: int, possible_awakening_flag: int) -> Optional[int]:
async def put_equipment_data(self, user_id: int, equipment_id: int, enhancement_value: int, enhancement_exp: int, awakening_exp: int, awakening_stage: int, possible_awakening_flag: int) -> Optional[int]:
sql = insert(equipment_data).values(
user=user_id,
equipment_id=equipment_id,
@@ -210,7 +210,7 @@ class SaoItemData(BaseData):
possible_awakening_flag=possible_awakening_flag,
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(
f"{__name__} failed to insert equipment! user: {user_id}, equipment_id: {equipment_id}"
@@ -219,7 +219,7 @@ class SaoItemData(BaseData):
return result.lastrowid
def put_hero_log(self, user_id: int, user_hero_log_id: int, log_level: int, log_exp: int, main_weapon: int, sub_equipment: int, skill_slot1_skill_id: int, skill_slot2_skill_id: int, skill_slot3_skill_id: int, skill_slot4_skill_id: int, skill_slot5_skill_id: int) -> Optional[int]:
async def put_hero_log(self, user_id: int, user_hero_log_id: int, log_level: int, log_exp: int, main_weapon: int, sub_equipment: int, skill_slot1_skill_id: int, skill_slot2_skill_id: int, skill_slot3_skill_id: int, skill_slot4_skill_id: int, skill_slot5_skill_id: int) -> Optional[int]:
sql = insert(hero_log_data).values(
user=user_id,
user_hero_log_id=user_hero_log_id,
@@ -246,7 +246,7 @@ class SaoItemData(BaseData):
skill_slot5_skill_id=skill_slot5_skill_id,
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(
f"{__name__} failed to insert hero! user: {user_id}, user_hero_log_id: {user_hero_log_id}"
@@ -255,7 +255,7 @@ class SaoItemData(BaseData):
return result.lastrowid
def put_hero_party(self, user_id: int, user_party_team_id: int, user_hero_log_id_1: int, user_hero_log_id_2: int, user_hero_log_id_3: int) -> Optional[int]:
async def put_hero_party(self, user_id: int, user_party_team_id: int, user_hero_log_id_1: int, user_hero_log_id_2: int, user_hero_log_id_3: int) -> Optional[int]:
sql = insert(hero_party).values(
user=user_id,
user_party_team_id=user_party_team_id,
@@ -270,7 +270,7 @@ class SaoItemData(BaseData):
user_hero_log_id_3=user_hero_log_id_3,
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(
f"{__name__} failed to insert hero party! user: {user_id}, user_party_team_id: {user_party_team_id}"
@@ -279,7 +279,7 @@ class SaoItemData(BaseData):
return result.lastrowid
def put_player_quest(self, user_id: int, episode_id: int, quest_clear_flag: bool, clear_time: int, combo_num: int, total_damage: int, concurrent_destroying_num: int) -> Optional[int]:
async def put_player_quest(self, user_id: int, episode_id: int, quest_clear_flag: bool, clear_time: int, combo_num: int, total_damage: int, concurrent_destroying_num: int) -> Optional[int]:
sql = insert(quest).values(
user=user_id,
episode_id=episode_id,
@@ -298,7 +298,7 @@ class SaoItemData(BaseData):
concurrent_destroying_num=concurrent_destroying_num
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(
f"{__name__} failed to insert quest! user: {user_id}, episode_id: {episode_id}"
@@ -307,15 +307,15 @@ class SaoItemData(BaseData):
return result.lastrowid
def get_user_equipment(self, user_id: int, equipment_id: int) -> Optional[Dict]:
async def get_user_equipment(self, user_id: int, equipment_id: int) -> Optional[Dict]:
sql = equipment_data.select(equipment_data.c.user == user_id and equipment_data.c.equipment_id == equipment_id)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_user_equipments(
async def get_user_equipments(
self, user_id: int
) -> Optional[List[Row]]:
"""
@@ -327,12 +327,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchall()
def get_user_items(
async def get_user_items(
self, user_id: int
) -> Optional[List[Row]]:
"""
@@ -344,12 +344,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchall()
def get_hero_log(
async def get_hero_log(
self, user_id: int, user_hero_log_id: int = None
) -> Optional[List[Row]]:
"""
@@ -362,12 +362,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_hero_logs(
async def get_hero_logs(
self, user_id: int
) -> Optional[List[Row]]:
"""
@@ -379,12 +379,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchall()
def get_hero_party(
async def get_hero_party(
self, user_id: int, user_party_team_id: int = None
) -> Optional[List[Row]]:
sql = hero_party.select(
@@ -394,12 +394,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_quest_log(
async def get_quest_log(
self, user_id: int, episode_id: int = None
) -> Optional[List[Row]]:
"""
@@ -412,12 +412,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_quest_logs(
async def get_quest_logs(
self, user_id: int
) -> Optional[List[Row]]:
"""
@@ -429,12 +429,12 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchall()
def get_session(
async def get_session(
self, user_id: int = None
) -> Optional[List[Row]]:
sql = sessions.select(
@@ -445,12 +445,12 @@ class SaoItemData(BaseData):
sessions.c.play_date.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_end_session(
async def get_end_session(
self, user_id: int = None
) -> Optional[List[Row]]:
sql = end_sessions.select(
@@ -461,12 +461,12 @@ class SaoItemData(BaseData):
end_sessions.c.play_date.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def remove_hero_log(self, user_id: int, user_hero_log_id: int) -> None:
async def remove_hero_log(self, user_id: int, user_hero_log_id: int) -> None:
sql = hero_log_data.delete(
and_(
hero_log_data.c.user == user_id,
@@ -474,31 +474,31 @@ class SaoItemData(BaseData):
)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
self.logger.error(
f"{__name__} failed to remove hero log! profile: {user_id}, user_hero_log_id: {user_hero_log_id}"
)
return None
def remove_equipment(self, user_id: int, equipment_id: int) -> None:
async def remove_equipment(self, user_id: int, equipment_id: int) -> None:
sql = equipment_data.delete(
and_(equipment_data.c.user == user_id, equipment_data.c.equipment_id == equipment_id)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
self.logger.error(
f"{__name__} failed to remove equipment! profile: {user_id}, equipment_id: {equipment_id}"
)
return None
def remove_item(self, user_id: int, item_id: int) -> None:
async def remove_item(self, user_id: int, item_id: int) -> None:
sql = item_data.delete(
and_(item_data.c.user == user_id, item_data.c.item_id == item_id)
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
self.logger.error(
f"{__name__} failed to remove item! profile: {user_id}, item_id: {item_id}"

View File

@@ -30,17 +30,17 @@ profile = Table(
)
class SaoProfileData(BaseData):
def create_profile(self, user_id: int) -> Optional[int]:
async def create_profile(self, user_id: int) -> Optional[int]:
sql = insert(profile).values(user=user_id)
conflict = sql.on_duplicate_key_update(user=user_id)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(f"Failed to create SAO profile for user {user_id}!")
return None
return result.lastrowid
def put_profile(self, user_id: int, user_type: int, nick_name: str, rank_num: int, rank_exp: int, own_col: int, own_vp: int, own_yui_medal: int, setting_title_id: int) -> Optional[int]:
async def put_profile(self, user_id: int, user_type: int, nick_name: str, rank_num: int, rank_exp: int, own_col: int, own_vp: int, own_yui_medal: int, setting_title_id: int) -> Optional[int]:
sql = insert(profile).values(
user=user_id,
user_type=user_type,
@@ -62,7 +62,7 @@ class SaoProfileData(BaseData):
setting_title_id=setting_title_id
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
self.logger.error(
f"{__name__} failed to insert profile! user: {user_id}"
@@ -71,9 +71,9 @@ class SaoProfileData(BaseData):
return result.lastrowid
def get_profile(self, user_id: int) -> Optional[Row]:
async def get_profile(self, user_id: int) -> Optional[Row]:
sql = profile.select(profile.c.user == user_id)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()

View File

@@ -128,25 +128,25 @@ title = Table(
)
class SaoStaticData(BaseData):
def put_quest( self, questSceneId: int, version: int, sortNo: int, name: str, enabled: bool ) -> Optional[int]:
async def put_quest( self, questSceneId: int, version: int, sortNo: int, name: str, enabled: bool ) -> Optional[int]:
sql = insert(quest).values(
questSceneId=questSceneId,
version=version,
sortNo=sortNo,
name=name,
tutorial=tutorial,
enabled=enabled,
)
conflict = sql.on_duplicate_key_update(
name=name, questSceneId=questSceneId, version=version
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def put_hero( self, version: int, heroLogId: int, name: str, nickname: str, rarity: int, skillTableSubId: int, awakeningExp: int, flavorText: str, enabled: bool ) -> Optional[int]:
async def put_hero( self, version: int, heroLogId: int, name: str, nickname: str, rarity: int, skillTableSubId: int, awakeningExp: int, flavorText: str, enabled: bool ) -> Optional[int]:
sql = insert(hero).values(
version=version,
heroLogId=heroLogId,
@@ -163,12 +163,12 @@ class SaoStaticData(BaseData):
name=name, heroLogId=heroLogId
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def put_equipment( self, version: int, equipmentId: int, name: str, equipmentType: int, weaponTypeId:int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]:
async def put_equipment( self, version: int, equipmentId: int, name: str, equipmentType: int, weaponTypeId:int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]:
sql = insert(equipment).values(
version=version,
equipmentId=equipmentId,
@@ -184,12 +184,12 @@ class SaoStaticData(BaseData):
name=name, equipmentId=equipmentId
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def put_item( self, version: int, itemId: int, name: str, itemTypeId: int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]:
async def put_item( self, version: int, itemId: int, name: str, itemTypeId: int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]:
sql = insert(item).values(
version=version,
itemId=itemId,
@@ -204,12 +204,12 @@ class SaoStaticData(BaseData):
name=name, itemId=itemId
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def put_support_log( self, version: int, supportLogId: int, charaId: int, name: str, rarity: int, salePrice: int, skillName: str, enabled: bool ) -> Optional[int]:
async def put_support_log( self, version: int, supportLogId: int, charaId: int, name: str, rarity: int, salePrice: int, skillName: str, enabled: bool ) -> Optional[int]:
sql = insert(support).values(
version=version,
supportLogId=supportLogId,
@@ -225,12 +225,12 @@ class SaoStaticData(BaseData):
name=name, supportLogId=supportLogId
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def put_rare_drop( self, version: int, questRareDropId: int, commonRewardId: int, enabled: bool ) -> Optional[int]:
async def put_rare_drop( self, version: int, questRareDropId: int, commonRewardId: int, enabled: bool ) -> Optional[int]:
sql = insert(rare_drop).values(
version=version,
questRareDropId=questRareDropId,
@@ -242,12 +242,12 @@ class SaoStaticData(BaseData):
questRareDropId=questRareDropId, commonRewardId=commonRewardId, version=version
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def put_title( self, version: int, titleId: int, displayName: str, requirement: int, rank: int, imageFilePath: str, enabled: bool ) -> Optional[int]:
async def put_title( self, version: int, titleId: int, displayName: str, requirement: int, rank: int, imageFilePath: str, enabled: bool ) -> Optional[int]:
sql = insert(title).values(
version=version,
titleId=titleId,
@@ -262,107 +262,107 @@ class SaoStaticData(BaseData):
displayName=displayName, titleId=titleId
)
result = self.execute(conflict)
result = await self.execute(conflict)
if result is None:
return None
return result.lastrowid
def get_quests_id(self, sortNo: int) -> Optional[Dict]:
async def get_quests_id(self, sortNo: int) -> Optional[Dict]:
sql = quest.select(quest.c.sortNo == sortNo)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_quests_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
async def get_quests_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
sql = quest.select(quest.c.version == version and quest.c.enabled == enabled).order_by(
quest.c.questSceneId.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return [list[2] for list in result.fetchall()]
def get_hero_id(self, heroLogId: int) -> Optional[Dict]:
async def get_hero_id(self, heroLogId: int) -> Optional[Dict]:
sql = hero.select(hero.c.heroLogId == heroLogId)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_hero_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
async def get_hero_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
sql = hero.select(hero.c.version == version and hero.c.enabled == enabled).order_by(
hero.c.heroLogId.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return [list[2] for list in result.fetchall()]
def get_equipment_id(self, equipmentId: int) -> Optional[Dict]:
async def get_equipment_id(self, equipmentId: int) -> Optional[Dict]:
sql = equipment.select(equipment.c.equipmentId == equipmentId)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_equipment_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
async def get_equipment_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
sql = equipment.select(equipment.c.version == version and equipment.c.enabled == enabled).order_by(
equipment.c.equipmentId.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return [list[2] for list in result.fetchall()]
def get_item_id(self, itemId: int) -> Optional[Dict]:
async def get_item_id(self, itemId: int) -> Optional[Dict]:
sql = item.select(item.c.itemId == itemId)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_rare_drop_id(self, questRareDropId: int) -> Optional[Dict]:
async def get_rare_drop_id(self, questRareDropId: int) -> Optional[Dict]:
sql = rare_drop.select(rare_drop.c.questRareDropId == questRareDropId)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return result.fetchone()
def get_item_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
async def get_item_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
sql = item.select(item.c.version == version and item.c.enabled == enabled).order_by(
item.c.itemId.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return [list[2] for list in result.fetchall()]
def get_support_log_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
async def get_support_log_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
sql = support.select(support.c.version == version and support.c.enabled == enabled).order_by(
support.c.supportLogId.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return [list[2] for list in result.fetchall()]
def get_title_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
async def get_title_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
sql = title.select(title.c.version == version and title.c.enabled == enabled).order_by(
title.c.titleId.asc()
)
result = self.execute(sql)
result = await self.execute(sql)
if result is None:
return None
return [list[2] for list in result.fetchall()]