forked from Dniel97/artemis
adding partial synthetize system for SAO
This commit is contained in:
parent
db77e61b79
commit
cf6cfdbd3b
@ -244,6 +244,77 @@ class SaoBase:
|
||||
resp = SaoCheckProfileCardUsedRewardResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
|
||||
return resp.make()
|
||||
|
||||
def handle_c816(self, request: Any) -> bytes: # not fully done yet
|
||||
#custom/synthesize_enhancement_equipment
|
||||
req = bytes.fromhex(request)[24:]
|
||||
|
||||
req_struct = Struct(
|
||||
Padding(20),
|
||||
"ticket_id" / Bytes(1), # needs to be parsed as an int
|
||||
Padding(1),
|
||||
"user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
|
||||
"user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
|
||||
"origin_user_equipment_id_size" / Rebuild(Int32ub, len_(this.origin_user_equipment_id) * 2), # calculates the length of the origin_user_equipment_id
|
||||
"origin_user_equipment_id" / PaddedString(this.origin_user_equipment_id_size, "utf_16_le"), # origin_user_equipment_id is a (zero) padded string
|
||||
Padding(3),
|
||||
"material_common_reward_user_data_list_length" / Rebuild(Int8ub, len_(this.material_common_reward_user_data_list)), # material_common_reward_user_data_list is a byte,
|
||||
"material_common_reward_user_data_list" / Array(this.material_common_reward_user_data_list_length, Struct(
|
||||
"common_reward_type" / Int16ub, # team_no is a byte
|
||||
"user_common_reward_id_size" / Rebuild(Int32ub, len_(this.user_common_reward_id) * 2), # calculates the length of the user_common_reward_id
|
||||
"user_common_reward_id" / PaddedString(this.user_common_reward_id_size, "utf_16_le"), # user_common_reward_id is a (zero) padded string
|
||||
)),
|
||||
)
|
||||
|
||||
req_data = req_struct.parse(req)
|
||||
|
||||
user_id = req_data.user_id
|
||||
synthesize_equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id)
|
||||
|
||||
for i in range(0,req_data.material_common_reward_user_data_list_length):
|
||||
|
||||
itemList = self.game_data.static.get_item_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
heroList = self.game_data.static.get_hero_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
equipmentList = self.game_data.static.get_equipment_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
|
||||
if itemList:
|
||||
equipment_exp = 2000 + int(synthesize_equipment_data["enhancement_exp"])
|
||||
# Then delete the used item, function for items progression is not done yet...
|
||||
|
||||
if equipmentList:
|
||||
equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
equipment_exp = int(equipment_data["enhancement_exp"]) + int(synthesize_equipment_data["enhancement_exp"])
|
||||
self.game_data.item.remove_equipment(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
|
||||
if heroList:
|
||||
hero_data = self.game_data.item.get_hero_log(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
equipment_exp = int(hero_data["log_exp"]) + int(synthesize_equipment_data["enhancement_exp"])
|
||||
self.game_data.item.remove_hero_log(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
|
||||
|
||||
self.game_data.item.put_equipment_data(req_data.user_id, int(req_data.origin_user_equipment_id), synthesize_equipment_data["enhancement_value"], equipment_exp, 0, 0, 0)
|
||||
|
||||
profile = self.game_data.profile.get_profile(req_data.user_id)
|
||||
new_col = int(profile["own_col"]) - 100
|
||||
|
||||
# Update profile
|
||||
|
||||
self.game_data.profile.put_profile(
|
||||
req_data.user_id,
|
||||
profile["user_type"],
|
||||
profile["nick_name"],
|
||||
profile["rank_num"],
|
||||
profile["rank_exp"],
|
||||
new_col,
|
||||
profile["own_vp"],
|
||||
profile["own_yui_medal"],
|
||||
profile["setting_title_id"]
|
||||
)
|
||||
|
||||
# Load the item again to push to the response handler
|
||||
synthesize_equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id)
|
||||
|
||||
resp = SaoSynthesizeEnhancementEquipmentResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, synthesize_equipment_data)
|
||||
return resp.make()
|
||||
|
||||
def handle_c806(self, request: Any) -> bytes:
|
||||
#custom/change_party
|
||||
req = bytes.fromhex(request)[24:]
|
||||
|
@ -1775,3 +1775,140 @@ class SaoCheckProfileCardUsedRewardResponse(SaoBaseResponse):
|
||||
|
||||
self.length = len(resp_data)
|
||||
return super().make() + resp_data
|
||||
|
||||
class SaoSynthesizeEnhancementEquipment(SaoBaseRequest):
|
||||
def __init__(self, data: bytes) -> None:
|
||||
super().__init__(data)
|
||||
|
||||
class SaoSynthesizeEnhancementEquipmentResponse(SaoBaseResponse):
|
||||
def __init__(self, cmd, synthesize_equipment_data) -> None:
|
||||
super().__init__(cmd)
|
||||
self.result = 1
|
||||
equipment_level = 0
|
||||
|
||||
# Calculate level based off experience and the CSV list
|
||||
with open(r'titles/sao/data/EquipmentLevel.csv') as csv_file:
|
||||
csv_reader = csv.reader(csv_file, delimiter=',')
|
||||
line_count = 0
|
||||
data = []
|
||||
rowf = False
|
||||
for row in csv_reader:
|
||||
if rowf==False:
|
||||
rowf=True
|
||||
else:
|
||||
data.append(row)
|
||||
|
||||
exp = synthesize_equipment_data[4]
|
||||
|
||||
for e in range(0,len(data)):
|
||||
if exp>=int(data[e][1]) and exp<int(data[e+1][1]):
|
||||
equipment_level = int(data[e][0])
|
||||
break
|
||||
|
||||
# equipment_user_data_list
|
||||
self.user_equipment_id = str(synthesize_equipment_data[2]) #str
|
||||
self.equipment_id = synthesize_equipment_data[2] #int
|
||||
self.enhancement_value = equipment_level #short
|
||||
self.max_enhancement_value_extended_num = equipment_level #short
|
||||
self.enhancement_exp = synthesize_equipment_data[4] #int
|
||||
self.possible_awakening_flag = synthesize_equipment_data[7] #byte
|
||||
self.awakening_stage = synthesize_equipment_data[5] #short
|
||||
self.awakening_exp = synthesize_equipment_data[6] #int
|
||||
self.property1_property_id = 0 #int
|
||||
self.property1_value1 = 0 #int
|
||||
self.property1_value2 = 0 #int
|
||||
self.property2_property_id = 0 #int
|
||||
self.property2_value1 = 0 #int
|
||||
self.property2_value2 = 0 #int
|
||||
self.property3_property_id = 0 #int
|
||||
self.property3_value1 = 0 #int
|
||||
self.property3_value2 = 0 #int
|
||||
self.property4_property_id = 0 #int
|
||||
self.property4_value1 = 0 #int
|
||||
self.property4_value2 = 0 #int
|
||||
self.converted_card_num = 1 #short
|
||||
self.shop_purchase_flag = 1 #byte
|
||||
self.protect_flag = 0 #byte
|
||||
self.get_date = "20230101120000" #str
|
||||
|
||||
def make(self) -> bytes:
|
||||
|
||||
after_equipment_user_data_struct = Struct(
|
||||
"user_equipment_id_size" / Int32ub, # big endian
|
||||
"user_equipment_id" / Int16ul[9], #string
|
||||
"equipment_id" / Int32ub, #int
|
||||
"enhancement_value" / Int16ub, #short
|
||||
"max_enhancement_value_extended_num" / Int16ub, #short
|
||||
"enhancement_exp" / Int32ub, #int
|
||||
"possible_awakening_flag" / Int8ul, # result is either 0 or 1
|
||||
"awakening_stage" / Int16ub, #short
|
||||
"awakening_exp" / Int32ub, #int
|
||||
"property1_property_id" / Int32ub,
|
||||
"property1_value1" / Int32ub,
|
||||
"property1_value2" / Int32ub,
|
||||
"property2_property_id" / Int32ub,
|
||||
"property2_value1" / Int32ub,
|
||||
"property2_value2" / Int32ub,
|
||||
"property3_property_id" / Int32ub,
|
||||
"property3_value1" / Int32ub,
|
||||
"property3_value2" / Int32ub,
|
||||
"property4_property_id" / Int32ub,
|
||||
"property4_value1" / Int32ub,
|
||||
"property4_value2" / Int32ub,
|
||||
"converted_card_num" / Int16ub,
|
||||
"shop_purchase_flag" / Int8ul, # result is either 0 or 1
|
||||
"protect_flag" / Int8ul, # result is either 0 or 1
|
||||
"get_date_size" / Int32ub, # big endian
|
||||
"get_date" / Int16ul[len(self.get_date)],
|
||||
)
|
||||
|
||||
# create a resp struct
|
||||
resp_struct = Struct(
|
||||
"result" / Int8ul, # result is either 0 or 1
|
||||
"after_equipment_user_data_size" / Rebuild(Int32ub, len_(this.after_equipment_user_data)), # big endian
|
||||
"after_equipment_user_data" / Array(this.after_equipment_user_data_size, after_equipment_user_data_struct),
|
||||
)
|
||||
|
||||
resp_data = resp_struct.parse(resp_struct.build(dict(
|
||||
result=self.result,
|
||||
after_equipment_user_data_size=0,
|
||||
after_equipment_user_data=[],
|
||||
)))
|
||||
|
||||
synthesize_equipment_data = dict(
|
||||
user_equipment_id_size=len(self.user_equipment_id) * 2,
|
||||
user_equipment_id=[ord(x) for x in self.user_equipment_id],
|
||||
equipment_id=self.equipment_id,
|
||||
enhancement_value=self.enhancement_value,
|
||||
max_enhancement_value_extended_num=self.max_enhancement_value_extended_num,
|
||||
enhancement_exp=self.enhancement_exp,
|
||||
possible_awakening_flag=self.possible_awakening_flag,
|
||||
awakening_stage=self.awakening_stage,
|
||||
awakening_exp=self.awakening_exp,
|
||||
property1_property_id=self.property1_property_id,
|
||||
property1_value1=self.property1_value1,
|
||||
property1_value2=self.property1_value2,
|
||||
property2_property_id=self.property2_property_id,
|
||||
property2_value1=self.property2_value1,
|
||||
property2_value2=self.property2_value2,
|
||||
property3_property_id=self.property3_property_id,
|
||||
property3_value1=self.property3_value1,
|
||||
property3_value2=self.property3_value2,
|
||||
property4_property_id=self.property4_property_id,
|
||||
property4_value1=self.property4_value1,
|
||||
property4_value2=self.property4_value2,
|
||||
converted_card_num=self.converted_card_num,
|
||||
shop_purchase_flag=self.shop_purchase_flag,
|
||||
protect_flag=self.protect_flag,
|
||||
get_date_size=len(self.get_date) * 2,
|
||||
get_date=[ord(x) for x in self.get_date],
|
||||
|
||||
)
|
||||
|
||||
resp_data.after_equipment_user_data.append(synthesize_equipment_data)
|
||||
|
||||
# finally, rebuild the resp_data
|
||||
resp_data = resp_struct.build(resp_data)
|
||||
|
||||
self.length = len(resp_data)
|
||||
return super().make() + resp_data
|
@ -193,6 +193,14 @@ class SaoItemData(BaseData):
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
def get_user_equipment(self, user_id: int, equipment_id: int) -> Optional[Dict]:
|
||||
sql = equipment_data.select(equipment_data.c.user == user_id and equipment_data.c.equipment_id == equipment_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_user_equipments(
|
||||
self, user_id: int
|
||||
) -> Optional[List[Row]]:
|
||||
@ -275,3 +283,30 @@ class SaoItemData(BaseData):
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def remove_hero_log(self, user_id: int, user_hero_log_id: int) -> None:
|
||||
sql = hero_log_data.delete(
|
||||
and_(
|
||||
hero_log_data.c.user == user_id,
|
||||
hero_log_data.c.user_hero_log_id == user_hero_log_id,
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to remove hero log! profile: {user_id}, user_hero_log_id: {user_hero_log_id}"
|
||||
)
|
||||
return None
|
||||
|
||||
def remove_equipment(self, user_id: int, equipment_id: int) -> None:
|
||||
sql = equipment_data.delete(
|
||||
and_(equipment_data.c.user == user_id, equipment_data.c.equipment_id == equipment_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to remove equipment! profile: {user_id}, equipment_id: {equipment_id}"
|
||||
)
|
||||
return None
|
@ -282,6 +282,14 @@ class SaoStaticData(BaseData):
|
||||
return None
|
||||
return [list[2] for list in result.fetchall()]
|
||||
|
||||
def get_item_id(self, itemId: int) -> Optional[Dict]:
|
||||
sql = item.select(item.c.itemId == itemId)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_item_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
|
||||
sql = item.select(item.c.version == version and item.c.enabled == enabled).order_by(
|
||||
item.c.itemId.asc()
|
||||
|
Loading…
Reference in New Issue
Block a user