From 2b4ac0638997e11559756aa19a3816d478cabfc2 Mon Sep 17 00:00:00 2001 From: Midorica Date: Mon, 29 May 2023 19:21:26 -0400 Subject: [PATCH] adding more profile & hero saving stuff to SAO --- titles/sao/base.py | 56 ++++++++++++++++++++++++++- titles/sao/schema/item.py | 75 ++++++++++++++++++++++++++++++------ titles/sao/schema/profile.py | 32 +++++++++++++++ 3 files changed, 150 insertions(+), 13 deletions(-) diff --git a/titles/sao/base.py b/titles/sao/base.py index 685d330..609c5ac 100644 --- a/titles/sao/base.py +++ b/titles/sao/base.py @@ -329,10 +329,18 @@ class SaoBase: user_id = req_data.user_id profile_data = self.game_data.profile.get_profile(user_id) + self.game_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(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data) return resp.make() - def handle_c908(self, request: Any) -> bytes: + def handle_c908(self, request: Any) -> bytes: # Level calculation missing for the profile and heroes #quest/episode_play_end req = bytes.fromhex(request)[24:] @@ -424,6 +432,52 @@ class SaoBase: req_data = req_struct.parse(req) + # Update the profile + profile = self.game_data.profile.get_profile(req_data.user_id) + + exp = int(profile["rank_exp"]) + 100 #always 100 extra exp for some reason + col = int(profile["own_col"]) + int(req_data.base_get_data[0].get_col) + + updated_profile = self.game_data.profile.put_profile( + req_data.user_id, + profile["user_type"], + profile["nick_name"], + profile["rank_num"], + exp, + col, + profile["own_vp"], + profile["own_yui_medal"], + profile["setting_title_id"] + ) + + # Update heroes from the used party + play_session = self.game_data.item.get_session(req_data.user_id) + session_party = self.game_data.item.get_hero_party(req_data.user_id, play_session["user_party_team_id"]) + + 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,len(hero_list)): + hero_data = self.game_data.item.get_hero_log(req_data.user_id, hero_list[i]) + + log_exp = int(hero_data["log_exp"]) + int(req_data.base_get_data[0].get_hero_log_exp) + + self.game_data.item.put_hero_log( + req_data.user_id, + hero_data["user_hero_log_id"], + hero_data["log_level"], + log_exp, + hero_data["main_weapon"], + hero_data["sub_equipment"], + hero_data["skill_slot1_skill_id"], + hero_data["skill_slot2_skill_id"], + hero_data["skill_slot3_skill_id"], + hero_data["skill_slot4_skill_id"], + hero_data["skill_slot5_skill_id"] + ) + resp = SaoEpisodePlayEndResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1) return resp.make() diff --git a/titles/sao/schema/item.py b/titles/sao/schema/item.py index a0d5123..f6d030e 100644 --- a/titles/sao/schema/item.py +++ b/titles/sao/schema/item.py @@ -49,7 +49,42 @@ hero_party = Table( mysql_charset="utf8mb4", ) +sessions = Table( + "sao_play_sessions", + metadata, + Column("id", Integer, primary_key=True, nullable=False), + Column( + "user", + ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), + nullable=False, + ), + Column("user_party_team_id", Integer, nullable=False), + Column("episode_id", Integer, nullable=False), + Column("play_mode", Integer, nullable=False), + Column("quest_drop_boost_apply_flag", Integer, nullable=False), + Column("play_date", TIMESTAMP, nullable=False, server_default=func.now()), + UniqueConstraint("user", "user_party_team_id", "play_date", name="sao_play_sessions_uk"), + mysql_charset="utf8mb4", +) + class SaoItemData(BaseData): + def create_session(self, user_id: int, user_party_team_id: int, episode_id: int, play_mode: int, quest_drop_boost_apply_flag: int) -> Optional[int]: + sql = insert(sessions).values( + user=user_id, + user_party_team_id=user_party_team_id, + episode_id=episode_id, + play_mode=play_mode, + quest_drop_boost_apply_flag=quest_drop_boost_apply_flag + ) + + conflict = sql.on_duplicate_key_update(user=user_id) + + result = self.execute(conflict) + if result is None: + self.logger.error(f"Failed to create SAO session for user {user_id}!") + return None + return result.lastrowid + def put_hero_log(self, user_id: int, user_hero_log_id: int, log_level: int, log_exp: int, main_weapon: int, sub_equipment: int, skill_slot1_skill_id: int, skill_slot2_skill_id: int, skill_slot3_skill_id: int, skill_slot4_skill_id: int, skill_slot5_skill_id: int) -> Optional[int]: sql = insert(hero_log_data).values( user=user_id, @@ -66,15 +101,15 @@ class SaoItemData(BaseData): ) conflict = sql.on_duplicate_key_update( - log_level=hero_log_data.c.log_level, - log_exp=hero_log_data.c.log_exp, - main_weapon=hero_log_data.c.main_weapon, - sub_equipment=hero_log_data.c.sub_equipment, - skill_slot1_skill_id=hero_log_data.c.skill_slot1_skill_id, - skill_slot2_skill_id=hero_log_data.c.skill_slot2_skill_id, - skill_slot3_skill_id=hero_log_data.c.skill_slot3_skill_id, - skill_slot4_skill_id=hero_log_data.c.skill_slot4_skill_id, - skill_slot5_skill_id=hero_log_data.c.skill_slot5_skill_id, + log_level=log_level, + log_exp=log_exp, + main_weapon=main_weapon, + sub_equipment=sub_equipment, + skill_slot1_skill_id=skill_slot1_skill_id, + skill_slot2_skill_id=skill_slot2_skill_id, + skill_slot3_skill_id=skill_slot3_skill_id, + skill_slot4_skill_id=skill_slot4_skill_id, + skill_slot5_skill_id=skill_slot5_skill_id, ) result = self.execute(conflict) @@ -96,9 +131,9 @@ class SaoItemData(BaseData): ) conflict = sql.on_duplicate_key_update( - user_hero_log_id_1=hero_party.c.user_hero_log_id_1, - user_hero_log_id_2=hero_party.c.user_hero_log_id_2, - user_hero_log_id_3=hero_party.c.user_hero_log_id_3, + user_hero_log_id_1=user_hero_log_id_1, + user_hero_log_id_2=user_hero_log_id_2, + user_hero_log_id_3=user_hero_log_id_3, ) result = self.execute(conflict) @@ -155,6 +190,22 @@ class SaoItemData(BaseData): ) ) + result = self.execute(sql) + if result is None: + return None + return result.fetchone() + + def get_session( + self, user_id: int = None + ) -> Optional[List[Row]]: + sql = sessions.select( + and_( + sessions.c.user == user_id, + ) + ).order_by( + sessions.c.play_date.asc() + ) + result = self.execute(sql) if result is None: return None diff --git a/titles/sao/schema/profile.py b/titles/sao/schema/profile.py index 6ae60b1..b125717 100644 --- a/titles/sao/schema/profile.py +++ b/titles/sao/schema/profile.py @@ -40,6 +40,38 @@ class SaoProfileData(BaseData): return None return result.lastrowid + def put_profile(self, user_id: int, user_type: int, nick_name: str, rank_num: int, rank_exp: int, own_col: int, own_vp: int, own_yui_medal: int, setting_title_id: int) -> Optional[int]: + sql = insert(profile).values( + user=user_id, + user_type=user_type, + nick_name=nick_name, + rank_num=rank_num, + rank_exp=rank_exp, + own_col=own_col, + own_vp=own_vp, + own_yui_medal=own_yui_medal, + setting_title_id=setting_title_id + ) + + conflict = sql.on_duplicate_key_update( + rank_num=rank_num, + rank_exp=rank_exp, + own_col=own_col, + own_vp=own_vp, + own_yui_medal=own_yui_medal, + setting_title_id=setting_title_id + ) + + result = self.execute(conflict) + if result is None: + self.logger.error( + f"{__name__} failed to insert profile! user: {user_id}" + ) + return None + + print(result.lastrowid) + return result.lastrowid + def get_profile(self, user_id: int) -> Optional[Row]: sql = profile.select(profile.c.user == user_id) result = self.execute(sql)