sao: fix yui shops

This commit is contained in:
Hay1tsme 2023-11-13 17:17:27 -05:00
parent a9f72cec69
commit e035806b41
9 changed files with 373 additions and 12 deletions

View File

@ -1,6 +1,8 @@
import logging import logging
from csv import * from csv import *
from random import choice from random import choice
from typing import Dict, List
from os import path
from core.data import Data from core.data import Data
from core import CoreConfig from core import CoreConfig
@ -17,6 +19,19 @@ class SaoBase:
self.version = 0 self.version = 0
self.logger = logging.getLogger("sao") self.logger = logging.getLogger("sao")
def load_data_csv(self, file: str) -> List[Dict]:
ret = []
if path.exists(f"titles/sao/data/{file}.csv"):
with open(f"titles/sao/data/{file}.csv", "r", encoding="utf8") as f:
data = csv.DictReader(f, delimiter=',')
for x in data:
ret.append(x)
return ret
self.logger.warning(f"Failed to find csv file {file}.csv")
return ret
def handle_noop(self, header: SaoRequestHeader, request: bytes) -> bytes: def handle_noop(self, header: SaoRequestHeader, request: bytes) -> bytes:
self.logger.info(f"Using Generic handler") self.logger.info(f"Using Generic handler")
resp_thing = SaoNoopResponse(header.cmd + 1) resp_thing = SaoNoopResponse(header.cmd + 1)
@ -835,7 +850,86 @@ class SaoBase:
def handle_c700(self, header: SaoRequestHeader, request: bytes) -> bytes: def handle_c700(self, header: SaoRequestHeader, request: bytes) -> bytes:
# shop/get_shop_resource_sales_data_list # shop/get_shop_resource_sales_data_list
# TODO: Shop data # TODO: Get user shop data
req = GetShopResourceSalesDataListRequest(header, request) req = GetShopResourceSalesDataListRequest(header, request)
resp = GetShopResourceSalesDataListResponse(header.cmd + 1) resp = GetShopResourceSalesDataListResponse(header.cmd + 1)
return resp.make() return resp.make()
def handle_d100(self, header: SaoRequestHeader, request: bytes) -> bytes:
# shop/get_yui_medal_shop_user_data_list
# TODO: Get user shop data
req = GetYuiMedalShopUserDataListRequest(header, request)
resp = GetYuiMedalShopUserDataListResponse(header.cmd + 1)
return resp.make()
def handle_cf0e(self, header: SaoRequestHeader, request: bytes) -> bytes:
# gasha/get_gasha_medal_shop_user_data_list
# TODO: Get user shop data
req = GetGashaMedalShopUserDataListRequest(header, request)
resp = GetGashaMedalShopUserDataListResponse(header.cmd + 1)
return resp.make()
def handle_d5da(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_yui_medal_shops
req = GetMYuiMedalShopDataRequest(header, request)
resp = GetMYuiMedalShopDataResponse(header.cmd + 1)
shops = self.load_data_csv("YuiMedalShops")
for shop in shops:
tmp = YuiMedalShopData.from_args(int(shop['YuiMedalShopId']), shop['Name'], shop['Description'])
tmp.selling_yui_medal = int(shop['SellingYuiMedal'])
tmp.selling_col = int(shop['SellingCol'])
tmp.selling_event_item_id = int(shop['SellingEventItemId'])
tmp.selling_event_item_num = int(shop['SellingEventItemNum'])
tmp.selling_ticket_num = int(shop['SellingTicketNum'])
tmp.purchase_limit = int(shop['PurchaseLimit'])
tmp.pick_up_flag = 1 if shop['PickUpFlag'] == "True" else 0
tmp.product_category = int(shop['ProductCategory'])
tmp.sales_type = int(shop['SalesType'])
tmp.target_days = int(shop['TargetDays'])
tmp.target_hour = int(shop['TargetHour'])
tmp.interval_hour = int(shop['IntervalHour'])
tmp.sort = int(shop['Sort'])
tmp.sales_end_date = datetime(2100, 1, 1, 0, 0, 0, 0) # always open
resp.data_list.append(tmp)
return resp.make()
def handle_d5dc(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_yui_medal_shop_items
req = GetMYuiMedalShopItemsRequest(header, request)
resp = GetMYuiMedalShopItemsResponse(header.cmd + 1)
shops = self.load_data_csv("YuiMedalShopItems")
for shop in shops:
tmp = YuiMedalShopItemData.from_args(int(shop['YuiMedalShopItemId']), int(shop['YuiMedalShopId']), int(shop['CommonRewardType']), int(shop['CommonRewardId']), int(shop['CommonRewardNum']), int(shop['Strength']))
tmp.property1_property_id = int(shop['Property1PropertyId'])
tmp.property1_value1 = int(shop['Property1Value1'])
tmp.property1_value2 = int(shop['Property1Value2'])
tmp.property2_property_id = int(shop['Property2PropertyId'])
tmp.property2_value1 = int(shop['Property2Value1'])
tmp.property2_value2 = int(shop['Property2Value2'])
tmp.property3_property_id = int(shop['Property3PropertyId'])
tmp.property3_value1 = int(shop['Property3Value1'])
tmp.property3_value2 = int(shop['Property3Value2'])
tmp.property4_property_id = int(shop['Property4PropertyId'])
tmp.property4_value1 = int(shop['Property4Value1'])
tmp.property4_value2 = int(shop['Property4Value2'])
resp.data_list.append(tmp)
return resp.make()
def handle_d5fc(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data/get_m_gasha_medal_shops
pass
def handle_d604(self, header: SaoRequestHeader, request: bytes) -> bytes:
# master_data_2/get_m_res_earn_campaign_shops
pass

View File

@ -1,4 +1,4 @@
// GashaMedalShopItemId,GashaMedalShopId,CommonRewardType,CommonRewardId,CommonRewardNum,Strength,Property1PropertyId,Property1Value1,Property1Value2,Property2PropertyId,Property2Value1,Property2Value2,Property3PropertyId,Property3Value1,Property3Value2,Property4PropertyId,Property4Value1,Property4Value2 GashaMedalShopItemId,GashaMedalShopId,CommonRewardType,CommonRewardId,CommonRewardNum,Strength,Property1PropertyId,Property1Value1,Property1Value2,Property2PropertyId,Property2Value1,Property2Value2,Property3PropertyId,Property3Value1,Property3Value2,Property4PropertyId,Property4Value1,Property4Value2
15701,15701,1,101000220,1,0,1,0,0,1,0,0,2,0,0,2,0,0 15701,15701,1,101000220,1,0,1,0,0,1,0,0,2,0,0,2,0,0
15702,15702,1,102000230,1,0,1,0,0,1,0,0,2,0,0,2,0,0 15702,15702,1,102000230,1,0,1,0,0,1,0,0,2,0,0,2,0,0
15703,15703,2,101000009,1,0,204000,5,0,1,0,0,2,0,0,2,0,0 15703,15703,2,101000009,1,0,204000,5,0,1,0,0,2,0,0,2,0,0

1 // GashaMedalShopItemId GashaMedalShopItemId GashaMedalShopId CommonRewardType CommonRewardId CommonRewardNum Strength Property1PropertyId Property1Value1 Property1Value2 Property2PropertyId Property2Value1 Property2Value2 Property3PropertyId Property3Value1 Property3Value2 Property4PropertyId Property4Value1 Property4Value2
2 15701 15701 1 101000220 1 0 1 0 0 1 0 0 2 0 0 2 0 0
3 15702 15702 1 102000230 1 0 1 0 0 1 0 0 2 0 0 2 0 0
4 15703 15703 2 101000009 1 0 204000 5 0 1 0 0 2 0 0 2 0 0

View File

@ -1,4 +1,4 @@
// GashaMedalShopId,Name,GashaMedalId,UseGashaMedalNum,PurchaseLimit,StartDate,EndDate GashaMedalShopId,Name,GashaMedalId,UseGashaMedalNum,PurchaseLimit,StartDate,EndDate
15701,"≪不屈の誓い≫キリト",10002,300,-1,"2020/03/10 7:00:00","2020/03/31 2:00:00" 15701,"≪不屈の誓い≫キリト",10002,300,-1,"2020/03/10 7:00:00","2020/03/31 2:00:00"
15702,"≪明日への誓い≫アスナ",10002,300,-1,"2020/03/10 7:00:00","2020/03/31 2:00:00" 15702,"≪明日への誓い≫アスナ",10002,300,-1,"2020/03/10 7:00:00","2020/03/31 2:00:00"
15703,"ダークリパルサー",10002,60,-1,"2020/03/10 7:00:00","2020/03/31 2:00:00" 15703,"ダークリパルサー",10002,60,-1,"2020/03/10 7:00:00","2020/03/31 2:00:00"

1 // GashaMedalShopId GashaMedalShopId Name GashaMedalId UseGashaMedalNum PurchaseLimit StartDate EndDate
2 15701 ≪不屈の誓い≫キリト 10002 300 -1 2020/03/10 7:00:00 2020/03/31 2:00:00
3 15702 ≪明日への誓い≫アスナ 10002 300 -1 2020/03/10 7:00:00 2020/03/31 2:00:00
4 15703 ダークリパルサー 10002 60 -1 2020/03/10 7:00:00 2020/03/31 2:00:00

View File

@ -1,4 +1,4 @@
// ResEarnCampaignShopItemId,ResEarnCampaignShopId,CommonRewardType,CommonRewardId,CommonRewardNum,Strength,Property1PropertyId,Property1Value1,Property1Value2,Property2PropertyId,Property2Value1,Property2Value2,Property3PropertyId,Property3Value1,Property3Value2,Property4PropertyId,Property4Value1,Property4Value2 ResEarnCampaignShopItemId,ResEarnCampaignShopId,CommonRewardType,CommonRewardId,CommonRewardNum,Strength,Property1PropertyId,Property1Value1,Property1Value2,Property2PropertyId,Property2Value1,Property2Value2,Property3PropertyId,Property3Value1,Property3Value2,Property4PropertyId,Property4Value1,Property4Value2
15701,15701,1,101000220,1,0,1,0,0,1,0,0,2,0,0,2,0,0 15701,15701,1,101000220,1,0,1,0,0,1,0,0,2,0,0,2,0,0
15702,15702,1,102000230,1,0,1,0,0,1,0,0,2,0,0,2,0,0 15702,15702,1,102000230,1,0,1,0,0,1,0,0,2,0,0,2,0,0
15703,15703,2,101000009,1,0,204000,5,0,1,0,0,2,0,0,2,0,0 15703,15703,2,101000009,1,0,204000,5,0,1,0,0,2,0,0,2,0,0

1 // ResEarnCampaignShopItemId ResEarnCampaignShopItemId ResEarnCampaignShopId CommonRewardType CommonRewardId CommonRewardNum Strength Property1PropertyId Property1Value1 Property1Value2 Property2PropertyId Property2Value1 Property2Value2 Property3PropertyId Property3Value1 Property3Value2 Property4PropertyId Property4Value1 Property4Value2
2 15701 15701 15701 1 101000220 1 0 1 0 0 1 0 0 2 0 0 2 0 0
3 15702 15702 15702 1 102000230 1 0 1 0 0 1 0 0 2 0 0 2 0 0
4 15703 15703 15703 2 101000009 1 0 204000 5 0 1 0 0 2 0 0 2 0 0

View File

@ -1,4 +1,4 @@
// ResEarnCampaignShopId,ResEarnCampaignApplicationId,Name,SellingYuiMedal,SellingCol,SellingEventItemId,SellingEventItemNum,PurchaseLimit,GetApplicationPoint,StartDate,EndDate ResEarnCampaignShopId,ResEarnCampaignApplicationId,Name,SellingYuiMedal,SellingCol,SellingEventItemId,SellingEventItemNum,PurchaseLimit,GetApplicationPoint,StartDate,EndDate
15701,10001,"≪不屈の誓い≫キリト",-1,1,-1,-1,-1,1,"2020/01/01 7:00:00","2020/03/31 2:00:00" 15701,10001,"≪不屈の誓い≫キリト",-1,1,-1,-1,-1,1,"2020/01/01 7:00:00","2020/03/31 2:00:00"
15702,10001,"≪明日への誓い≫アスナ",-1,12,-1,-1,-1,1,"2020/01/01 7:00:00","2020/03/31 2:00:00" 15702,10001,"≪明日への誓い≫アスナ",-1,12,-1,-1,-1,1,"2020/01/01 7:00:00","2020/03/31 2:00:00"
15703,10001,"ダークリパルサー",-1,123,-1,-1,-1,1,"2020/01/01 7:00:00","2020/03/31 2:00:00" 15703,10001,"ダークリパルサー",-1,123,-1,-1,-1,1,"2020/01/01 7:00:00","2020/03/31 2:00:00"

1 // ResEarnCampaignShopId ResEarnCampaignShopId ResEarnCampaignApplicationId Name SellingYuiMedal SellingCol SellingEventItemId SellingEventItemNum PurchaseLimit GetApplicationPoint StartDate EndDate
2 15701 15701 10001 ≪不屈の誓い≫キリト -1 1 -1 -1 -1 1 2020/01/01 7:00:00 2020/03/31 2:00:00
3 15702 15702 10001 ≪明日への誓い≫アスナ -1 12 -1 -1 -1 1 2020/01/01 7:00:00 2020/03/31 2:00:00
4 15703 15703 10001 ダークリパルサー -1 123 -1 -1 -1 1 2020/01/01 7:00:00 2020/03/31 2:00:00

View File

@ -1,4 +1,4 @@
// YuiMedalShopItemId,YuiMedalShopId,CommonRewardType,CommonRewardId,CommonRewardNum,Strength,Property1PropertyId,Property1Value1,Property1Value2,Property2PropertyId,Property2Value1,Property2Value2,Property3PropertyId,Property3Value1,Property3Value2,Property4PropertyId,Property4Value1,Property4Value2 YuiMedalShopItemId,YuiMedalShopId,CommonRewardType,CommonRewardId,CommonRewardNum,Strength,Property1PropertyId,Property1Value1,Property1Value2,Property2PropertyId,Property2Value1,Property2Value2,Property3PropertyId,Property3Value1,Property3Value2,Property4PropertyId,Property4Value1,Property4Value2
1,1,1,101000190,1,0,1,0,0,1,0,0,2,0,0,2,0,0 1,1,1,101000190,1,0,1,0,0,1,0,0,2,0,0,2,0,0
2,2,1,110000150,1,0,1,0,0,1,0,0,2,0,0,2,0,0 2,2,1,110000150,1,0,1,0,0,1,0,0,2,0,0,2,0,0
3,3,2,120000003,1,0,302000,10,0,301900,20,0,2,0,0,2,0,0 3,3,2,120000003,1,0,302000,10,0,301900,20,0,2,0,0,2,0,0

1 // YuiMedalShopItemId YuiMedalShopItemId YuiMedalShopId CommonRewardType CommonRewardId CommonRewardNum Strength Property1PropertyId Property1Value1 Property1Value2 Property2PropertyId Property2Value1 Property2Value2 Property3PropertyId Property3Value1 Property3Value2 Property4PropertyId Property4Value1 Property4Value2
2 1 1 1 101000190 1 0 1 0 0 1 0 0 2 0 0 2 0 0
3 2 2 1 110000150 1 0 1 0 0 1 0 0 2 0 0 2 0 0
4 3 3 2 120000003 1 0 302000 10 0 301900 20 0 2 0 0 2 0 0

View File

@ -1,4 +1,4 @@
// YuiMedalShopId,Name,Description,SellingYuiMedal,SellingCol,SellingEventItemId,SellingEventItemNum,SellingTicketNum,PurchaseLimit,PickUpFlag,ProductCategory,SalesType,TargetDays,TargetHour,IntervalHour,SalesStartDate,SalesEndDate,Sort YuiMedalShopId,Name,Description,SellingYuiMedal,SellingCol,SellingEventItemId,SellingEventItemNum,SellingTicketNum,PurchaseLimit,PickUpFlag,ProductCategory,SalesType,TargetDays,TargetHour,IntervalHour,SalesStartDate,SalesEndDate,Sort
1,"≪想い馳せる窓辺≫キリト",,5,-1,0,-1,-1,-1,True,0,0,0,0,0,"2019/08/01","2019/11/01 2:00:00",0 1,"≪想い馳せる窓辺≫キリト",,5,-1,0,-1,-1,-1,True,0,0,0,0,0,"2019/08/01","2019/11/01 2:00:00",0
2,"≪悪戯なオネーサン≫アルゴ",,5,-1,0,-1,-1,-1,True,0,0,0,0,0,"2019/08/01","2019/11/01 2:00:00",0 2,"≪悪戯なオネーサン≫アルゴ",,5,-1,0,-1,-1,-1,True,0,0,0,0,0,"2019/08/01","2019/11/01 2:00:00",0
3,"ネックレス",,2,-1,0,-1,-1,-1,False,0,0,0,0,0,"2019/08/01","2019/11/01 2:00:00",0 3,"ネックレス",,2,-1,0,-1,-1,-1,False,0,0,0,0,0,"2019/08/01","2019/11/01 2:00:00",0

1 // YuiMedalShopId YuiMedalShopId Name Description SellingYuiMedal SellingCol SellingEventItemId SellingEventItemNum SellingTicketNum PurchaseLimit PickUpFlag ProductCategory SalesType TargetDays TargetHour IntervalHour SalesStartDate SalesEndDate Sort
2 1 ≪想い馳せる窓辺≫キリト 5 -1 0 -1 -1 -1 True 0 0 0 0 0 2019/08/01 2019/11/01 2:00:00 0
3 2 ≪悪戯なオネーサン≫アルゴ 5 -1 0 -1 -1 -1 True 0 0 0 0 0 2019/08/01 2019/11/01 2:00:00 0
4 3 ネックレス 2 -1 0 -1 -1 -1 False 0 0 0 0 0 2019/08/01 2019/11/01 2:00:00 0

View File

@ -3116,3 +3116,81 @@ class GetShopResourceSalesDataListResponse(SaoBaseResponse):
self.header.length = len(ret) self.header.length = len(ret)
return super().make() + ret return super().make() + ret
class GetYuiMedalShopUserDataListRequest(SaoBaseRequest):
def __init__(self, header: SaoRequestHeader, data: bytes) -> None:
super().__init__(header, data)
off = 0
user_id = decode_str(data, off)
self.user_id = user_id[0]
off += user_id[1]
class GetYuiMedalShopUserDataListResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.user_data_list: List[YuiMedalShopUserData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.user_data_list)
self.header.length = len(ret)
return super().make() + ret
class GetGashaMedalShopUserDataListRequest(SaoBaseRequest):
def __init__(self, header: SaoRequestHeader, data: bytes) -> None:
super().__init__(header, data)
off = 0
user_id = decode_str(data, off)
self.user_id = user_id[0]
off += user_id[1]
class GetGashaMedalShopUserDataListResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[GashaMedalShopUserData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
self.header.length = len(ret)
return super().make() + ret
class GetMYuiMedalShopDataRequest(SaoBaseRequest):
def __init__(self, header: SaoRequestHeader, data: bytes) -> None:
super().__init__(header, data)
self.dummy = decode_byte(data, 0)
class GetMYuiMedalShopDataResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[YuiMedalShopData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
self.header.length = len(ret)
return super().make() + ret
class GetMYuiMedalShopItemsRequest(SaoBaseRequest):
def __init__(self, header: SaoRequestHeader, data: bytes) -> None:
super().__init__(header, data)
self.dummy = decode_byte(data, 0)
class GetMYuiMedalShopItemsResponse(SaoBaseResponse):
def __init__(self, cmd_id: int) -> None:
super().__init__(cmd_id)
self.result = 1 # byte
self.data_list: List[YuiMedalShopItemData] = []
def make(self) -> bytes:
ret = encode_byte(self.result)
ret += encode_arr_cls(self.data_list)
self.header.length = len(ret)
return super().make() + ret

View File

@ -594,7 +594,7 @@ class ShopResourceSalesData(BaseHelper):
self._sz += sales_resource_data_list[1] self._sz += sales_resource_data_list[1]
@classmethod @classmethod
def from_args(cls, resource_id: str = "0", discharge_id: int = "0", remaining: int = 0, purchased: int = 0) -> "ShopResourceSalesData": def from_args(cls, resource_id: str = "0", discharge_id: str = "0", remaining: int = 0, purchased: int = 0) -> "ShopResourceSalesData":
ret = cls(b"\x00" * 20, 0) ret = cls(b"\x00" * 20, 0)
ret.user_shop_resource_id = resource_id ret.user_shop_resource_id = resource_id
ret.discharge_user_id = discharge_id ret.discharge_user_id = discharge_id
@ -611,3 +611,192 @@ class ShopResourceSalesData(BaseHelper):
ret += encode_arr_cls(self.sales_resource_data_list) ret += encode_arr_cls(self.sales_resource_data_list)
return ret return ret
class YuiMedalShopUserData(BaseHelper):
def __init__(self, data: bytes, offset: int) -> None:
super().__init__(data, offset)
self.yui_medal_shop_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.purchase_num = decode_int(data, offset + self._sz)
self._sz += INT_OFF
last_purchase_date = decode_str(data, offset + self._sz)
self.last_purchase_date = last_purchase_date[0]
self._sz += last_purchase_date[1]
@classmethod
def from_args(cls, yui_medal_shop_id: int = 0, purchase_num: int = 0, last_purchase_date: datetime = datetime.fromtimestamp(0)) -> "YuiMedalShopUserData":
ret = cls(b"\x00" * 20, 0)
ret.yui_medal_shop_id = yui_medal_shop_id
ret.purchase_num = purchase_num
ret.last_purchase_date = last_purchase_date
def make(self) -> bytes:
ret = encode_int(self.yui_medal_shop_id)
ret += encode_int(self.purchase_num)
ret += encode_str(fmt_dt(self.last_purchase_date))
return ret
class GashaMedalShopUserData(BaseHelper):
def __init__(self, data: bytes, offset: int) -> None:
super().__init__(data, offset)
self.gasha_medal_shop_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.purchase_num = decode_int(data, offset + self._sz)
self._sz += INT_OFF
@classmethod
def from_args(cls, gasha_medal_shop_id: int = 0, purchase_num: int = 0) -> "GashaMedalShopUserData":
ret = cls(b"\x00" * 20, 0)
ret.gasha_medal_shop_id = gasha_medal_shop_id
ret.purchase_num = purchase_num
def make(self) -> bytes:
ret = encode_int(self.gasha_medal_shop_id)
ret += encode_int(self.purchase_num)
return ret
class YuiMedalShopData(BaseHelper):
def __init__(self, data: bytes, offset: int) -> None:
super().__init__(data, offset)
self.yui_medal_shop_id = decode_int(data, offset + self._sz)
name = decode_str(data, offset + self._sz)
self.name = name[0]
self._sz += name[1]
description = decode_str(data, offset + self._sz)
self.description = description[0]
self._sz += description[1]
self.selling_yui_medal = decode_short(data, offset + self._sz)
self.selling_col = decode_int(data, offset + self._sz)
self.selling_event_item_id = decode_int(data, offset + self._sz)
self.selling_event_item_num = decode_int(data, offset + self._sz)
self.selling_ticket_num = decode_int(data, offset + self._sz)
self.purchase_limit = decode_short(data, offset + self._sz)
self.pick_up_flag = decode_byte(data, offset + self._sz)
self.product_category = decode_byte(data, offset + self._sz)
self.sales_type = decode_byte(data, offset + self._sz)
self.target_days = decode_byte(data, offset + self._sz)
self.target_hour = decode_byte(data, offset + self._sz)
self.interval_hour = decode_byte(data, offset + self._sz)
sales_start_date = decode_str(data, offset + self._sz)
self.sales_start_date = prs_dt(sales_start_date[0])
self._sz += sales_start_date[1]
sales_end_date = decode_str(data, offset + self._sz)
self.sales_end_date = prs_dt(sales_end_date[0])
self._sz += sales_end_date[1]
self.sort = decode_byte(data, offset + self._sz)
@classmethod
def from_args(cls, shop_id: int = 0, name: str = "", desc: str = "") -> "YuiMedalShopData":
ret = cls(b"\x00" * 43, 0)
ret.yui_medal_shop_id = shop_id
ret.name = name
ret.description = desc
def make(self) -> bytes:
ret = encode_int(self.yui_medal_shop_id)
ret += encode_str(self.name)
ret += encode_str(self.description)
ret += encode_short(self.selling_yui_medal)
ret += encode_int(self.selling_col)
ret += encode_int(self.selling_event_item_id)
ret += encode_int(self.selling_event_item_num)
ret += encode_int(self.selling_ticket_num)
ret += encode_short(self.purchase_limit)
ret += encode_byte(self.pick_up_flag)
ret += encode_byte(self.product_category)
ret += encode_byte(self.sales_type)
ret += encode_byte(self.target_days)
ret += encode_byte(self.target_hour)
ret += encode_byte(self.interval_hour)
ret += encode_str(self.sales_end_date)
ret += encode_str(self.sales_end_date)
ret += encode_byte(self.sort)
return ret
class YuiMedalShopItemData(BaseHelper):
def __init__(self, data: bytes, offset: int) -> None:
super().__init__(data, offset)
self.yui_medal_shop_item_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.yui_medal_shop_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.common_reward_type = decode_byte(data, offset + self._sz)
self._sz += BYTE_OFF
self.common_reward_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.common_reward_num = decode_short(data, offset + self._sz)
self._sz += SHORT_OFF
self.strength = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property1_property_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property1_value1 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property1_value2 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property2_property_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property2_value1 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property2_value2 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property3_property_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property3_value1 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property3_value2 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property4_property_id = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property4_value1 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
self.property4_value2 = decode_int(data, offset + self._sz)
self._sz += INT_OFF
@classmethod
def from_args(cls, item_id: int = 0, shop_id: int = 0, reward_type: int = 0, reward_id: int = 0, reward_num: int = 0, strength: int = 0) -> "YuiMedalShopItemData":
ret = cls(b"\x00" * 67, 0)
ret.yui_medal_shop_item_id = item_id
ret.yui_medal_shop_id = shop_id
ret.common_reward_type = reward_type
ret.common_reward_id = reward_id
ret.common_reward_num = reward_num
ret.strength = strength
return ret
def make(self) -> bytes:
ret = encode_int(self.yui_medal_shop_item_id)
ret += encode_int(self.yui_medal_shop_id)
ret += encode_byte(self.common_reward_type)
ret += encode_int(self.common_reward_id)
ret += encode_short(self.common_reward_num)
ret += encode_int(self.strength)
ret += encode_int(self.property1_property_id)
ret += encode_int(self.property1_value1)
ret += encode_int(self.property1_value2)
ret += encode_int(self.property2_property_id)
ret += encode_int(self.property2_value1)
ret += encode_int(self.property2_value2)
ret += encode_int(self.property3_property_id)
ret += encode_int(self.property3_value1)
ret += encode_int(self.property3_value2)
ret += encode_int(self.property4_property_id)
ret += encode_int(self.property4_value1)
ret += encode_int(self.property4_value2)
return ret