2023-11-11 06:13:09 +00:00
import logging
2023-05-30 18:29:50 +00:00
from csv import *
2024-06-25 18:02:53 +00:00
from random import choice , randint
2023-11-13 22:17:27 +00:00
from typing import Dict , List
from os import path
2024-06-25 18:02:53 +00:00
import re
from sqlalchemy . engine import Row
2023-05-26 17:45:20 +00:00
from core import CoreConfig
from . config import SaoConfig
from . database import SaoData
2024-06-25 18:02:53 +00:00
from . const import GameconnectCmd , RewardType , ExBonusCondition , QuestType
2023-05-26 17:45:20 +00:00
from titles . sao . handlers . base import *
2024-06-25 18:02:53 +00:00
import csv
2023-05-26 17:45:20 +00:00
class SaoBase :
2024-06-25 18:02:53 +00:00
DATA_LIST = { }
2023-05-26 17:45:20 +00:00
def __init__ ( self , core_cfg : CoreConfig , game_cfg : SaoConfig ) - > None :
self . core_cfg = core_cfg
self . game_cfg = game_cfg
2024-01-22 21:45:09 +00:00
self . data = SaoData ( core_cfg )
2023-05-26 17:45:20 +00:00
self . logger = logging . getLogger ( " sao " )
2024-06-25 18:02:53 +00:00
def load_data_csv ( self , file : str , version : int = 1 , base_ver : int = 1 ) - > List [ Dict ] :
if base_ver > version :
self . logger . warning ( f " load_data_csv: Cannot use base version higher then requested version ( { base_ver } > { version } ) " )
return [ ]
for x in range ( version , base_ver - 1 , - 1 ) :
ret = self . DATA_LIST . get ( x , { } ) . get ( file , [ ] )
if ret :
break
if not ret and base_ver != 1 :
ret = self . DATA_LIST . get ( 1 , { } ) . get ( file , [ ] )
if ret :
2023-11-13 22:17:27 +00:00
return ret
2024-06-25 18:02:53 +00:00
found = False
for x in range ( version , base_ver - 1 , - 1 ) :
fname = f " ./titles/sao/data/ { x } / { file } .csv "
if path . exists ( fname ) :
found_ver = x
found = True
break
if not found and base_ver != 1 : # v1 will always be fallback if it isn't already
fname = f " ./titles/sao/data/1/ { file } .csv "
if path . exists ( fname ) :
found_ver = 1
found = True
if not found :
self . logger . warning ( f " load_data_csv: Failed to find v { version } csv file { fname } " )
return [ ]
ret = [ ]
with open ( fname , " r " , encoding = " utf8 " ) as f :
data = csv . DictReader ( f , delimiter = ' , ' )
for x in data :
newdict = { }
for k , v in x . items ( ) :
newkey = k
if k . startswith ( " // " ) :
newkey = k . replace ( " // " , " " )
if v . isdigit ( ) :
newdict [ newkey ] = int ( v )
elif v . lower ( ) == " true " :
newdict [ newkey ] = True
elif v . lower ( ) == " false " :
newdict [ newkey ] = False
elif re . match ( r " ^ \ d \ d \ d \ d \ / \ d \ d \ / \ d \ d \ d { 1,2}: \ d \ d: \ d \ d$ " , v ) :
newdict [ newkey ] = datetime . strptime ( v , " % Y/ % m/ %d % H: % M: % S " )
elif re . match ( r " ^ \ d \ d \ d \ d \ / \ d \ d \ / \ d \ d$ " , v ) :
newdict [ newkey ] = datetime . strptime ( v , " % Y/ % m/ %d " )
else :
newdict [ newkey ] = v
ret . append ( newdict )
# Cache the CSV data in memory
if found_ver not in self . DATA_LIST :
self . DATA_LIST [ found_ver ] = { }
self . DATA_LIST [ found_ver ] [ file ] = ret
2023-11-13 22:17:27 +00:00
return ret
2024-06-25 18:02:53 +00:00
async def add_reward ( self , reward : Dict , user_id : int ) :
reward_type = int ( reward . get ( " CommonRewardType " , " 0 " ) )
if reward_type == RewardType . HeroLog :
reward_hero_data = await self . data . static . get_hero_by_id ( reward [ ' CommonRewardId ' ] )
now_have_skills = await self . hero_default_skills ( reward_hero_data [ ' SkillTableSubId ' ] )
new_hero_id = await self . data . item . put_hero_log (
user_id ,
reward [ ' CommonRewardId ' ] ,
1 ,
0 ,
None ,
None ,
now_have_skills [ 0 ] ,
now_have_skills [ 1 ] ,
now_have_skills [ 2 ] ,
now_have_skills [ 3 ] ,
now_have_skills [ 4 ] ,
)
self . logger . info ( f " Rewarded user { user_id } with hero { reward [ ' CommonRewardId ' ] } (ID { new_hero_id } ) " )
# TODO: add properties
elif reward_type == RewardType . Equipment :
new_equip_id = await self . data . item . put_equipment ( user_id , reward [ ' CommonRewardId ' ] )
self . logger . info ( f " Rewarded user { user_id } with equipment { reward [ ' CommonRewardId ' ] } (ID { new_equip_id } ) " )
elif reward_type == RewardType . Item :
new_item_id = await self . data . item . put_item ( user_id , reward [ ' CommonRewardId ' ] )
self . logger . info ( f " Rewarded user { user_id } with item { reward [ ' CommonRewardId ' ] } (ID { new_item_id } ) " )
elif reward_type == RewardType . Col :
col_num = int ( reward [ ' CommonRewardNum ' ] )
self . logger . info ( f " Rewarded user { user_id } with { col_num } Col " )
await self . data . profile . add_col ( user_id , col_num )
elif reward_type == RewardType . VP :
vp_num = int ( reward [ ' CommonRewardNum ' ] )
self . logger . info ( f " Rewarded user { user_id } with { vp_num } VP " )
await self . data . profile . add_vp ( user_id , vp_num )
elif reward_type == RewardType . YuiMadal :
medal_num = int ( reward [ ' CommonRewardNum ' ] )
self . logger . info ( f " Rewarded user { user_id } with { medal_num } Yui Medals " )
await self . data . profile . add_yui_medals ( user_id , medal_num )
else :
self . logger . warn ( f " User { user_id } Unhandled reward type { reward_type } -> { reward } " )
async def hero_default_skills ( self , skill_table_id : int ) - > List [ int ] :
skills = await self . data . static . get_skill_table_by_subid ( skill_table_id )
if not skills :
self . logger . error ( f " Failed to find skill table { skill_table_id } ! Please run the reader " )
return [ None , None , None , None , None ]
default_skills = [ ]
now_have_skills = [ None , None , None , None , None ]
for skill in skills :
if skill [ ' LevelObtained ' ] == 1 and skill [ ' AwakeningId ' ] == 0 :
default_skills . append ( skill [ ' SkillId ' ] )
for skill in default_skills :
skill_info = await self . data . static . get_skill_by_id ( skill )
skill_slot = skill_info [ ' Level ' ] - 1
if now_have_skills [ skill_slot ] is not None :
now_have_skills [ skill ]
return now_have_skills
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_noop ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
return SaoNoopResponse ( header . cmd + 1 ) . make ( )
2024-01-10 17:51:40 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c000 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#ticket/ticket
req = SaoTicketRequest ( header , request )
return SaoTicketResponse ( ) . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c100 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
2023-05-26 17:45:20 +00:00
#common/get_app_versions
2024-06-25 18:02:53 +00:00
resp = SaoGetAppVersionsResponse ( )
resp . data_list . append ( AppVersionData . from_args ( self . game_cfg . server . game_version , datetime . fromtimestamp ( 0 ) ) )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c102 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
2023-05-26 17:45:20 +00:00
#common/master_data_version_check
2024-06-25 18:02:53 +00:00
req = SaoMasterDataVersionCheckRequest ( header , request )
self . logger . info ( f " Cab at { src_ip } checked in with master data v { req . current_data_version } " )
return SaoMasterDataVersionCheckResponse ( self . game_cfg . server . data_version , req . current_data_version ) . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c104 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#common/login
req = SaoLoginRequest ( header , request )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
user_id = await self . data . card . get_user_id_from_card ( req . access_code )
if not user_id :
card = await self . data . card . get_card_by_idm ( req . chip_id [ : 16 ] )
if card :
user_id = card [ ' user ' ]
card_id = card [ ' id ' ]
await self . data . card . set_access_code_by_access_code ( card [ ' access_code ' ] , req . access_code )
else :
user_id = await self . data . user . create_user ( ) #works
card_id = await self . data . card . create_card ( user_id , req . access_code )
if card_id is None :
user_id = - 1
self . logger . error ( " Failed to register card! " )
self . logger . info ( f " Registered card { req . access_code } to user { user_id } from { req . serial_no } " )
if req . access_code . startswith ( " 5 " ) :
await self . data . card . set_idm_by_access_code ( req . access_code , req . chip_id [ : 16 ] )
elif ( req . access_code . startswith ( " 010 " ) or req . access_code . startswith ( " 3 " ) ) and int ( req . chip_id [ : 8 ] , 16 ) != 0x04030201 :
await self . data . card . set_chip_id_by_access_code ( req . access_code , int ( req . chip_id [ : 8 ] , 16 ) )
profile_data = await self . data . profile . get_profile ( user_id )
if not profile_data :
profile_id = await self . data . profile . create_profile ( user_id )
if profile_id :
equip1 = await self . data . item . put_equipment ( user_id , 101000000 )
equip2 = await self . data . item . put_equipment ( user_id , 102000000 )
equip3 = await self . data . item . put_equipment ( user_id , 109000000 )
if not equip1 or not equip2 or not equip3 :
self . logger . error ( f " Failed to create profile for user { user_id } from { req . serial_no } (could not add equipment) " )
return SaoNoopResponse ( GameconnectCmd . LOGIN_RESPONSE ) . make ( )
hero1 = await self . data . item . put_hero_log ( user_id , 101000010 , 1 , 0 , equip1 , None , 1002 , 1003 , 1014 , None , None )
hero2 = await self . data . item . put_hero_log ( user_id , 102000010 , 1 , 0 , equip2 , None , 3001 , 3002 , 3004 , None , None )
hero3 = await self . data . item . put_hero_log ( user_id , 105000010 , 1 , 0 , equip3 , None , 10005 , 10002 , 10004 , None , None )
if not hero1 or not hero2 or not hero3 :
self . logger . error ( f " Failed to create profile for user { user_id } from { req . serial_no } (could not add heros) " )
return SaoNoopResponse ( GameconnectCmd . LOGIN_RESPONSE ) . make ( )
await self . data . item . put_hero_party ( user_id , 0 , hero1 , hero2 , hero3 )
self . logger . info ( f " Create profile { profile_id } for user { user_id } from { req . serial_no } " )
else :
self . logger . error ( f " Failed to create profile for user { user_id } from { req . serial_no } " )
return SaoNoopResponse ( GameconnectCmd . LOGIN_RESPONSE ) . make ( )
resp = SaoLoginResponse ( user_id , True , False )
else :
is_login_today = False
if profile_data [ ' last_login_date ' ] :
last_login_time = int ( profile_data [ " last_login_date " ] . timestamp ( ) )
midnight_today_ts = int (
datetime . now ( )
. replace ( hour = 0 , minute = 0 , second = 0 , microsecond = 0 )
. timestamp ( )
)
if last_login_time > midnight_today_ts :
is_login_today = True
if not is_login_today :
await self . data . profile . add_vp ( user_id , 100 )
resp = SaoLoginResponse ( user_id , profile_data [ ' login_ct ' ] < 1 , is_login_today )
await self . data . profile . user_login ( user_id )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c106 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/logout
req = SaoLogoutRequest ( header , request )
self . logger . info ( f " User { req . user_id } Logout from { ' game ' if req . cabinet_type == 0 else ' terminal ' } @ { src_ip } with { req . remaining_ticket_num } tickets remaining " )
return SaoNoopResponse ( GameconnectCmd . LOGOUT_RESPONSE ) . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c108 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/logout_ticket_unpurchased
req = SaoLogoutTicketUnpurchasedRequest ( header , request )
self . logger . info ( f " User { req . user_id } Logout from { ' game ' if req . cabinet_type == 0 else ' terminal ' } @ { src_ip } without buying a ticket " )
return SaoNoopResponse ( GameconnectCmd . LOGOUT_TICKET_UNPURCHASED_RESPONSE ) . make ( )
async def handle_c10a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/paying_play_start
req = SaoPayingPlayStartRequest ( header , request )
self . logger . info ( f " User { req . paying_user_id } started paying session @ { req . store_name } ( { src_ip } ) on cab { req . serial_no } " )
resp = SaoPayingPlayStartResponse ( )
# TODO: session management
return resp . make ( )
async def handle_c10c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/paying_play_end
req = SaoPayingPlayEndRequest ( header , request )
self . logger . info ( f " User { req . paying_user_id } ended paying session { req . paying_session_id } @ { req . store_name } ( { src_ip } ) on cab { req . serial_no } after { req . played_amount } { req . played_type } type games " )
return SaoNoopResponse ( GameconnectCmd . PAYING_PLAY_END_RESPONSE ) . make ( )
async def handle_c10e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/purchase_ticket
req = SaoPurchaseTicketRequest ( header , request )
self . logger . info ( f " User { req . user_id } pruchased { req . purchase_num } tickets (ID { req . ticket_id } ) @ { src_ip } with discout type { req . discount_type } " )
return SaoNoopResponse ( GameconnectCmd . PURCHASE_TICKET_RESPONSE ) . make ( )
async def handle_c110 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/consume_ticket
req = SaoConsumeTicketRequest ( header , request )
self . logger . info ( f " User { req . user_id } consumed { req . consume_num } tickets (ID { req . ticket_id } ) @ { src_ip } with discout type { req . discount_type } on { req . act_type } " )
return SaoNoopResponse ( GameconnectCmd . CONSUME_TICKET_RESPONSE ) . make ( )
async def handle_c112 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/add_credit
req = SaoAddCreditRequest ( header , request )
self . logger . info ( f " User { req . user_id } added { req . add_num } credits to a { ' game ' if req . cabinet_type == 0 else ' terminal ' } @ { src_ip } " )
return SaoNoopResponse ( GameconnectCmd . ADD_CREDIT_RESPONSE ) . make ( )
async def handle_c114 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/consume_credit
req = SaoConsumeCreditRequest ( header , request )
self . logger . info ( f " User { req . user_id } consumed { req . consume_num } credits on a { ' game ' if req . cabinet_type == 0 else ' terminal ' } @ { req . store_id } ( { src_ip } ) on { req . act_type } " )
return SaoNoopResponse ( GameconnectCmd . CONSUME_CREDIT_RESPONSE ) . make ( )
async def handle_c116 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/purchase_ticket_guest
req = SaoPurchaseTicketGuestRequest ( header , request )
self . logger . info ( f " Guest purchased { req . purchase_num } tickets on a { ' game ' if req . cabinet_type == 0 else ' terminal ' } @ { req . store_id } ( { src_ip } | SN { req . serial_no } ) " )
return SaoNoopResponse ( GameconnectCmd . PURCHASE_TICKET_GUEST_RESPONSE ) . make ( )
async def handle_c118 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/consume_ticket_guest
req = SaoConsumeTicketGuestRequest ( header , request )
self . logger . info ( f " Guest consumed { req . consume_num } tickets @ { req . store_id } ( { src_ip } | SN { req . serial_no } ) with discout type { req . discount_type } on { req . act_type } " )
return SaoNoopResponse ( GameconnectCmd . CONSUME_TICKET_GUEST_RESPONSE ) . make ( )
async def handle_c11a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/add_credit_guest
req = SaoAddCreditGuestRequest ( header , request )
self . logger . info ( f " Guest added { req . add_num } credits to a { ' game ' if req . cabinet_type == 0 else ' terminal ' } @ { req . store_id } ( { src_ip } | SN { req . serial_no } ) " )
return SaoNoopResponse ( GameconnectCmd . ADD_CREDIT_GUEST_RESPONSE ) . make ( )
async def handle_c11c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/consume_credit_guest
req = SaoConsumeCreditGuestRequest ( header , request )
self . logger . info ( f " Guest consumed { req . consume_num } credits on a { ' game ' if req . cab_type == 0 else ' terminal ' } @ { req . shop_id } ( { src_ip } | SN { req . serial_num } ) on { req . act_type } " )
return SaoNoopResponse ( GameconnectCmd . CONSUME_CREDIT_GUEST_RESPONSE ) . make ( )
async def handle_c11e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
2023-05-26 17:45:20 +00:00
#common/get_auth_card_data
2023-11-10 04:29:06 +00:00
req = SaoGetAuthCardDataRequest ( header , request )
2023-05-26 17:45:20 +00:00
#Check authentication
2024-06-25 18:02:53 +00:00
card = await self . data . card . get_card_by_access_code ( req . access_code )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
if not card :
card = await self . data . card . get_card_by_idm ( req . chip_id [ : 16 ] )
if not card :
self . logger . info ( f " Unregistered card { req . access_code } authenticated from { req . serial_no } " )
return SaoGetAuthCardDataResponse ( " NEW PLAYER " , 0 ) . make ( )
await self . data . card . set_access_code_by_access_code ( card [ ' access_code ' ] , req . access_code )
else :
user_id = card [ ' user ' ]
card_id = card [ ' id ' ]
if req . access_code . startswith ( " 5 " ) and not card [ ' idm ' ] :
2024-06-22 04:47:12 +00:00
await self . data . card . set_idm_by_access_code ( card_id , req . chip_id [ : 16 ] )
2024-06-25 18:02:53 +00:00
elif ( req . access_code . startswith ( " 010 " ) or req . access_code . startswith ( " 3 " ) ) and not card [ ' chip_id ' ] and int ( req . chip_id [ : 8 ] , 16 ) != 0x04030201 :
2024-06-22 04:47:12 +00:00
await self . data . card . set_chip_id_by_access_code ( card_id , int ( req . chip_id [ : 8 ] , 16 ) )
2024-06-25 18:02:53 +00:00
self . logger . info ( f " User Authenticated from { req . serial_no } : { req . access_code } | { user_id } " )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
#Grab values from profile
profile_data = await self . data . profile . get_profile ( user_id )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
if not profile_data :
self . logger . info ( f " Unregistered user { user_id } with card { req . access_code } authenticated from { req . serial_no } " )
return SaoGetAuthCardDataResponse ( " NEW PLAYER " , user_id ) . make ( )
return SaoGetAuthCardDataResponse ( profile_data [ ' nick_name ' ] , user_id ) . make ( )
async def handle_c120 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/get_access_code_by_keitai
req = SaoGetAccessCodeByKeitaiRequest ( header , request )
cid = req . chip_id
idm = cid [ : 16 ]
pmm = cid [ 16 : ]
card = await self . data . card . get_card_by_idm ( idm )
# If we don't have that card saved locally, check aimedb
if not card :
# Validate that we're talking to a phone
if not int ( pmm [ 2 : 4 ] , 16 ) in self . data . card . moble_os_codes :
self . logger . warn ( f " { req . serial_no } looked up non-moble chip ID { cid } ! " )
return SaoGetAccessCodeByKeitaiResponse ( " " ) . make ( )
# TODO: Actual felica moble registration
return SaoGetAccessCodeByKeitaiResponse ( " " ) . make ( )
#ac = await self.data.card.register_felica_moble_ac(idm, pmm)
# if we didn't get an access code, fail hard
if not ac :
self . logger . warn ( f " Failed to register access code for chip ID { cid } requested by { req . serial_no } " )
return SaoGetAccessCodeByKeitaiResponse ( " " ) . make ( )
self . logger . info ( f " Successfully registered moble felica access code { ac } for chip ID { cid } requested by { req . serial_no } " )
uid = await self . data . user . create_user ( )
if not uid :
self . logger . error ( f " Failed to create user for chip ID { cid } (access code { ac } ) @ LoadAccessCode request from { req . serial_no } " )
return SaoGetAccessCodeByKeitaiResponse ( " " ) . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
cardid = await self . data . card . create_card ( uid , ac )
if not cardid :
self . logger . error ( f " Failed to create card for user { uid } with chip ID { cid } (access code { ac } ) @ LoadAccessCode request from { req . serial_no } " )
await self . data . user . delete_user ( uid )
return SaoGetAccessCodeByKeitaiResponse ( " " ) . make ( )
self . logger . info ( f " Moble Felica access code lookup for { cid } -> { ac } (user { uid } ) requested by { req . serial_no } " )
else :
ac = card [ ' access_code ' ]
uid = card [ ' user ' ]
self . logger . info ( f " Moble Felica access code for { cid } -> { ac } (user { uid } ) requested by { req . serial_no } " )
return SaoGetAccessCodeByKeitaiResponse ( ac ) . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c122 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#common/get_maintenance_info
resp = SaoGetMaintenanceInfoResponse ( )
return resp . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c124 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#common/get_resource_path_info
resp = SaoGetResourcePathInfoResponse ( f " https:// { self . core_cfg . server . hostname } /saoresource/ " )
return resp . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c126 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/validation_error_notification
req = SaoValidationErrorNotificationRequest ( header , request )
self . logger . warn ( f " User { req . user_id } on { ' game ' if req . cabinet_type == 0 else ' terminal ' } { req . serial_no } @ { req . store_name } ( { src_ip } | Place ID { req . place_id } ) " \
+ f " Validation error: { req . send_protocol_name } || { req . send_data_to_fraud_value } || { req . send_data_to_modification_value } " )
return SaoNoopResponse ( GameconnectCmd . VALIDATION_ERROR_NOTIFICATION_RESPONSE ) . make ( )
async def handle_c128 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/power_cutting_return_notification
req = SaoPowerCuttingReturnNotification ( header , request )
self . logger . warn ( f " User { req . user_id } on { ' game ' if req . cabinet_type == 0 else ' terminal ' } { req . serial_no } @ { req . store_name } ( { src_ip } | Place ID { req . place_id } ) " \
+ f " Power outage return: Act Type { req . last_act_type } || { req . remaining_ticket_num } Remaining Tickets || { req . remaining_credit_num } Remaining Credits " )
return SaoNoopResponse ( GameconnectCmd . POWER_CUTTING_RETURN_NOTIFICATION_RESPONSE ) . make ( )
async def handle_c12a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#common/give_free_ticket
req = SaoGiveFreeTicketRequest ( header , request )
self . logger . info ( f " Give { req . give_num } free tickets (id { req . ticket_id } ) to user { req . user_id } " )
resp = SaoNoopResponse ( GameconnectCmd . GIVE_FREE_TICKET_RESPONSE )
return resp . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c12c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# common/matching_error_notification
req = SaoMatchingErrorNotificationRequest ( header , request )
self . logger . warn ( f " { ' game ' if req . cabinet_type == 0 else ' terminal ' } { req . serial_no } @ { req . store_name } ( { src_ip } | Place ID { req . place_id } ) " \
+ f " Matching error: { req . matching_error_data_list [ 0 ] } " )
return SaoNoopResponse ( GameconnectCmd . MATCHING_ERROR_NOTIFICATION_RESPONSE ) . make ( )
async def handle_c12e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#common/ac_cabinet_boot_notification
req = SaoCommonAcCabinetBootNotificationRequest ( header , request )
if req . current_version_app_id < self . game_cfg . server . game_version :
self . logger . info ( f " !!OUTDATED!! { ' Game ' if req . cabinet_type == 0 else ' Terminal ' } { req . serial_no } Booted v { req . current_version_app_id } (Master data v { req . current_master_data_version } ): { req . store_name } ( { src_ip } | Place/Shop ID { req . place_id } / { req . store_id } ) " )
if req . current_version_app_id > self . game_cfg . server . game_version :
self . logger . info ( f " !!TOO NEW!! { ' Game ' if req . cabinet_type == 0 else ' Terminal ' } { req . serial_no } Booted v { req . current_version_app_id } (Master data v { req . current_master_data_version } ): { req . store_name } ( { src_ip } | Place/Shop ID { req . place_id } / { req . store_id } ) " )
self . logger . info ( f " { ' Game ' if req . cabinet_type == 0 else ' Terminal ' } { req . serial_no } Booted v { req . current_version_app_id } (Master data v { req . current_master_data_version } ): { req . store_name } ( { src_ip } | Place/Shop ID { req . place_id } / { req . store_id } ) " )
resp = SaoNoopResponse ( GameconnectCmd . AC_CABINET_BOOT_NOTIFICATION_RESPONSE )
return resp . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c200 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# tutorial/first_tutorial_end
req = SaoGenericUserTicketRequest ( header , request )
self . logger . info ( f " User { req . user_id } (ticket { req . ticket_id } ) finished first tutorial " )
return SaoNoopResponse ( GameconnectCmd . FIRST_TUTORIAL_END_RESPONSE ) . make ( )
async def handle_c202 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# tutorial/various_tutorial_end
req = SaoVariousTutorialEndRequest ( header , request )
await self . data . profile . add_tutorial_byte ( int ( req . user_id ) , req . tutorial_type )
return SaoNoopResponse ( GameconnectCmd . VARIOUS_TUTORIAL_END_RESPONSE ) . make ( )
async def handle_c204 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# tutorial/get_various_tutorial_data_list
req = SaoGenericUserRequest ( header , request )
tuts = await self . data . profile . get_tutorial_bytes ( int ( req . user_id ) )
resp = SaoGetVariousTutorialDataListResponse ( )
if tuts :
for t in tuts :
resp . end_tutorial_type_list . append ( t [ ' tutorial_byte ' ] )
return resp . make ( )
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c300 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# card/discharge_profile_card
req = SaoDischargeProfileCardRequest ( header , request )
# Real cards seem to start with 10-17 as the first 2 digits, so we'll anchor ours with 2 to ensure no overlap
sn = f " 2 { str ( randint ( 1 , 999999999999999999 ) ) . zfill ( 18 ) } "
while await self . data . profile . get_hero_card ( sn ) :
sn = f " 2 { str ( randint ( 1 , 999999999999999999 ) ) . zfill ( 18 ) } "
resp = SaoDischargeProfileCardResponse ( sn )
db_hero = await self . data . item . get_hero_log ( req . user_id , req . hero_log_user_hero_log_id )
if not db_hero :
hero_statc = await self . data . static . get_hero_by_id ( db_hero [ ' hero_log_id ' ] )
if not hero_statc :
self . logger . error ( f " Failed to find hero log { db_hero [ ' hero_log_id ' ] } ! Please run the reader " )
resp . header . error_type = ProtocolErrorNum . RESOURCE_CARD_ERR1
return resp . make ( )
now_have_skills = await self . hero_default_skills ( hero_statc [ ' SkillTableSubId ' ] )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
db_hero_id = await self . data . item . put_hero_log (
req . user_id ,
db_hero [ ' hero_log_id ' ] ,
1 ,
0 ,
None ,
None ,
now_have_skills [ 0 ] ,
now_have_skills [ 1 ] ,
now_have_skills [ 2 ] ,
now_have_skills [ 3 ] ,
now_have_skills [ 4 ]
)
if not db_hero_id :
self . logger . error ( f " Failed to give user { req . user_id } hero { db_hero [ ' hero_log_id ' ] } ! " )
resp . header . error_type = ProtocolErrorNum . RESOURCE_CARD_ERR6
return resp . make ( )
else :
db_hero_id = db_hero [ ' id ' ]
await self . data . profile . put_hero_card ( req . user_id , sn , db_hero_id , req . holographic_flag )
self . logger . info ( f " User { req . user_id } printed { ' holo ' if req . holographic_flag == 1 else ' ' } profile card { req . hero_log_user_hero_log_id } { req . execute_print_type } , code { sn } " )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c302 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# card/discharge_resource_card
req = SaoDischargeResourceCardRequest ( header , request )
for x in req . common_reward_user_data :
sn = f " 2 { str ( randint ( 1 , 999999999999999999 ) ) . zfill ( 18 ) } "
self . logger . info ( f " User { req . user_id } printed { ' holo ' if req . holographic_flag == 1 else ' ' } resource card { x . user_common_reward_id } { req . execute_print_type } , code { sn } " )
await self . data . profile . put_resource_card ( req . user_id , sn , x . common_reward_type , x . user_common_reward_id , req . holographic_flag )
return SaoDischargeProfileCardResponse ( sn ) . make ( )
async def handle_c304 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# card/discharge_resource_card_complete
req = SaoDischargeResourceCardCompleteRequest ( header , request )
self . logger . info ( f " User { req . user_id } finished printing resource card { req . resource_card_code } " )
return SaoNoopResponse ( GameconnectCmd . DISCHARGE_RESOURCE_CARD_COMPLETE_RESPONSE ) . make ( )
async def handle_c306 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#card/scan_qr_quest_profile_card
req = SaoScanQrQuestProfileCardRequest ( header , request )
resp = SaoScanQrQuestProfileCardResponse ( )
card = await self . data . profile . get_hero_card ( req . profile_card_code )
if not card :
self . logger . warn ( f " User { req . user_id } scanned unregistered QR code { req . profile_card_code } " )
return resp . make ( )
hero = await self . data . item . get_hero_log_by_id ( card [ ' user_hero_id ' ] )
if not hero : # Shouldn't happen
self . logger . warn ( f " User { req . user_id } scanned QR code { req . profile_card_code } but does not have hero entry { card [ ' user_hero_id ' ] } " )
return resp . make ( )
hero_static_data = await self . data . static . get_hero_by_id ( hero [ ' hero_log_id ' ] )
if not hero_static_data : # Shouldn't happen
self . logger . warn ( f " No entry for hero { hero [ ' hero_log_id ' ] } , please run read.py " )
return resp . make ( )
profile = await self . data . profile . get_profile ( card [ ' user ' ] )
if not profile : # Shouldn't happen
self . logger . warn ( f " No profile for user { card [ ' user ' ] } , something broke " )
return resp . make ( )
self . logger . info ( f " User { req . user_id } scanned QR code { req . profile_card_code } " )
card_resp = ReadProfileCard . from_args ( req . profile_card_code , profile [ ' nick_name ' ] )
card_resp . rank_num = profile [ ' rank_num ' ]
card_resp . setting_title_id = profile [ ' setting_title_id ' ]
card_resp . skill_id = hero [ ' skill_slot1_skill_id ' ]
card_resp . hero_log_hero_log_id = hero [ ' hero_log_id ' ]
card_resp . hero_log_log_level = hero [ ' log_level ' ]
#TODO: Awakening
#card_resp.hero_log_awakening_stage = hero['log_level']
resp . profile_card_data . append ( card_resp )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c308 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# card/scan_qr_shop_resource_card
req = SaoScanQrShopResourceCardRequest ( header , request )
self . logger . info ( f " User { req . user_id } scanned shop resource card { req . resource_card_code } " )
resp = SaoNoopResponse ( GameconnectCmd . SCAN_QR_SHOP_RESOURCE_CARD_RESPONSE )
# On official, resource cards have limited uses, but we don't track that currently (tho we should)
card = await self . data . profile . get_resource_card ( req . resource_card_code ) # TODO: use count
if not card :
self . logger . warn ( f " No resource card with serial { req . resource_card_code } exists! " )
resp . header . err_status = 4832 # Theres a few error codes but none seem to do anything?
# Also not sure if it should be this or result
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
return resp . make ( )
async def handle_c30a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# card/scan_qr_quest_resource_card
req = SaoScanQrQuestResourceCardRequest ( header , request )
self . logger . info ( f " User { req . user_id } scanned quest resource card { req . resource_card_code } " )
card = await self . data . profile . get_resource_card ( req . resource_card_code )
if not card :
resp = SaoScanQrQuestResourceCardResponse ( card [ ' common_reward_type ' ] , card [ ' common_reward_id ' ] , card [ ' holographic_flag ' ] )
else :
self . logger . warn ( f " No resource card with serial { req . resource_card_code } exists! " )
resp = SaoScanQrQuestResourceCardResponse ( )
resp . header . err_status = 4832 # Theres a few error codes but none seem to do anything?
# Also not sure if it should be this or result
return resp . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_c400 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#home/check_yui_medal_get_condition
req = SaoCheckYuiMedalGetConditionRequest ( header , request )
profile = await self . data . profile . get_profile ( req . user_id )
if profile [ ' last_yui_medal_date ' ] :
last_check_ts = int ( profile [ ' last_yui_medal_date ' ] . timestamp ( ) )
day_ts = int ( datetime . now ( ) . replace ( hour = 0 , minute = 0 , second = 0 , microsecond = 0 ) . timestamp ( ) )
diff_ts = day_ts - last_check_ts
if diff_ts > 0 :
num_days = diff_ts / 86400
else :
num_days = 0
else :
num_days = 1
if num_days > 1 :
await self . data . profile . add_yui_medals ( req . user_id )
await self . data . profile . update_yui_medal_date ( req . user_id )
return SaoCheckYuiMedalGetConditionResponse ( num_days , 1 if num_days > 1 else 0 ) . make ( )
async def handle_c402 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#home/get_yui_medal_bonus_user_data
req = SaoGetYuiMedalBonusUserDataRequest ( header , request )
resp = SaoGetYuiMedalBonusUserDataResponse ( ) # TODO: Track yui login bonus
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c404 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# home/check_comeback_event
req = SaoGenericUserTicketRequest ( header , request )
resp = SaoCheckComebackEventResponse ( )
#resp.get_comeback_event_id_list += [1,2,3,4] # TODO: track comeback date
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c406 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# home/change_my_store
req = SaoChangeMyStoreRequest ( header , request )
self . logger . info ( f " User { req . user_id } changed My Store to { req . store_id } " )
shop_id = int ( req . store_id [ 3 : ] , 16 )
await self . data . profile . set_my_shop ( req . user_id , shop_id )
return SaoNoopResponse ( GameconnectCmd . CHANGE_MY_STORE_RESPONSE ) . make ( )
async def handle_c408 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# home/check_title_get_decision
req = SaoCheckTitleGetDecisionRequest ( header , request )
resp = SaoCheckTitleGetDecisionResponse ( ) # TODO: titles
return resp . make ( )
async def handle_c40a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# home/check_profile_card_used_reward
req = SaoCheckProfileCardUsedRewardRequest ( header , request )
resp = SaoCheckProfileCardUsedRewardResponse ( ) # TODO: check_profile_card_used_reward
return resp . make ( )
async def handle_c40c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# home/check_ac_login_bonus
req = SaoGenericUserTicketRequest ( header , request )
resp = SaoCheckAcLoginBonusResponse ( )
#resp.get_ac_login_bonus_id_list.append(1) # TODO: track login bonus date
#resp.get_ac_login_bonus_id_list.append(2)
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c500 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# user_info/get_user_basic_data
2023-11-10 04:29:06 +00:00
req = SaoGetUserBasicDataRequest ( header , request )
2023-06-24 16:29:28 +00:00
2024-01-22 21:45:09 +00:00
profile_data = await self . data . profile . get_profile ( req . user_id )
2024-06-25 18:02:53 +00:00
player_rank_data = self . load_data_csv ( " PlayerRank " )
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
resp = SaoGetUserBasicDataResponse ( profile_data )
for e in player_rank_data :
if resp . user_basic_data [ 0 ] . rank_num == int ( e [ ' PlayerRankId ' ] ) :
resp . user_basic_data [ 0 ] . rank_exp = resp . user_basic_data [ 0 ] . rank_exp - int ( e [ " TotalExp " ] )
break
if profile_data [ ' my_shop ' ] :
ac = await self . data . arcade . get_arcade ( profile_data [ ' my_shop ' ] )
if ac :
resp . user_basic_data [ 0 ] . my_store_name = ac [ ' name ' ]
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
return resp . make ( )
async def handle_c502 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# user_info/get_vp_gasha_ticket_data_list
req = SaoGetVpGashaTicketDataListRequest ( header , request )
# TODO: gasha tickets
resp = SaoGetVpGashaTicketDataListResponse ( )
return resp . make ( )
async def handle_c504 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# user_info/get_present_box_num
req = SaoGenericUserRequest ( header , request )
# TODO: presents
return SaoGetPresentBoxNumResponse ( ) . make ( )
async def handle_c600 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# have_object/get_hero_log_user_data_list
req = SaoGenericUserRequest ( header , request )
hero_level_data = self . load_data_csv ( " HeroLogLevel " )
2023-05-29 20:51:41 +00:00
2024-01-22 21:45:09 +00:00
hero_data = await self . data . item . get_hero_logs ( req . user_id )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
resp = SaoGetHeroLogUserDataListResponse ( )
for hero in hero_data :
append = HeroLogUserData . from_args ( hero )
hero_static = await self . data . static . get_hero_by_id ( hero [ ' hero_log_id ' ] )
if not hero_static :
self . logger . warn ( f " No hero for id { hero [ ' hero_log_id ' ] } , please run reader " )
resp . hero_log_user_data_list . append ( append )
continue
append . property1_property_id = hero_static [ ' Property1PropertyId ' ] if hero_static [ ' Property1PropertyId ' ] else 0
append . property1_value1 = hero_static [ ' Property1Value1 ' ] if hero_static [ ' Property1Value1 ' ] else 0
append . property1_value2 = hero_static [ ' Property1Value2 ' ] if hero_static [ ' Property1Value2 ' ] else 0
append . property2_property_id = hero_static [ ' Property2PropertyId ' ] if hero_static [ ' Property2PropertyId ' ] else 0
append . property2_value1 = hero_static [ ' Property2Value1 ' ] if hero_static [ ' Property2Value1 ' ] else 0
append . property2_value2 = hero_static [ ' Property2Value2 ' ] if hero_static [ ' Property2Value2 ' ] else 0
append . property3_property_id = hero_static [ ' Property3PropertyId ' ] if hero_static [ ' Property3PropertyId ' ] else 0
append . property3_value1 = hero_static [ ' Property3Value1 ' ] if hero_static [ ' Property3Value1 ' ] else 0
append . property3_value2 = hero_static [ ' Property3Value2 ' ] if hero_static [ ' Property3Value2 ' ] else 0
append . property4_property_id = hero_static [ ' Property4PropertyId ' ] if hero_static [ ' Property4PropertyId ' ] else 0
append . property4_value1 = hero_static [ ' Property4Value1 ' ] if hero_static [ ' Property4Value1 ' ] else 0
append . property4_value2 = hero_static [ ' Property4Value2 ' ] if hero_static [ ' Property4Value2 ' ] else 0
for e in hero_level_data :
if hero [ ' log_level ' ] == int ( e [ ' HeroLogLevelId ' ] ) :
append . log_exp = hero [ ' log_exp ' ] - int ( e [ " TotalExp " ] )
break
resp . hero_log_user_data_list . append ( append )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_c602 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# have_object/get_equipment_user_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetEquipmentUserDataListResponse ( )
equip_level_data = self . load_data_csv ( " EquipmentLevel " )
2023-05-30 22:03:52 +00:00
2024-01-22 21:45:09 +00:00
equipment_data = await self . data . item . get_user_equipments ( req . user_id )
2024-06-25 18:02:53 +00:00
if equipment_data :
for equipment in equipment_data :
e = EquipmentUserData . from_args ( equipment )
weapon_static = await self . data . static . get_equipment_by_id ( equipment [ ' equipment_id ' ] )
if not weapon_static :
self . logger . warn ( f " No equipment for id { equipment [ ' equipment_id ' ] } , please run reader " )
resp . equipment_user_data_list . append ( e )
continue
if not e . property1_property_id :
e . property1_property_id = weapon_static [ ' Property1PropertyId ' ] if weapon_static [ ' Property1PropertyId ' ] else 0
e . property1_value1 = weapon_static [ ' Property1Value1 ' ] if weapon_static [ ' Property1Value1 ' ] else 0
e . property1_value2 = weapon_static [ ' Property1Value2 ' ] if weapon_static [ ' Property1Value2 ' ] else 0
if not e . property2_property_id :
e . property2_property_id = weapon_static [ ' Property2PropertyId ' ] if weapon_static [ ' Property2PropertyId ' ] else 0
e . property2_value1 = weapon_static [ ' Property2Value1 ' ] if weapon_static [ ' Property2Value1 ' ] else 0
e . property2_value2 = weapon_static [ ' Property2Value2 ' ] if weapon_static [ ' Property2Value2 ' ] else 0
if e . property3_property_id :
e . property3_property_id = weapon_static [ ' Property3PropertyId ' ] if weapon_static [ ' Property3PropertyId ' ] else 0
e . property3_value1 = weapon_static [ ' Property3Value1 ' ] if weapon_static [ ' Property3Value1 ' ] else 0
e . property3_value2 = weapon_static [ ' Property3Value2 ' ] if weapon_static [ ' Property3Value2 ' ] else 0
if e . property4_property_id :
e . property4_property_id = weapon_static [ ' Property4PropertyId ' ] if weapon_static [ ' Property4PropertyId ' ] else 0
e . property4_value1 = weapon_static [ ' Property4Value1 ' ] if weapon_static [ ' Property4Value1 ' ] else 0
e . property4_value2 = weapon_static [ ' Property4Value2 ' ] if weapon_static [ ' Property4Value2 ' ] else 0
for f in equip_level_data :
if equipment [ ' enhancement_value ' ] == int ( f [ ' EquipmentLevelId ' ] ) :
e . enhancement_exp = equipment [ ' enhancement_exp ' ] - int ( f [ " TotalExp " ] )
break
resp . equipment_user_data_list . append ( e )
return resp . make ( )
async def handle_c604 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# have_object/get_item_user_data_list
req = SaoGenericUserRequest ( header , request )
item_data = await self . data . item . get_user_items ( req . user_id )
resp = SaoGetItemUserDataListResponse ( item_data )
return resp . make ( )
async def handle_c606 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# have_object/get_support_log_user_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetSupportLogUserDataListResponse ( )
supports = self . load_data_csv ( " SupportLog " )
# TODO: Save supports
for x in range ( len ( supports ) ) :
tmp = SupportLogUserData . from_args ( f " { req . user_id } { x } " , supports [ x ] [ ' SupportLogId ' ] )
resp . support_log_user_data_list . append ( tmp )
return resp . make ( )
async def handle_c608 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#have_object/get_episode_append_data_list
req = SaoGenericUserRequest ( header , request )
# TODO: Appends
resp = SaoGetEpisodeAppendDataListResponse ( )
return resp . make ( )
async def handle_c60a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# have_object/get_event_item_data_list
req = SaoGenericUserRequest ( header , request )
res = SaoGetEventItemDataListResponse ( )
# TODO: Event items maybe
return res . make ( )
async def handle_c60c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# have_object/get_gasha_medal_user_data_list
req = SaoGenericUserRequest ( header , request )
res = SaoGetGashaMedalUserDataListResponse ( )
# TODO: Gasha Medal data
return res . make ( )
async def handle_c700 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# shop/get_shop_resource_sales_data_list
# TODO: Get user shop data
req = SaoGenericUserRequest ( header , request )
resp = SaoGetShopResourceSalesDataListResponse ( )
return resp . make ( )
async def handle_c702 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# shop/purchase_shop_resource
req = SaoPurchaseShopResourceRequest ( header , request )
self . logger . infof ( f " User { req . user_id } (ticket { req . ticket_id } ) purchased shop resourse { req . user_shop_resource_id } " )
# TODO: Shop purchases
return SaoNoopResponse ( GameconnectCmd . PURCHASE_SHOP_RESOURCE_RESPONSE ) . make ( )
async def handle_c704 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# shop/discard_shop_resource
req = SaoPurchaseShopResourceRequest ( header , request )
self . logger . infof ( f " User { req . user_id } (ticket { req . ticket_id } ) discarded shop resourse { req . user_shop_resource_id } " )
return SaoNoopResponse ( GameconnectCmd . DISCARD_SHOP_RESOURCE_RESPONSE ) . make ( )
async def handle_c800 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# custom/get_title_user_data_list
req = SaoGenericUserRequest ( header , request )
titleIdsData = await self . data . static . get_title_ids ( 0 , True )
# TODO: Save titles
resp = SaoGetTitleUserDataListResponse ( req . user_id , titleIdsData )
return resp . make ( )
async def handle_c802 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# custom/change_title
req = SaoChangeTitleRequest ( header , request )
self . logger . info ( f " User { req . user_id } (ticket { req . ticket_id } ) changed their title to { req . user_title_id } " )
await self . data . profile . set_title ( req . user_id , req . user_title_id )
return SaoNoopResponse ( GameconnectCmd . CHANGE_TITLE_RESPONSE ) . make ( )
async def handle_c804 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# custom/get_party_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetPartyDataListResponse ( )
hero_parties = await self . data . item . get_hero_party ( req . user_id )
for party in hero_parties :
hero1_data = await self . data . item . get_user_hero_by_id ( party [ ' user_hero_log_id_1 ' ] )
hero2_data = await self . data . item . get_user_hero_by_id ( party [ ' user_hero_log_id_2 ' ] )
hero3_data = await self . data . item . get_user_hero_by_id ( party [ ' user_hero_log_id_3 ' ] )
resp . party_data_list . append ( PartyData . from_args ( party [ ' id ' ] , party [ ' user_party_team_id ' ] , hero1_data . _asdict ( ) , hero2_data . _asdict ( ) , hero3_data . _asdict ( ) ) )
return resp . make ( )
async def handle_c808 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# custom/get_support_log_party_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetSupportLogPartyDataListResponse ( )
# TODO: Support logs
return resp . make ( )
async def handle_c812 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# custom/disposal_resource
req = SaoDisposalResourceRequest ( header , request )
get_col = 0
for disposal in req . disposal_common_reward_user_data_list :
if disposal . common_reward_type == RewardType . HeroLog :
removed_hero = await self . data . item . remove_hero_log ( disposal . user_common_reward_id )
if removed_hero :
static_hero = await self . data . static . get_hero_by_id ( removed_hero )
get_col + = static_hero [ ' SalePrice ' ]
elif disposal . common_reward_type == RewardType . Equipment :
removed_equip = await self . data . item . remove_equipment ( disposal . user_common_reward_id )
if removed_equip :
static_equip = await self . data . static . get_equipment_by_id ( removed_equip )
get_col + = static_equip [ ' SalePrice ' ]
elif disposal . common_reward_type == RewardType . Item :
removed_equip = await self . data . item . remove_item ( disposal . user_common_reward_id )
if removed_equip :
static_equip = await self . data . static . get_equipment_by_id ( removed_equip )
get_col + = static_equip [ ' SalePrice ' ]
elif disposal . common_reward_type == RewardType . SupportLog :
continue
else :
self . logger . warn ( f " Unhandled disposal type { disposal . common_reward_type } " )
await self . data . profile . add_col ( req . user_id , get_col )
return SaoDisposalResourceResponse ( get_col ) . make ( )
async def handle_c814 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#custom/synthesize_enhancement_hero_log
req = SaoSynthesizeEnhancementHeroLogRequest ( header , request )
resp = SaoSynthesizeEnhancementHeroLogResponse ( )
hero_level_data = self . load_data_csv ( " HeroLogLevel " )
equip_level_data = self . load_data_csv ( " EquipmentLevel " )
hero_exp = 0
col_cost = 0
for x in req . material_common_reward_user_data_list :
if x . common_reward_type == RewardType . Item :
user_item = await self . data . item . get_user_item_by_id ( x . user_common_reward_id )
static_item = await self . data . static . get_item_id ( user_item [ ' item_id ' ] )
if int ( static_item [ ' ItemTypeId ' ] ) == 7 :
hero_exp + = int ( static_item [ ' Value ' ] )
self . logger . info ( f " Remove item { x . user_common_reward_id } and add { int ( static_item [ ' Value ' ] ) } XP (running { hero_exp } ) " )
await self . data . item . remove_item ( x . user_common_reward_id )
elif x . common_reward_type == RewardType . Equipment :
equipment_data = await self . data . item . get_user_equipment_by_id ( x . user_common_reward_id )
if equipment_data is None :
self . logger . error ( f " Failed to find equipment { x . user_common_reward_id } for user { req . user_id } ! " )
continue
req_exp = 0
for e in range ( len ( equip_level_data ) ) :
if equipment_data [ ' enhancement_value ' ] == int ( equip_level_data [ e ] [ ' EquipmentLevelId ' ] ) :
req_exp = equip_level_data [ e + 1 ] [ ' RequireExp ' ]
break
static_equip_data = await self . data . static . get_equipment_by_id ( equipment_data [ ' equipment_id ' ] )
hero_exp + = int ( static_equip_data [ ' CompositionExp ' ] ) + req_exp
self . logger . info ( f " Remove equipment { x . user_common_reward_id } and add { int ( static_equip_data [ ' CompositionExp ' ] ) + req_exp } XP (running { hero_exp } ) " )
await self . data . item . remove_equipment ( x . user_common_reward_id )
elif x . common_reward_type == RewardType . HeroLog :
hero_data = await self . data . item . get_hero_log_by_id ( x . user_common_reward_id )
if hero_data is None :
self . logger . error ( f " Failed to find hero { x . user_common_reward_id } for user { req . user_id } ! " )
continue
req_exp = 0
for e in range ( len ( hero_level_data ) ) :
if hero_data [ ' log_level ' ] == int ( hero_level_data [ e ] [ ' HeroLogLevelId ' ] ) :
req_exp = hero_level_data [ e + 1 ] [ ' RequireExp ' ]
break
static_hero_data = await self . data . static . get_hero_by_id ( hero_data [ ' hero_log_id ' ] )
hero_exp + = int ( static_hero_data [ ' CompositionExp ' ] ) + req_exp
self . logger . info ( f " Remove hero { x . user_common_reward_id } and add { int ( static_hero_data [ ' CompositionExp ' ] ) + req_exp } XP (running { hero_exp } ) " )
await self . data . item . remove_hero_log ( x . user_common_reward_id )
else :
self . logger . warn ( f " Unhandled ype { x . common_reward_type } ! (running { hero_exp } ) " )
hero_exp = int ( hero_exp * 1.5 )
await self . data . item . add_hero_xp ( req . origin_user_hero_log_id , hero_exp )
log_exp = await self . data . item . get_hero_xp ( req . origin_user_hero_log_id )
pre_synth_xp = log_exp - hero_exp
pre_synth_level = 1
for e in range ( len ( hero_level_data ) ) :
if log_exp > = int ( hero_level_data [ e ] [ " TotalExp " ] ) and log_exp < int ( hero_level_data [ e + 1 ] [ " TotalExp " ] ) :
self . logger . info ( f " Set hero { req . origin_user_hero_log_id } level { hero_level_data [ e ] [ ' HeroLogLevelId ' ] } " )
remain_exp = log_exp - int ( hero_level_data [ e ] [ " TotalExp " ] )
await self . data . item . set_hero_level ( req . origin_user_hero_log_id , hero_level_data [ e ] [ " HeroLogLevelId " ] )
break
for e in range ( len ( hero_level_data ) ) :
if pre_synth_xp > = int ( hero_level_data [ e ] [ " TotalExp " ] ) and pre_synth_xp < int ( hero_level_data [ e + 1 ] [ " TotalExp " ] ) :
pre_synth_level = int ( hero_level_data [ e ] [ " HeroLogLevelId " ] )
break
# Load the item again to push to the response handler
synthesize_hero_log_data = await self . data . item . get_hero_log_by_id ( req . origin_user_hero_log_id )
col_cost = pre_synth_level * ( 100 * len ( req . material_common_reward_user_data_list ) ) * ( 1 - synthesize_hero_log_data [ ' awakening_stage ' ] * 0.1 )
if pre_synth_level > = 100 :
col_cost = col_cost * 10
col_cost = col_cost * 1000
col_cost = max ( 100 , int ( col_cost / 1000 ) )
self . logger . info ( f " Synthesize { hero_exp } exp for hero { req . origin_user_hero_log_id } , costing { col_cost } col " )
await self . data . profile . add_col ( req . user_id , - col_cost )
if synthesize_hero_log_data is not None :
resp . after_hero_log_user_data . append ( HeroLogUserData . from_args ( synthesize_hero_log_data ) )
resp . after_hero_log_user_data [ 0 ] . log_exp = remain_exp
return resp . make ( )
async def handle_c816 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#custom/synthesize_enhancement_equipment
req_data = SaoSynthesizeEnhancementEquipmentRequest ( header , request )
resp = SaoSynthesizeEnhancementEquipmentResponse ( )
hero_level_data = self . load_data_csv ( " HeroLogLevel " )
equip_level_data = self . load_data_csv ( " EquipmentLevel " )
equipment_exp = 0
col_cost = 0
for x in req_data . material_common_reward_user_data_list :
if x . common_reward_type == RewardType . Item :
user_item = await self . data . item . get_user_item_by_id ( x . user_common_reward_id )
static_item = await self . data . static . get_item_id ( user_item [ ' item_id ' ] )
if int ( static_item [ ' ItemTypeId ' ] ) == 7 :
equipment_exp + = int ( static_item [ ' Value ' ] )
self . logger . info ( f " Remove item { x . user_common_reward_id } and add { int ( static_item [ ' Value ' ] ) } XP (running { equipment_exp } ) " )
await self . data . item . remove_item ( x . user_common_reward_id )
elif x . common_reward_type == RewardType . Equipment :
equipment_data = await self . data . item . get_user_equipment_by_id ( x . user_common_reward_id )
if equipment_data is None :
self . logger . error ( f " Failed to find equipment { x . user_common_reward_id } for user { req_data . user_id } ! " )
continue
req_exp = 0
for e in range ( len ( equip_level_data ) ) :
if equipment_data [ ' enhancement_value ' ] == int ( equip_level_data [ e ] [ ' EquipmentLevelId ' ] ) :
req_exp = equip_level_data [ e + 1 ] [ ' RequireExp ' ]
break
static_equip_data = await self . data . static . get_equipment_by_id ( equipment_data [ ' equipment_id ' ] )
equipment_exp + = int ( static_equip_data [ ' CompositionExp ' ] ) + req_exp
self . logger . info ( f " Remove equipment { x . user_common_reward_id } and add { int ( static_equip_data [ ' CompositionExp ' ] ) + req_exp } XP (running { equipment_exp } ) " )
await self . data . item . remove_equipment ( x . user_common_reward_id )
elif x . common_reward_type == RewardType . HeroLog :
hero_data = await self . data . item . get_hero_log_by_id ( x . user_common_reward_id )
if hero_data is None :
self . logger . error ( f " Failed to find hero { x . user_common_reward_id } for user { req_data . user_id } ! " )
continue
req_exp = 0
for e in range ( len ( hero_level_data ) ) :
if hero_data [ ' log_level ' ] == int ( hero_level_data [ e ] [ ' HeroLogLevelId ' ] ) :
req_exp = hero_level_data [ e + 1 ] [ ' RequireExp ' ]
break
static_hero_data = await self . data . static . get_hero_by_id ( hero_data [ ' hero_log_id ' ] )
equipment_exp + = int ( static_hero_data [ ' CompositionExp ' ] ) + req_exp
self . logger . info ( f " Remove hero { x . user_common_reward_id } and add { int ( static_hero_data [ ' CompositionExp ' ] ) + req_exp } XP (running { equipment_exp } ) " )
await self . data . item . remove_hero_log ( x . user_common_reward_id )
else :
self . logger . warn ( f " Unhandled ype { x . common_reward_type } ! (running { equipment_exp } ) " )
equipment_exp = int ( equipment_exp * 1.5 )
await self . data . item . add_equipment_enhancement_exp ( req_data . origin_user_equipment_id , equipment_exp )
synthesize_equipment_data = await self . data . item . get_user_equipment ( req_data . user_id , req_data . origin_user_equipment_id )
equip_exp_new = synthesize_equipment_data [ ' enhancement_exp ' ]
pre_synth_level = synthesize_equipment_data [ ' enhancement_value ' ]
new_synth_level = 1
for e in range ( len ( equip_level_data ) ) :
if equip_exp_new > = int ( equip_level_data [ e ] [ " TotalExp " ] ) and equip_exp_new < int ( equip_level_data [ e + 1 ] [ " TotalExp " ] ) :
self . logger . info ( f " Set equipment { req_data . origin_user_equipment_id } level { equip_level_data [ e ] [ ' EquipmentLevelId ' ] } " )
new_synth_level = equip_level_data [ e ] [ ' EquipmentLevelId ' ]
remain_exp = equip_exp_new - int ( equip_level_data [ e ] [ " TotalExp " ] )
await self . data . item . set_equipment_enhancement_value ( req_data . origin_user_equipment_id , equip_level_data [ e ] [ " EquipmentLevelId " ] )
break
# Load the item again to push to the response handler
col_cost = pre_synth_level * ( 100 * len ( req_data . material_common_reward_user_data_list ) ) * ( 1 - synthesize_equipment_data [ ' awakening_stage ' ] * 0.1 )
if pre_synth_level > = 100 :
col_cost = col_cost * 10
col_cost = col_cost * 1000
col_cost = max ( 100 , int ( col_cost / 1000 ) )
self . logger . info ( f " Synthesize { equipment_exp } exp for equipment { req_data . origin_user_equipment_id } , costing { col_cost } col " )
await self . data . profile . add_col ( req_data . user_id , - col_cost )
if synthesize_equipment_data is not None :
resp . after_equipment_user_data . append ( EquipmentUserData . from_args ( synthesize_equipment_data ) )
resp . after_equipment_user_data [ 0 ] . enhancement_exp = remain_exp
resp . after_equipment_user_data [ 0 ] . enhancement_value = new_synth_level
return resp . make ( )
async def handle_c806 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#custom/change_party
req_data = SaoChangePartyRequest ( header , request )
for party_team in req_data . party_data_list :
for hero in party_team . party_team_data_list :
await self . data . item . set_user_hero_weapons (
int ( hero . user_hero_log_id ) ,
int ( hero . main_weapon_user_equipment_id ) if hero . main_weapon_user_equipment_id and int ( hero . main_weapon_user_equipment_id ) > 0 else None ,
int ( hero . sub_equipment_user_equipment_id ) if hero . sub_equipment_user_equipment_id and int ( hero . sub_equipment_user_equipment_id ) > 0 else None
)
await self . data . item . set_user_hero_skills (
int ( hero . user_hero_log_id ) ,
hero . skill_slot1_skill_id if hero . skill_slot1_skill_id > 0 else None ,
hero . skill_slot2_skill_id if hero . skill_slot2_skill_id > 0 else None ,
hero . skill_slot3_skill_id if hero . skill_slot3_skill_id > 0 else None ,
hero . skill_slot4_skill_id if hero . skill_slot4_skill_id > 0 else None ,
hero . skill_slot5_skill_id if hero . skill_slot5_skill_id > 0 else None
)
await self . data . item . put_hero_party (
req_data . user_id ,
party_team . team_no ,
party_team . party_team_data_list [ 0 ] . user_hero_log_id ,
party_team . party_team_data_list [ 1 ] . user_hero_log_id ,
party_team . party_team_data_list [ 2 ] . user_hero_log_id ,
)
resp = SaoNoopResponse ( GameconnectCmd . CHANGE_PARTY_RESPONSE )
return resp . make ( )
async def handle_c900 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#quest/get_quest_scene_user_data_list
req = SaoGenericUserRequest ( header , request )
quest_data = await self . data . item . get_quest_logs ( req . user_id )
resp = SaoGetQuestSceneUserDataListResponse ( )
for quest in quest_data :
ex_bonus_data = await self . data . item . get_player_ex_bonus_by_quest ( req . user_id , quest [ " quest_scene_id " ] )
tmp = QuestSceneUserData . from_args ( quest )
for ex_bonus in ex_bonus_data :
tmp . quest_scene_ex_bonus_user_data_list . append ( QuestSceneExBonusUserData . from_args ( ex_bonus [ ' ex_bonus_table_id ' ] , ex_bonus [ ' quest_clear_flag ' ] ) )
resp . quest_scene_user_data_list . append ( tmp )
return resp . make ( )
async def handle_c902 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes : # for whatever reason, having all entries empty or filled changes nothing
#quest/get_quest_scene_prev_scan_profile_card
resp = SaoGetQuestScenePrevScanProfileCardResponse ( )
resp . profile_card_data . append ( ReadProfileCardData . from_args ( { } , { } ) )
return resp . make ( )
async def handle_c904 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#quest/episode_play_start
req_data = SaoEpisodePlayStartRequest ( header , request )
user_id = req_data . user_id
profile_data = await self . data . profile . get_profile ( user_id )
sesh_id = await self . data . item . create_session (
user_id ,
int ( req_data . play_start_request_data [ 0 ] . user_party_id ) ,
req_data . episode_id ,
req_data . play_mode ,
req_data . play_start_request_data [ 0 ] . quest_drop_boost_apply_flag
)
resp = SaoEpisodePlayStartResponse ( )
resp . play_start_response_data . append ( QuestScenePlayStartResponseData . from_args ( sesh_id , profile_data [ ' nick_name ' ] ) )
resp . multi_play_start_response_data . append ( QuestSceneMultiPlayStartResponseData . from_args ( ) )
return resp . make ( )
async def handle_c908 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes : # Level calculation missing for the profile and heroes
#quest/episode_play_end
req_data = SaoEpisodePlayEndRequest ( header , request )
resp = SaoEpisodePlayEndResponse ( )
user_id = req_data . user_id
episode_id = req_data . episode_id
play_end = req_data . play_end_request_data [ 0 ]
base_get_data = play_end . base_get_data [ 0 ]
score_data = play_end . score_data [ 0 ]
exp = 0
cleared_mission_ct = 0
highest_mission_diff_cleared = 0
num_monsters_defeated = 0
monsters_defeated_data = { }
json_data = { " data " : [ ] }
ep_data = await self . data . static . get_episode_by_id ( req_data . episode_id )
quest_scene = await self . data . static . get_quest_by_id ( int ( ep_data [ ' QuestSceneId ' ] ) )
reward_table = await self . data . static . get_rewards_by_subtable ( int ( quest_scene [ ' RewardTableSubId ' ] ) )
ex_bonus_table = await self . data . static . get_ex_bonuses_by_subtable ( int ( ep_data [ ' ExBonusTableSubId ' ] ) )
await self . data . profile . add_col ( user_id , base_get_data . get_col )
quest_clear_flag = score_data . clear_time > 0
clear_time = score_data . clear_time
combo_num = score_data . combo_num
total_damage = score_data . total_damage
concurrent_destroying_num = score_data . concurrent_destroying_num
if quest_clear_flag is True :
await self . data . profile . add_vp ( user_id , quest_scene [ ' SingleRewardVp ' ] )
await self . data . profile . add_exp ( user_id , quest_scene [ ' SuccessPlayerExp ' ] )
exp = await self . data . profile . get_exp ( user_id )
else :
await self . data . profile . add_exp ( user_id , quest_scene [ ' FailedPlayerExp ' ] )
exp = await self . data . profile . get_exp ( user_id )
# Calculate level based off experience and the CSV list
player_level_data = self . load_data_csv ( " PlayerRank " )
for i in range ( 0 , len ( player_level_data ) ) :
if exp > = int ( player_level_data [ i ] [ " TotalExp " ] ) and exp < int ( player_level_data [ i + 1 ] [ " TotalExp " ] ) :
await self . data . profile . set_level ( user_id , int ( player_level_data [ i ] [ " PlayerRankId " ] ) )
break
current_data = await self . data . item . get_quest_log ( user_id , ep_data [ ' QuestSceneId ' ] )
if current_data :
await self . data . item . put_player_quest (
user_id ,
2024-06-28 03:24:12 +00:00
int ( QuestType . EPISODE ) ,
2024-06-25 18:02:53 +00:00
ep_data [ ' QuestSceneId ' ] ,
False if not quest_clear_flag and not current_data [ ' quest_clear_flag ' ] else True ,
min ( clear_time , current_data [ ' clear_time ' ] ) if quest_clear_flag else current_data [ ' clear_time ' ] ,
max ( combo_num , current_data [ ' combo_num ' ] ) ,
max ( int ( total_damage ) , current_data [ ' total_damage ' ] ) ,
max ( concurrent_destroying_num , current_data [ ' concurrent_destroying_num ' ] )
)
else :
await self . data . item . put_player_quest (
user_id ,
2024-06-28 03:24:12 +00:00
int ( QuestType . EPISODE ) ,
2024-06-25 18:02:53 +00:00
ep_data [ ' QuestSceneId ' ] ,
quest_clear_flag ,
clear_time ,
combo_num ,
total_damage ,
concurrent_destroying_num
)
for mission in play_end . mission_data_list :
if mission . clear_flag == 1 :
cleared_mission_ct + = 1
if mission . mission_difficulty_id > highest_mission_diff_cleared :
highest_mission_diff_cleared = mission . mission_difficulty_id
for monster_data in play_end . discovery_enemy_data_list :
num_monsters_defeated + = monster_data . destroy_num
monsters_defeated_data [ monster_data . enemy_kind_id ] = monster_data . destroy_num
for bonus in ex_bonus_table :
table_id = int ( bonus [ ' ExBonusTableId ' ] )
ach_thing = 0
condition = int ( bonus [ ' ExBonusConditionId ' ] )
val1 = int ( bonus [ ' ConditionValue1 ' ] )
val2 = int ( bonus [ ' ConditionValue2 ' ] )
if condition == ExBonusCondition . CLEAR_UNDER_X_SECS :
if quest_clear_flag and int ( score_data . clear_time / 1000 ) < val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . DEFEAT_X_MONSTER_Y_TIMES :
if monsters_defeated_data . get ( val1 , 0 ) > = val2 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . DEFEAT_X_MONSTERS :
if num_monsters_defeated > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . CLEAR_X_MISSIONS :
if cleared_mission_ct > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . CLEAR_MISSION_DIFFICULTY_X :
if highest_mission_diff_cleared > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . COLLECT_X_LOGS :
if len ( play_end . get_unanalyzed_log_tmp_reward_data_list ) > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . CLEAR_SKILL_LEVEL_X :
if score_data . reaching_skill_level > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . NO_LOSSES :
if score_data . total_loss_num == 0 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . ACCEL_X_TIMES :
if score_data . acceleration_invocation_num > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . MAX_COMBO_X :
if score_data . combo_num > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . MULTIPLAYER_CLEAR_X :
# TODO
pass
else :
self . logger . warn ( f " Unhandled EX Bonus condition { condition } " )
resp . play_end_response_data [ 0 ] . ex_bonus_data_list . append ( QuestScenePlayEndExBonusData . from_args ( table_id , ach_thing ) )
self . logger . info ( f " User { user_id } { ' cleared ' if quest_clear_flag else ' ended ' } episode { episode_id } " )
for rare_drop in play_end . get_rare_drop_data_list :
rewardList = self . load_data_csv ( " QuestRareDrop " )
for drop in rewardList :
if int ( drop [ ' QuestRareDropId ' ] ) == rare_drop . quest_rare_drop_id :
await self . add_reward ( drop , user_id )
break
for unanalyzed_log in play_end . get_unanalyzed_log_tmp_reward_data_list :
able_rewards : List [ Row ] = [ ]
for reward in reward_table :
if int ( reward [ ' UnanalyzedLogGradeId ' ] ) == unanalyzed_log . unanalyzed_log_grade_id :
able_rewards . append ( reward )
randomized_unanalyzed_id = choice ( able_rewards )
await self . add_reward ( randomized_unanalyzed_id . _asdict ( ) , user_id )
json_data [ " data " ] . append ( randomized_unanalyzed_id . _asdict ( ) )
trace_table = await self . data . static . get_player_trace_by_subid ( quest_scene [ ' PlayerTraceTableSubId ' ] )
for trace in play_end . get_player_trace_data_list :
self . logger . info ( f " User { user_id } obtained trace { trace . user_quest_scene_player_trace_id } " )
resp . play_end_response_data [ 0 ] . play_end_player_trace_reward_data_list . append ( QuestScenePlayEndPlayerTraceRewardData . from_args ( choice ( trace_table ) . _asdict ( ) ) )
await self . data . item . create_end_session ( user_id , ep_data [ ' QuestSceneId ' ] , play_end . play_result_flag , json_data [ " data " ] )
# Update heroes from the used party
play_session = await self . data . item . get_session ( user_id )
session_party = await self . data . item . get_hero_party_by_id ( play_session [ " user_party_team_id " ] )
if session_party :
hero_level_data = self . load_data_csv ( " HeroLogLevel " )
hero_list = [ ]
hero_list . append ( session_party [ " user_hero_log_id_1 " ] )
hero_list . append ( session_party [ " user_hero_log_id_2 " ] )
hero_list . append ( session_party [ " user_hero_log_id_3 " ] )
for i in range ( 0 , 3 ) :
await self . data . item . add_hero_xp ( hero_list [ i ] , base_get_data . get_hero_log_exp )
log_exp = await self . data . item . get_hero_xp ( hero_list [ i ] )
# Calculate hero level based off experience and the CSV list
if log_exp :
for e in range ( 0 , len ( hero_level_data ) ) :
if log_exp > = int ( hero_level_data [ e ] [ " TotalExp " ] ) and log_exp < int ( hero_level_data [ e + 1 ] [ " TotalExp " ] ) :
self . logger . info ( f " Set hero { hero_list [ i ] } level { hero_level_data [ e ] [ ' HeroLogLevelId ' ] } ( { log_exp } total XP) " )
await self . data . item . set_hero_level ( hero_list [ i ] , hero_level_data [ e ] [ ' HeroLogLevelId ' ] )
break
else :
self . logger . error ( f " Failed to get session party { play_session [ ' user_party_team_id ' ] } data for user { user_id } ! " )
return resp . make ( )
async def handle_c90a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#quest/episode_play_end_unanalyzed_log_fixed
req = SaoEpisodePlayEndUnanalyzedLogFixedRequest ( header , request )
resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse ( )
end_session_data = await self . data . item . get_end_session ( req . user_id )
for data in end_session_data [ ' reward_data ' ] :
resp . play_end_unanalyzed_log_reward_data_list . append ( QuestScenePlayEndUnanalyzedLogRewardData . from_args ( data [ ' UnanalyzedLogGradeId ' ] , data ) )
return resp . make ( )
async def handle_c914 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#quest/trial_tower_play_start
req_data = SaoTrialTowerPlayStartRequest ( header , request )
user_id = req_data . user_id
profile_data = await self . data . profile . get_profile ( user_id )
sesh_id = await self . data . item . create_session (
user_id ,
int ( req_data . play_start_request_data [ 0 ] . user_party_id ) ,
req_data . trial_tower_id ,
req_data . play_mode ,
req_data . play_start_request_data [ 0 ] . quest_drop_boost_apply_flag
)
self . logger . info ( f " User { req_data . user_id } started trial tower on floor { req_data . trial_tower_id } " )
resp = SaoTrialTowerPlayStartResponse ( sesh_id , profile_data [ ' nick_name ' ] )
return resp . make ( )
async def handle_c918 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#quest/trial_tower_play_end
req_data = SaoTrialTowerPlayEndRequest ( header , request )
resp = SaoTrialTowerPlayEndResponse ( )
user_id = req_data . user_id
trial_tower_id = req_data . trial_tower_id
play_end = req_data . play_end_request_data [ 0 ]
base_get_data = play_end . base_get_data [ 0 ]
score_data = play_end . score_data [ 0 ]
exp = 0
cleared_mission_ct = 0
highest_mission_diff_cleared = 0
num_monsters_defeated = 0
monsters_defeated_data = { }
json_data = { " data " : [ ] }
ep_data = await self . data . static . get_tower_by_id ( trial_tower_id )
quest_scene = await self . data . static . get_quest_by_id ( int ( ep_data [ ' QuestSceneId ' ] ) )
reward_table = await self . data . static . get_rewards_by_subtable ( int ( quest_scene [ ' RewardTableSubId ' ] ) )
ex_bonus_table = await self . data . static . get_ex_bonuses_by_subtable ( int ( ep_data [ ' ExBonusTableSubId ' ] ) )
await self . data . profile . add_col ( user_id , base_get_data . get_col )
quest_clear_flag = score_data . clear_time > 0
clear_time = score_data . clear_time
combo_num = score_data . combo_num
total_damage = score_data . total_damage
concurrent_destroying_num = score_data . concurrent_destroying_num
if quest_clear_flag is True :
await self . data . profile . add_vp ( user_id , quest_scene [ ' SingleRewardVp ' ] )
await self . data . profile . add_exp ( user_id , quest_scene [ ' SuccessPlayerExp ' ] )
exp = await self . data . profile . get_exp ( user_id )
else :
await self . data . profile . add_exp ( user_id , quest_scene [ ' FailedPlayerExp ' ] )
exp = await self . data . profile . get_exp ( user_id )
# Calculate level based off experience and the CSV list
player_level_data = self . load_data_csv ( " PlayerRank " )
for i in range ( 0 , len ( player_level_data ) ) :
if exp > = int ( player_level_data [ i ] [ " TotalExp " ] ) and exp < int ( player_level_data [ i + 1 ] [ " TotalExp " ] ) :
await self . data . profile . set_level ( user_id , int ( player_level_data [ i ] [ " PlayerRankId " ] ) )
break
current_data = await self . data . item . get_quest_log ( user_id , ep_data [ ' QuestSceneId ' ] )
if current_data :
await self . data . item . put_player_quest (
user_id ,
2024-06-28 03:24:12 +00:00
int ( QuestType . TRIAL_TOWER ) ,
2024-06-25 18:02:53 +00:00
ep_data [ ' QuestSceneId ' ] ,
False if not quest_clear_flag and not current_data [ ' quest_clear_flag ' ] else True ,
min ( clear_time , current_data [ ' clear_time ' ] ) if quest_clear_flag else current_data [ ' clear_time ' ] ,
max ( combo_num , current_data [ ' combo_num ' ] ) ,
max ( int ( total_damage ) , current_data [ ' total_damage ' ] ) ,
max ( concurrent_destroying_num , current_data [ ' concurrent_destroying_num ' ] )
)
else :
await self . data . item . put_player_quest (
user_id ,
2024-06-28 03:24:12 +00:00
int ( QuestType . TRIAL_TOWER ) ,
2024-06-25 18:02:53 +00:00
ep_data [ ' QuestSceneId ' ] ,
quest_clear_flag ,
clear_time ,
combo_num ,
total_damage ,
concurrent_destroying_num
)
for mission in play_end . mission_data_list :
if mission . clear_flag == 1 :
cleared_mission_ct + = 1
if mission . mission_difficulty_id > highest_mission_diff_cleared :
highest_mission_diff_cleared = mission . mission_difficulty_id
for monster_data in play_end . discovery_enemy_data_list :
num_monsters_defeated + = monster_data . destroy_num
monsters_defeated_data [ monster_data . enemy_kind_id ] = monster_data . destroy_num
for bonus in ex_bonus_table :
table_id = int ( bonus [ ' ExBonusTableId ' ] )
ach_thing = 0
condition = int ( bonus [ ' ExBonusConditionId ' ] )
val1 = int ( bonus [ ' ConditionValue1 ' ] )
val2 = int ( bonus [ ' ConditionValue2 ' ] )
if condition == ExBonusCondition . CLEAR_UNDER_X_SECS :
if quest_clear_flag and int ( score_data . clear_time / 1000 ) < val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . DEFEAT_X_MONSTER_Y_TIMES :
if monsters_defeated_data . get ( val1 , 0 ) > = val2 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . DEFEAT_X_MONSTERS :
if num_monsters_defeated > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . CLEAR_X_MISSIONS :
if cleared_mission_ct > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . CLEAR_MISSION_DIFFICULTY_X :
if highest_mission_diff_cleared > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . COLLECT_X_LOGS :
if len ( play_end . get_unanalyzed_log_tmp_reward_data_list ) > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . CLEAR_SKILL_LEVEL_X :
if score_data . reaching_skill_level > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . NO_LOSSES :
if score_data . total_loss_num == 0 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . ACCEL_X_TIMES :
if score_data . acceleration_invocation_num > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . MAX_COMBO_X :
if score_data . combo_num > = val1 :
await self . add_reward ( bonus . _asdict ( ) , user_id )
await self . data . item . put_ex_bonus ( user_id , int ( ep_data [ ' QuestSceneId ' ] ) , table_id , True )
ach_thing = 2
elif condition == ExBonusCondition . MULTIPLAYER_CLEAR_X :
# TODO
pass
else :
self . logger . warn ( f " Unhandled EX Bonus condition { condition } " )
resp . play_end_response_data [ 0 ] . ex_bonus_data_list . append ( QuestScenePlayEndExBonusData . from_args ( table_id , ach_thing ) )
self . logger . info ( f " User { user_id } { ' cleared ' if quest_clear_flag else ' ended ' } trial tower { trial_tower_id } " )
for rare_drop in play_end . get_rare_drop_data_list :
rewardList = self . load_data_csv ( " QuestRareDrop " )
for drop in rewardList :
if int ( drop [ ' QuestRareDropId ' ] ) == rare_drop . quest_rare_drop_id :
await self . add_reward ( drop , user_id )
break
for unanalyzed_log in play_end . get_unanalyzed_log_tmp_reward_data_list :
able_rewards : List [ Row ] = [ ]
for reward in reward_table :
if int ( reward [ ' UnanalyzedLogGradeId ' ] ) == unanalyzed_log . unanalyzed_log_grade_id :
able_rewards . append ( reward )
randomized_unanalyzed_id = choice ( able_rewards )
await self . add_reward ( randomized_unanalyzed_id . _asdict ( ) , user_id )
json_data [ " data " ] . append ( randomized_unanalyzed_id . _asdict ( ) )
trace_table = await self . data . static . get_player_trace_by_subid ( quest_scene [ ' PlayerTraceTableSubId ' ] )
for trace in play_end . get_player_trace_data_list :
self . logger . info ( f " User { user_id } obtained trace { trace . user_quest_scene_player_trace_id } " )
resp . play_end_response_data [ 0 ] . play_end_player_trace_reward_data_list . append ( QuestScenePlayEndPlayerTraceRewardData . from_args ( choice ( trace_table ) . _asdict ( ) ) )
await self . data . item . create_end_session ( user_id , ep_data [ ' QuestSceneId ' ] , play_end . play_result_flag , json_data [ " data " ] )
# Update heroes from the used party
play_session = await self . data . item . get_session ( user_id )
session_party = await self . data . item . get_hero_party_by_id ( play_session [ " user_party_team_id " ] )
if session_party :
hero_level_data = self . load_data_csv ( " HeroLogLevel " )
hero_list = [ ]
hero_list . append ( session_party [ " user_hero_log_id_1 " ] )
hero_list . append ( session_party [ " user_hero_log_id_2 " ] )
hero_list . append ( session_party [ " user_hero_log_id_3 " ] )
for i in range ( 0 , 3 ) :
self . logger . info ( f " Give hero { hero_list [ i ] } { base_get_data . get_hero_log_exp } " )
await self . data . item . add_hero_xp ( hero_list [ i ] , base_get_data . get_hero_log_exp )
log_exp = await self . data . item . get_hero_xp ( hero_list [ i ] )
# Calculate hero level based off experience and the CSV list
if log_exp :
for e in range ( 0 , len ( hero_level_data ) ) :
if log_exp > = int ( hero_level_data [ e ] [ " TotalExp " ] ) and log_exp < int ( hero_level_data [ e + 1 ] [ " TotalExp " ] ) :
self . logger . info ( f " Set hero { hero_list [ i ] } level { hero_level_data [ e ] [ ' HeroLogLevelId ' ] } ( { log_exp } total XP) " )
await self . data . item . set_hero_level ( hero_list [ i ] , hero_level_data [ e ] [ ' HeroLogLevelId ' ] )
break
else :
self . logger . error ( f " Failed to get session party { play_session [ ' user_party_team_id ' ] } data for user { user_id } ! " )
return resp . make ( )
async def handle_c91a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes : # handler is identical to the episode
#quest/trial_tower_play_end_unanalyzed_log_fixed
req = SaoTrialTowerPlayEndUnanalyzedLogFixedRequest ( header , request )
resp = SaoTrialTowerPlayEndUnanalyzedLogFixedResponse ( )
end_session_data = await self . data . item . get_end_session ( req . user_id )
for data in end_session_data [ ' reward_data ' ] :
resp . play_end_unanalyzed_log_reward_data_list . append ( QuestScenePlayEndUnanalyzedLogRewardData . from_args ( data [ ' UnanalyzedLogGradeId ' ] , data ) )
return resp . make ( )
async def handle_c930 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# quest/get_chat_side_story_user_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetChatSideStoryUserDataListResponse ( )
return resp . make ( )
async def handle_ca02 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#quest_multi_play_room/get_quest_scene_multi_play_photon_server
resp = SaoGetQuestSceneMultiPlayPhotonServerResponse ( self . game_cfg . server . photon_app_id )
return resp . make ( )
async def handle_cb02 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# quest_ranking/get_quest_hierarchy_progress_degrees_ranking_list
req = SaoGetQuestHierarchyProgressDegreesRankingListRequest ( header , request )
return SaoGetQuestHierarchyProgressDegreesRankingListResponse ( GameconnectCmd . GET_QUEST_HIERARCHY_PROGRESS_DEGREES_RANKING_LIST_RESPONSE ) . make ( )
async def handle_cb04 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# quest_ranking/get_quest_popular_hero_log_ranking_list
req = SaoGetQuestPopularHeroLogRankingListRequest ( header , request )
return SaoGetQuestPopularHeroLogRankingListResponse ( GameconnectCmd . GET_QUEST_POPULAR_HERO_LOG_RANKING_LIST_RESPONSE ) . make ( )
async def handle_cd00 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#defrag_match/get_defrag_match_basic_data
resp = SaoGetDefragMatchBasicDataResponse ( )
data = DefragMatchBasicUserData . from_args ( )
return resp . make ( )
async def handle_cd02 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#defrag_match/get_defrag_match_ranking_user_data
# TODO: League points
req = SaoGetDefragMatchRankingUserDataRequest ( header , request )
profile = await self . data . profile . get_profile ( req . user_id )
resp = SaoGetDefragMatchRankingUserDataResponse ( profile . _asdict ( ) )
return resp . make ( )
async def handle_cd04 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#defrag_match/get_defrag_match_league_point_ranking_list
resp = SaoGetDefragMatchLeaguePointRankingListResponse ( )
return resp . make ( )
async def handle_cd06 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
#defrag_match/get_defrag_match_league_score_ranking_list
resp = SaoGetDefragMatchLeagueScoreRankingListResponse ( )
return resp . make ( )
async def handle_cf0e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# gasha/get_gasha_medal_shop_user_data_list
# TODO: Get user shop data
req = GetGashaMedalShopUserDataListRequest ( header , request )
resp = GetGashaMedalShopUserDataListResponse ( GameconnectCmd . GET_GASHA_MEDAL_SHOP_USER_DATA_LIST_RESPONSE )
return resp . make ( )
async def handle_d000 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
req = SaoGenericUserRequest ( header , request )
resp = SaoGetAdventureExecUserDataResponse ( )
return resp . make ( )
async def handle_d100 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# shop/get_yui_medal_shop_user_data_list
# TODO: Get user shop data
req = GetYuiMedalShopUserDataListRequest ( header , request )
resp = GetYuiMedalShopUserDataListResponse ( GameconnectCmd . GET_YUI_MEDAL_SHOP_USER_DATA_LIST_RESPONSE )
return resp . make ( )
async def handle_d200 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# mission/get_beginner_mission_user_data
req = SaoGetBeginnerMissionUserDataRequest ( header , request )
resp = SaoGetBeginnerMissionUserDataResponse ( )
profile = await self . data . profile . get_profile ( req . user_id )
if profile :
if profile [ ' ad_confirm_date ' ] :
resp . data [ 0 ] . ad_confirm_date = profile [ ' ad_confirm_date ' ]
resp . data [ 0 ] . ad_confirm_flag = 1
return resp . make ( )
async def handle_d202 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# mission/get_beginner_mission_progresses_user_data_list
req = SaoGetBeginnerMissionProgressesUserDataListRequest ( header , request )
resp = SaoGetBeginnerMissionProgressesUserDataListResponse ( )
return resp . make ( )
async def handle_d204 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# mission/get_beginner_mission_seat_progresses_user_data_list
req = SaoGetBeginnerMissionSeatProgressesUserDataListRequest ( header , request )
resp = SaoGetBeginnerMissionSeatProgressesUserDataListResponse ( )
return resp . make ( )
async def handle_d206 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# mission/beginner_mission_ad_confirm_notification
req = SaoBeginnerMissionAdConfirmNotificationRequest ( header , request )
self . logger . info ( f " User { req . user_id } confirmed ad for beginner mission { req . beginner_mission_id } " )
await self . data . profile . update_beginner_mission_date ( req . user_id )
return SaoNoopResponse ( GameconnectCmd . BEGINNER_MISSION_AD_CONFIRM_NOTIFICATION_RESPONSE ) . make ( )
async def handle_d312 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# campaign/get_linked_site_reg_campaign_user_data
req = SaoGetLinkedSiteRegCampaignUserDataRequest ( header , request )
resp = SaoGetLinkedSiteRegCampaignUserDataResponse ( )
return resp . make ( )
async def handle_d400 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# other/get_hero_log_unit_user_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetHeroLogUnitUserDataListResponse ( )
return resp . make ( )
async def handle_d402 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# other/get_chara_unit_user_data_list
req = SaoGenericUserRequest ( header , request )
resp = SaoGetCharaUnitUserDataListResponse ( )
return resp . make ( )
async def handle_d404 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# other/bnid_serial_code_check
req = SaoBnidSerialCodeCheckRequest ( )
resp = SaoBnidSerialCodeCheckResponse ( )
return resp . make ( )
async def handle_d404 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# other/bnid_serial_code_entry_by_appendix_card
req = SaoBnidSerialCodeEntryByAppendixCardRequest ( )
resp = SaoBnidSerialCodeEntryByAppendixCardResponse ( )
return resp . make ( )
async def handle_d500 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_player_ranks
tbl = self . load_data_csv ( ' PlayerRank ' )
resp = SaoGetMPlayerRanksResponse ( tbl )
return resp . make ( )
async def handle_d502 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_titles
tbl = self . load_data_csv ( ' Title ' )
resp = SaoGetMTitlesResponse ( tbl )
return resp . make ( )
async def handle_d504 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_fragments
tbl = self . load_data_csv ( ' Fragment ' )
resp = SaoGetMFragmentsResponse ( tbl )
return resp . make ( )
async def handle_d506 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_reward_tables
tbl = self . load_data_csv ( ' RewardTable ' )
resp = SaoGetMRewardTablesResponse ( tbl )
return resp . make ( )
async def handle_d508 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_reward_sets
tbl = self . load_data_csv ( ' RewardSet ' )
resp = SaoGetMRewardSetsResponse ( tbl )
return resp . make ( )
async def handle_d50a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_unanalyzed_log_grades
tbl = self . load_data_csv ( ' UnanalyzedLogGrade ' )
resp = SaoGetMUnanalyzedLogGradesResponse ( tbl )
return resp . make ( )
async def handle_d50c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_appoint_leader_params
tbl = self . load_data_csv ( ' AppointLeaderParam ' )
resp = SaoGetMAppointLeaderParamsResponse ( tbl )
return resp . make ( )
async def handle_d50e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_appoint_leader_effects
tbl = self . load_data_csv ( ' AppointLeaderEffect ' )
resp = SaoGetMAppointLeaderEffectsResponse ( tbl )
return resp . make ( )
async def handle_d510 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_appoint_leader_effect_types
tbl = self . load_data_csv ( ' AppointLeaderEffectType ' )
resp = SaoGetMAppointLeaderEffectTypesResponse ( tbl )
return resp . make ( )
async def handle_d512 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_rarities
tbl = self . load_data_csv ( ' Rarity ' )
resp = SaoGetMRaritiesResponse ( tbl )
return resp . make ( )
async def handle_d514 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_composition_events
tbl = self . load_data_csv ( ' CompositionEvent ' )
resp = SaoGetMCompositionEventsResponse ( tbl )
return resp . make ( )
async def handle_d516 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_composition_params
tbl = self . load_data_csv ( ' CompositionParam ' )
resp = SaoGetMCompositionParamsResponse ( tbl )
return resp . make ( )
async def handle_d518 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_game_play_prices
tbl = self . load_data_csv ( ' GamePlayPrice ' )
resp = SaoGetMGamePlayPricesResponse ( tbl )
return resp . make ( )
async def handle_d51a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_buy_tickets
tbl = self . load_data_csv ( ' BuyTicket ' )
resp = SaoGetMBuyTicketsResponse ( tbl )
return resp . make ( )
async def handle_d51c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_tips
tbl = self . load_data_csv ( ' Tips ' )
resp = SaoGetMTipsResponse ( tbl )
return resp . make ( )
async def handle_d51e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_caps
tbl = self . load_data_csv ( ' Cap ' )
resp = SaoGetMCapsResponse ( tbl )
return resp . make ( )
async def handle_d520 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_hero_log
tbl = self . load_data_csv ( ' HeroLog ' )
resp = SaoGetMHeroLogResponse ( tbl )
return resp . make ( )
async def handle_d522 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_hero_log_levels
tbl = self . load_data_csv ( ' HeroLogLevel ' )
resp = SaoGetMHeroLogLevelsResponse ( tbl )
return resp . make ( )
async def handle_d524 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_hero_log_roles
tbl = self . load_data_csv ( ' HeroLogRole ' )
resp = SaoGetMHeroLogRolesResponse ( tbl )
return resp . make ( )
async def handle_d526 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_hero_log_trust_ranks
tbl = self . load_data_csv ( ' HeroLogTrustRank ' )
resp = SaoGetMHeroLogTrustRanksResponse ( tbl )
return resp . make ( )
async def handle_d528 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_charas
tbl = self . load_data_csv ( ' Chara ' )
resp = SaoGetMCharasResponse ( tbl )
return resp . make ( )
async def handle_d52a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_chara_friendly_ranks
tbl = self . load_data_csv ( ' CharaFriendlyRank ' )
resp = SaoGetMCharaFriendlyRanksResponse ( tbl )
return resp . make ( )
async def handle_d52c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_equipments
tbl = self . load_data_csv ( ' Equipment ' )
resp = SaoGetMEquipmentsResponse ( tbl )
return resp . make ( )
async def handle_d52e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_equipment_levels
tbl = self . load_data_csv ( ' EquipmentLevel ' )
resp = SaoGetMEquipmentLevelsResponse ( tbl )
return resp . make ( )
async def handle_d530 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_weapon_types
tbl = self . load_data_csv ( ' WeaponType ' )
resp = SaoGetMWeaponTypesResponse ( tbl )
return resp . make ( )
async def handle_d532 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_items
tbl = self . load_data_csv ( ' Item ' )
resp = SaoGetMItemsResponse ( tbl )
return resp . make ( )
async def handle_d534 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_item_types
tbl = self . load_data_csv ( ' ItemType ' )
resp = SaoGetMItemTypesResponse ( tbl )
return resp . make ( )
async def handle_d536 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_buff_items
tbl = self . load_data_csv ( ' BuffItem ' )
resp = SaoGetMBuffItemsResponse ( tbl )
return resp . make ( )
async def handle_d538 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_enemies
tbl = self . load_data_csv ( ' Enemy ' )
resp = SaoGetMEnemiesResponse ( tbl )
return resp . make ( )
async def handle_d53a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_enemy_sets
tbl = self . load_data_csv ( ' EnemySet ' )
resp = SaoGetMEnemySetsResponse ( tbl )
return resp . make ( )
async def handle_d53c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_enemy_kinds
tbl = self . load_data_csv ( ' EnemyKind ' )
resp = SaoGetMEnemyKindsResponse ( tbl )
return resp . make ( )
2023-05-30 22:03:52 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d53e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_enemy_categories
tbl = self . load_data_csv ( ' EnemyCategory ' )
resp = SaoGetMEnemyCategoriesResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d540 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_units
tbl = self . load_data_csv ( ' Unit ' )
resp = SaoGetMUnitsResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d542 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_unit_gimmicks
tbl = self . load_data_csv ( ' UnitGimmick ' )
resp = SaoGetMUnitGimmicksResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d544 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_unit_collisions
tbl = self . load_data_csv ( ' UnitCollision ' )
resp = SaoGetMUnitCollisionsResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d546 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_unit_powers
tbl = self . load_data_csv ( ' UnitPower ' )
resp = SaoGetMUnitPowersResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d548 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gimmick_attacks
tbl = self . load_data_csv ( ' GimmickAttack ' )
resp = SaoGetMGimmickAttacksResponse ( tbl )
return resp . make ( )
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d54a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_chara_attacks
tbl = self . load_data_csv ( ' CharaAttack ' )
resp = SaoGetMCharaAttacksResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d54c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_boss_attacks
tbl = self . load_data_csv ( ' BossAttack ' )
resp = SaoGetMBossAttacksResponse ( tbl )
return resp . make ( )
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d54e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_monster_attacks
tbl = self . load_data_csv ( ' MonsterAttack ' )
resp = SaoGetMMonsterAttacksResponse ( tbl )
return resp . make ( )
2023-05-29 20:51:41 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d550 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_monster_actions
tbl = self . load_data_csv ( ' MonsterAction ' )
resp = SaoGetMMonsterActionsResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d552 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_properties
tbl = self . load_data_csv ( ' Property ' )
resp = SaoGetMPropertiesResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d554 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_property_tables
tbl = self . load_data_csv ( ' PropertyTable ' )
resp = SaoGetMPropertyTablesResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d556 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_property_types
tbl = self . load_data_csv ( ' PropertyType ' )
resp = SaoGetMPropertyTypesResponse ( tbl )
return resp . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d558 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_skills
tbl = self . load_data_csv ( ' Skill ' )
resp = SaoGetMSkillsResponse ( tbl )
return resp . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d55a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_skill_tables
tbl = self . load_data_csv ( ' SkillTable ' )
resp = SaoGetMSkillTablesResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d55c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_skill_levels
tbl = self . load_data_csv ( ' SkillLevel ' )
resp = SaoGetMSkillLevelsResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d55e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_awakenings
tbl = self . load_data_csv ( ' Awakening ' )
resp = SaoGetMAwakeningsResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d560 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_synchro_skills
tbl = self . load_data_csv ( ' SynchroSkill ' )
resp = SaoGetMSynchroSkillsResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2023-05-29 20:51:41 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d562 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_sound_skill_cut_in_voices
tbl = self . load_data_csv ( ' Sound_SkillCutInVoice ' )
resp = SaoGetMSoundSkillCutInVoicesResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d564 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_scenes
tbl = self . load_data_csv ( ' QuestScene ' )
resp = SaoGetMQuestScenesResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d566 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_exist_units
tbl = self . load_data_csv ( ' QuestExistUnit ' )
resp = SaoGetMQuestExistUnitsResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d568 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_episode_append_rewards
tbl = self . load_data_csv ( ' QuestEpisodeAppendRewards ' )
resp = SaoGetMQuestEpisodeAppendRewardsResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d56a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_side_quests
tbl = self . load_data_csv ( ' SideQuest ' )
resp = SaoGetMSideQuestsResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d56c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_episodes
tbl = self . load_data_csv ( ' Episode ' )
resp = SaoGetMEpisodesResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d56e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_episode_chapters
tbl = self . load_data_csv ( ' EpisodeChapter ' )
resp = SaoGetMEpisodeChaptersResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d570 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_episode_parts
tbl = self . load_data_csv ( ' EpisodePart ' )
resp = SaoGetMEpisodePartsResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d572 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_trial_towers
tbl = self . load_data_csv ( ' TrialTower ' )
resp = SaoGetMTrialTowersResponse ( tbl )
return resp . make ( )
2023-06-01 17:19:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d574 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_ex_towers
req = SaoGetMExTowersRequest ( header , request )
tbl = self . load_data_csv ( ' ExTowers ' )
resp = SaoGetMExTowersResponse ( tbl )
2023-06-01 17:19:48 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d576 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_ex_tower_quests
req = SaoGetMExTowerQuestsRequest ( header , request )
tbl = self . load_data_csv ( ' ExTowerQuests ' )
resp = SaoGetMExTowerQuestsResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d578 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_menu_display_enemies
tbl = self . load_data_csv ( ' MenuDisplayEnemy ' )
resp = SaoGetMMenuDisplayEnemiesResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d57a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_missions
tbl = self . load_data_csv ( ' Mission ' )
resp = SaoGetMMissionsResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d57c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_mission_tables
tbl = self . load_data_csv ( ' MissionTable ' )
resp = SaoGetMMissionTablesResponse ( tbl )
return resp . make ( )
2023-11-13 00:55:10 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d57e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_mission_difficulties
tbl = self . load_data_csv ( ' MissionDifficulty ' )
resp = SaoGetMMissionDifficultiesResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d580 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_battle_cameras
tbl = self . load_data_csv ( ' BattleCamera ' )
resp = SaoGetMBattleCamerasResponse ( tbl )
return resp . make ( )
2023-11-13 00:55:10 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d582 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_chat_main_stories
tbl = self . load_data_csv ( ' ChatMainStory ' )
resp = SaoGetMChatMainStoriesResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d584 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_chat_side_stories
tbl = self . load_data_csv ( ' ChatSideStory ' )
resp = SaoGetMChatSideStoriesResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d586 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_chat_event_stories
req = SaoGetMChatEventStoriesRequest ( header , request )
tbl = self . load_data_csv ( ' ChatEventStory ' )
resp = SaoGetMChatEventStoriesResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d588 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_navigator_charas
tbl = self . load_data_csv ( ' NavigatorChara ' )
resp = SaoGetMNavigatorCharasResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d58a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_navigator_comments
tbl = self . load_data_csv ( ' NavigatorComment ' )
resp = SaoGetMNavigatorCommentsResponse ( tbl )
return resp . make ( )
2023-06-01 01:58:30 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d58c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_ex_bonus_tables
tbl = self . load_data_csv ( ' ExBonusTable ' )
resp = SaoGetMExBonusTablesResponse ( tbl )
2023-06-01 01:58:30 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d58e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_ex_bonus_conditions
tbl = self . load_data_csv ( ' ExBonusCondition ' )
resp = SaoGetMExBonusConditionsResponse ( tbl )
return resp . make ( )
2023-05-29 15:10:32 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d590 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_rare_drops
tbl = self . load_data_csv ( ' QuestRareDrop ' )
resp = SaoGetMQuestRareDropsResponse ( tbl )
return resp . make ( )
2023-05-29 20:51:41 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d592 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_special_rare_drop_settings
tbl = self . load_data_csv ( ' QuestSpecialRareDropSettings ' )
resp = SaoGetMQuestSpecialRareDropSettingsResponse ( tbl )
return resp . make ( )
2023-05-29 20:51:41 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d594 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_special_rare_drops
tbl = self . load_data_csv ( ' QuestSpecialRareDrops ' )
resp = SaoGetMQuestSpecialRareDropsResponse ( tbl )
return resp . make ( )
2023-05-29 15:10:32 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d596 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_tutorials
tbl = self . load_data_csv ( ' QuestTutorial ' )
resp = SaoGetMQuestTutorialsResponse ( tbl )
return resp . make ( )
2023-06-25 18:40:34 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d598 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_player_trace_tables
tbl = self . load_data_csv ( ' PlayerTraceTable ' )
resp = SaoGetMQuestPlayerTraceTablesResponse ( tbl )
return resp . make ( )
2023-06-25 18:40:34 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d59a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_stills
tbl = self . load_data_csv ( ' QuestStill ' )
resp = SaoGetMQuestStillsResponse ( tbl )
2023-05-29 15:10:32 +00:00
return resp . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d59c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gashas
tbl = self . load_data_csv ( ' Gasha ' )
resp = SaoGetMGashasResponse ( tbl )
return resp . make ( )
2023-05-29 15:10:32 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d59e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_headers
tbl = self . load_data_csv ( ' GashaHeader ' )
resp = SaoGetMGashaHeadersResponse ( tbl )
return resp . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5a0 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_lottery_rarities
tbl = self . load_data_csv ( ' GashaLotteryRarity ' )
resp = SaoGetMGashaLotteryRaritiesResponse ( tbl )
return resp . make ( )
2023-05-29 23:21:26 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5a2 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_prizes
tbl = self . load_data_csv ( ' GashaPrize ' )
resp = SaoGetMGashaPrizesResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d5a4 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_comeback_events
tbl = self . load_data_csv ( ' ComebackEvent ' )
resp = SaoGetMComebackEventsResponse ( tbl )
return resp . make ( )
2023-05-29 15:10:32 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5a6 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_ad_banners
tbl = self . load_data_csv ( ' AdBanners ' )
resp = SaoGetMAdBannersResponse ( tbl )
return resp . make ( )
2023-05-29 15:10:32 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5a8 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_events
tbl = self . load_data_csv ( ' Event ' )
resp = SaoGetMEventsResponse ( tbl )
return resp . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5aa ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunts
req = SaoGetMTreasureHuntsRequest ( header , request )
tbl = self . load_data_csv ( ' TreasureHunt ' )
resp = SaoGetMTreasureHuntsResponse ( tbl )
return resp . make ( )
2023-06-25 17:47:31 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ac ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunt_whole_tasks
req = SaoGetMTreasureHuntWholeTasksRequest ( header , request )
tbl = self . load_data_csv ( ' TreasureHuntWholeTask ' )
resp = SaoGetMTreasureHuntWholeTasksResponse ( tbl )
return resp . make ( )
2023-06-25 04:08:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ae ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunt_individual_tasks
req = SaoGetMTreasureHuntIndividualTasksRequest ( header , request )
tbl = self . load_data_csv ( ' TreasureHuntIndividualTask ' )
resp = SaoGetMTreasureHuntIndividualTasksResponse ( tbl )
return resp . make ( )
2023-06-26 23:30:03 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5b0 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunt_special_effects
req = SaoGetMTreasureHuntSpecialEffectsRequest ( header , request )
tbl = self . load_data_csv ( ' TreasureHuntSpecialEffect ' )
resp = SaoGetMTreasureHuntSpecialEffectsResponse ( tbl )
return resp . make ( )
2023-06-25 04:08:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5b2 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunt_event_point_reward_common_rewards
req = SaoGetMTreasureHuntEventPointRewardCommonRewardsRequest ( header , request )
tbl = self . load_data_csv ( ' TreasureHuntEventPointRewardCommonReward ' )
resp = SaoGetMTreasureHuntEventPointRewardCommonRewardsResponse ( tbl )
return resp . make ( )
2023-06-24 22:48:48 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5b4 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunt_event_point_reward_titles
req = SaoGetMTreasureHuntEventPointRewardTitlesRequest ( header , request )
tbl = self . load_data_csv ( ' TreasureHuntEventPointRewardTitle ' )
resp = SaoGetMTreasureHuntEventPointRewardTitlesResponse ( tbl )
return resp . make ( )
2023-06-25 17:47:31 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5b6 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_treasure_hunt_task_texts
tbl = self . load_data_csv ( ' TreasureHuntTaskText ' )
resp = SaoGetMTreasureHuntTaskTextsResponse ( tbl )
return resp . make ( )
2023-05-29 23:21:26 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5b8 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_bnid_serial_codes
tbl = self . load_data_csv ( ' BnidSerialCodes ' )
resp = SaoGetMBnidSerialCodesResponse ( tbl )
return resp . make ( )
2023-05-30 00:57:02 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ba ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_bnid_serial_code_rewards
tbl = self . load_data_csv ( ' BnidSerialCodeRewards ' )
resp = SaoGetMBnidSerialCodeRewardsResponse ( tbl )
return resp . make ( )
2023-05-29 23:21:26 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5bc ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_support_log
tbl = self . load_data_csv ( ' SupportLog ' )
resp = SaoGetMSupportLogResponse ( tbl )
return resp . make ( )
2023-06-25 17:47:31 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5be ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_support_log_types
tbl = self . load_data_csv ( ' SupportLogType ' )
resp = SaoGetMSupportLogTypesResponse ( tbl )
return resp . make ( )
2023-06-03 15:42:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5c0 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_episode_appends
tbl = self . load_data_csv ( ' EpisodeAppends ' )
resp = SaoGetMEpisodeAppendsResponse ( tbl )
return resp . make ( )
2023-07-02 18:25:24 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5c2 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_defrag_match_quests
tbl = self . load_data_csv ( ' DefragMatchQuest ' )
resp = SaoGetMQuestDefragMatchQuestsResponse ( tbl )
return resp . make ( )
2023-05-29 23:21:26 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5c4 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_quest_defrag_match_quest_boss_tables
tbl = self . load_data_csv ( ' DefragMatchBossTable ' )
resp = SaoGetMQuestDefragMatchQuestBossTablesResponse ( tbl )
return resp . make ( )
2023-07-02 18:25:24 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5c6 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_matches
req = SaoGetMDefragMatchesRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchs ' )
resp = SaoGetMDefragMatchesResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d5c8 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_seed
req = SaoGetMDefragMatchSeedRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchSeed ' )
resp = SaoGetMDefragMatchSeedResponse ( tbl )
return resp . make ( )
2023-06-24 16:29:28 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ca ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_special_effects
req = SaoGetMDefragMatchSpecialEffectsRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchSpecialEffects ' )
resp = SaoGetMDefragMatchSpecialEffectsResponse ( tbl )
return resp . make ( )
2023-05-26 17:45:20 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5cc ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_grades
req = SaoGetMDefragMatchGradesRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchGrade ' )
resp = SaoGetMDefragMatchGradesResponse ( tbl )
return resp . make ( )
2023-06-25 04:08:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ce ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_cpu_units
tbl = self . load_data_csv ( ' DefragMatchCpuUnits ' )
resp = SaoGetMDefragMatchCpuUnitsResponse ( tbl )
2023-05-26 17:45:20 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d5d0 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_cpu_support_logs
tbl = self . load_data_csv ( ' DefragMatchCpuSupportLogs ' )
resp = SaoGetMDefragMatchCpuSupportLogsResponse ( tbl )
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5d2 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_period_bonuses
req = SaoGetMDefragMatchPeriodBonusesRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchPeriodBonuses ' )
resp = SaoGetMDefragMatchPeriodBonusesResponse ( tbl )
return resp . make ( )
2023-06-25 00:09:37 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5d4 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_random_bonus_tables
req = SaoGetMDefragMatchRandomBonusTablesRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchRandomBonusTables ' )
resp = SaoGetMDefragMatchRandomBonusTablesResponse ( tbl )
return resp . make ( )
2023-06-25 04:08:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5d6 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_random_bonus_conditions
tbl = self . load_data_csv ( ' DefragMatchRandomBonusConditions ' )
resp = SaoGetMDefragMatchRandomBonusConditionsResponse ( tbl )
return resp . make ( )
2023-06-25 04:08:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5d8 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_defrag_match_rare_drops
req = SaoGetMDefragMatchRareDropsRequest ( header , request )
tbl = self . load_data_csv ( ' DefragMatchRareDrops ' )
resp = SaoGetMDefragMatchRareDropsResponse ( tbl )
return resp . make ( )
2023-06-25 00:09:37 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5da ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_yui_medal_shops
tbl = self . load_data_csv ( ' YuiMedalShops ' )
resp = SaoGetMYuiMedalShopsResponse ( tbl )
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5dc ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_yui_medal_shop_items
tbl = self . load_data_csv ( ' YuiMedalShopItems ' )
resp = SaoGetMYuiMedalShopItemsResponse ( tbl )
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5de ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_event_scenes
req = SaoGetMEventScenesRequest ( header , request )
tbl = self . load_data_csv ( ' EventScenes ' )
resp = SaoGetMEventScenesResponse ( tbl )
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5e0 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_generic_campaign_periods
tbl = self . load_data_csv ( ' GenericCampaignPeriods ' )
resp = SaoGetMGenericCampaignPeriodsResponse ( tbl )
return resp . make ( )
2023-06-25 17:47:31 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5e2 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_beginner_missions
tbl = self . load_data_csv ( ' BeginnerMissions ' )
resp = SaoGetMBeginnerMissionsResponse ( tbl )
return resp . make ( )
2023-07-02 18:25:24 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5e4 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_beginner_mission_conditions
req = SaoGetMBeginnerMissionConditionsRequest ( header , request )
tbl = self . load_data_csv ( ' BeginnerMissionConditions ' )
resp = SaoGetMBeginnerMissionConditionsResponse ( tbl )
return resp . make ( )
2023-06-03 15:42:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5e6 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_beginner_mission_rewards
req = SaoGetMBeginnerMissionRewardsRequest ( header , request )
tbl = self . load_data_csv ( ' BeginnerMissionRewards ' )
resp = SaoGetMBeginnerMissionRewardsResponse ( tbl )
return resp . make ( )
2023-06-03 15:42:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5e8 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_beginner_mission_seat_conditions
req = SaoGetMBeginnerMissionSeatConditionsRequest ( header , request )
tbl = self . load_data_csv ( ' BeginnerMissionSeatConditions ' )
resp = SaoGetMBeginnerMissionSeatConditionsResponse ( tbl )
return resp . make ( )
2023-06-03 15:42:50 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ea ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_beginner_mission_seat_rewards
req = SaoGetMBeginnerMissionSeatRewardsRequest ( header , request )
tbl = self . load_data_csv ( ' BeginnerMissionSeatRewards ' )
resp = SaoGetMBeginnerMissionSeatRewardsResponse ( tbl )
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ec ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_event_items
tbl = self . load_data_csv ( ' EventItems ' )
resp = SaoGetMEventItemsResponse ( tbl )
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5ee ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_event_monsters
req = SaoGetMEventMonstersRequest ( header , request )
tbl = self . load_data_csv ( ' EventMonsters ' )
resp = SaoGetMEventMonstersResponse ( tbl )
return resp . make ( )
2023-07-02 18:25:24 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5f0 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_yui_medal_bonuses
tbl = self . load_data_csv ( ' YuiMedalBonus ' )
resp = SaoGetMYuiMedalBonusesResponse ( tbl )
2023-06-02 17:53:49 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d5f2 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_yui_medal_bonus_conditions
tbl = self . load_data_csv ( ' YuiMedalBonusCondition ' )
resp = SaoGetMYuiMedalBonusConditionsResponse ( tbl )
return resp . make ( )
2023-06-28 16:54:16 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5f4 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_medals
tbl = self . load_data_csv ( ' GashaMedals ' )
resp = SaoGetMGashaMedalsResponse ( tbl )
return resp . make ( )
2023-06-28 16:54:16 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5f6 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_medal_types
tbl = self . load_data_csv ( ' GashaMedalTypes ' )
resp = SaoGetMGashaMedalTypesResponse ( tbl )
return resp . make ( )
2023-06-28 16:54:16 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5f8 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_medal_settings
req = SaoGetMGashaMedalSettingsRequest ( header , request )
tbl = self . load_data_csv ( ' GashaMedalSettings ' )
resp = SaoGetMGashaMedalSettingsResponse ( tbl )
2023-05-30 22:03:52 +00:00
return resp . make ( )
2023-06-02 17:53:49 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5fa ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_medal_bonuses
tbl = self . load_data_csv ( ' GashaMedalBonuses ' )
resp = SaoGetMGashaMedalBonusesResponse ( tbl )
return resp . make ( )
2023-06-28 16:54:16 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5fc ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_medal_shops
tbl = self . load_data_csv ( ' GashaMedalShops ' )
resp = SaoGetMGashaMedalShopsResponse ( tbl )
return resp . make ( )
2023-06-28 16:54:16 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d5fe ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data/get_m_gasha_medal_shop_items
req = SaoGetMGashaMedalShopItemsRequest ( header , request )
tbl = self . load_data_csv ( ' GashaMedalShopItems ' )
resp = SaoGetMGashaMedalShopItemsResponse ( tbl )
2023-06-24 22:48:48 +00:00
return resp . make ( )
2023-06-28 01:32:46 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d600 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mres_earn_campaign_applications
tbl = self . load_data_csv ( ' ResEarnCampaignApplications ' )
resp = SaoGetMResEarnCampaignApplicationsResponse ( tbl )
2023-06-28 01:32:46 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d602 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mres_earn_campaign_application_products
req = SaoGetMResEarnCampaignApplicationProductsRequest ( header , request )
tbl = self . load_data_csv ( ' ResEarnCampaignApplicationProducts ' )
resp = SaoGetMResEarnCampaignApplicationProductsResponse ( tbl )
2023-06-28 01:32:46 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d604 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mres_earn_campaign_shops
tbl = self . load_data_csv ( ' ResEarnCampaignShops ' )
resp = SaoGetMResEarnCampaignShopsResponse ( tbl )
2023-06-28 01:32:46 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d606 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mres_earn_campaign_shop_items
req = SaoGetMResEarnCampaignShopItemsRequest ( header , request )
tbl = self . load_data_csv ( ' ResEarnCampaignShopItems ' )
resp = SaoGetMResEarnCampaignShopItemsResponse ( tbl )
2023-06-28 04:18:02 +00:00
return resp . make ( )
2023-06-28 16:54:16 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d608 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mpaying_yui_medal_bonuses
tbl = self . load_data_csv ( ' PayingYuiMedalBonuses ' )
resp = SaoGetMPayingYuiMedalBonusesResponse ( tbl )
2023-06-28 04:18:02 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d60a ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mac_login_bonuses
tbl = self . load_data_csv ( ' AcLoginBonuses ' )
resp = SaoGetMAcLoginBonusesResponse ( tbl )
2023-11-13 17:53:40 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d60c ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mplay_campaigns
tbl = self . load_data_csv ( ' PlayCampaigns ' )
resp = SaoGetMPlayCampaignsResponse ( tbl )
2023-11-13 22:17:27 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d60e ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mplay_campaign_rewards
req = SaoGetMPlayCampaignRewardsRequest ( header , request )
tbl = self . load_data_csv ( ' PlayCampaignRewards ' )
resp = SaoGetMPlayCampaignRewardsResponse ( tbl )
2023-11-13 22:17:27 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d610 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mgasha_free_campaigns
tbl = self . load_data_csv ( ' GashaFreeCampaigns ' )
resp = SaoGetMGashaFreeCampaignsResponse ( tbl )
2023-11-13 22:17:27 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d612 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mquest_drop_boost_campaigns
tbl = self . load_data_csv ( ' QuestDropBoostCampaigns ' )
resp = SaoGetMQuestDropBoostCampaignsResponse ( tbl )
2023-11-13 22:17:27 +00:00
return resp . make ( )
2024-06-25 18:02:53 +00:00
async def handle_d614 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mfirst_ticket_purchase_campaigns
tbl = self . load_data_csv ( ' FirstTicketPurchaseCampaigns ' )
resp = SaoGetMFirstTicketPurchaseCampaignsResponse ( tbl )
2023-11-13 22:17:27 +00:00
return resp . make ( )
2023-11-15 01:51:51 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d616 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mlinked_site_reg_campaigns
tbl = self . load_data_csv ( ' LinkedSiteRegCampaigns ' )
resp = SaoGetMLinkedSiteRegCampaignsResponse ( tbl )
2023-11-15 01:51:51 +00:00
return resp . make ( )
2023-11-15 02:07:58 +00:00
2024-06-25 18:02:53 +00:00
async def handle_d618 ( self , header : SaoRequestHeader , request : bytes , src_ip : str ) - > bytes :
# master_data2/get_mlinked_site_reg_campaign_rewards
req = SaoGetMLinkedSiteRegCampaignRewardsRequest ( header , request )
tbl = self . load_data_csv ( ' LinkedSiteRegCampaignRewards ' )
resp = SaoGetMLinkedSiteRegCampaignRewardsResponse ( tbl )
return resp . make ( )