From 2b02ed86842ec308d563b90a3def6b4d0019f392 Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Thu, 5 Oct 2023 23:47:50 -0400 Subject: [PATCH] diva: add stage_result, end handlers --- titles/diva/base.py | 99 ++++++++++++++----------- titles/diva/handlers/base.py | 8 +-- titles/diva/handlers/pv.py | 136 ++++++++++++++++++++++++++++++++++- titles/diva/handlers/user.py | 46 +++++++----- 4 files changed, 222 insertions(+), 67 deletions(-) diff --git a/titles/diva/base.py b/titles/diva/base.py index 97a8b87..a13f3a0 100644 --- a/titles/diva/base.py +++ b/titles/diva/base.py @@ -34,7 +34,7 @@ class DivaBase: def handle_attend_request(self, data: bytes) -> str: req = AttendRequest(data) - resp = AttendResponse(req.cmd, req.req_id) + resp = AttendResponse(req.req_id) for i in [0, 3, 4, 5, 7, 9, 10, 11, 12, 13]: resp.atnd_prm1[i] = 0 @@ -392,7 +392,7 @@ class DivaBase: def handle_pre_start_request(self, data: bytes) -> str: req = PreStartRequest(data) - resp = PreStartResponse(req.cmd, req.req_id, req.aime_id) + resp = PreStartResponse(req.req_id, req.aime_id) profile = self.data.profile.get_profile(req.aime_id, self.version) profile_shop = self.data.item.get_shop(req.aime_id, self.version) @@ -420,7 +420,7 @@ class DivaBase: ) if pd_id is None: return "&cd_adm_result=-1" - return RegisterResponse(req.cmd, req.req_id, req.aime_id).make() + return RegisterResponse(req.req_id, req.aime_id).make() def handle_start_request(self, data: bytes) -> str: req = StartRequest(data) @@ -429,7 +429,7 @@ class DivaBase: if profile is None: return - resp = StartResponse(req.cmd, req.req_id, req.pd_id, profile['player_name']) + resp = StartResponse(req.req_id, req.pd_id, profile['player_name']) profile_dict = profile._asdict() profile_dict.pop("id") @@ -532,7 +532,7 @@ class DivaBase: if profile is None: return - resp = SpendCreditResponse(req.cmd, req.req_id) + resp = SpendCreditResponse(req.req_id) resp.vcld_pts = profile['vcld_pts'] resp.lv_str = profile['lv_str'] resp.lv_efct_id = profile['lv_efct_id'] @@ -663,7 +663,7 @@ class DivaBase: for x in pd_by_pv_id: pv += x - resp = GetPvPdResponse(req.cmd, req.req_id) + resp = GetPvPdResponse(req.req_id) resp.pd_by_pv_id = pv[:-1] response = "" response += f"&pd_by_pv_id={pv[:-1]}" @@ -676,33 +676,35 @@ class DivaBase: pass def handle_stage_result_request(self, data: bytes) -> str: - profile = self.data.profile.get_profile(data["pd_id"], self.version) + req = StageResultRequest(data) + resp = StageResultResponse(req.cmd, req.req_id) + profile = self.data.profile.get_profile(req.pd_id, self.version) - pd_song_list = data["stg_ply_pv_id"].split(",") - pd_song_difficulty = data["stg_difficulty"].split(",") - pd_song_edition = data["stg_edtn"].split(",") - pd_song_max_score = data["stg_score"].split(",") - pd_song_max_atn_pnt = data["stg_atn_pnt"].split(",") - pd_song_ranking = data["stg_clr_kind"].split(",") - pd_song_sort_kind = data["sort_kind"] - pd_song_cool_cnt = data["stg_cool_cnt"].split(",") - pd_song_fine_cnt = data["stg_fine_cnt"].split(",") - pd_song_safe_cnt = data["stg_safe_cnt"].split(",") - pd_song_sad_cnt = data["stg_sad_cnt"].split(",") - pd_song_worst_cnt = data["stg_wt_wg_cnt"].split(",") - pd_song_max_combo = data["stg_max_cmb"].split(",") + pd_song_list = req.stg_ply_pv_id + pd_song_difficulty = req.stg_difficulty + pd_song_edition = req.stg_edtn + pd_song_max_score = req.stg_score + pd_song_max_atn_pnt = req.stg_atn_pnt + pd_song_ranking = req.stg_clr_kind + pd_song_sort_kind = req.sort_kind + pd_song_cool_cnt = req.stg_cool_cnt + pd_song_fine_cnt = req.stg_fine_cnt + pd_song_safe_cnt = req.stg_safe_cnt + pd_song_sad_cnt = req.stg_sad_cnt + pd_song_worst_cnt = req.stg_wt_wg_cnt + pd_song_max_combo = req.stg_max_cmb for index, value in enumerate(pd_song_list): - if "-1" not in pd_song_list[index]: + if pd_song_list[index] > 0: profile_pd_db_song = self.data.score.get_best_user_score( - data["pd_id"], + req.pd_id, pd_song_list[index], pd_song_difficulty[index], pd_song_edition[index], ) if profile_pd_db_song is None: self.data.score.put_best_score( - data["pd_id"], + req.pd_id, self.version, pd_song_list[index], pd_song_difficulty[index], @@ -719,7 +721,7 @@ class DivaBase: pd_song_max_combo[index], ) self.data.score.put_playlog( - data["pd_id"], + req.pd_id, self.version, pd_song_list[index], pd_song_difficulty[index], @@ -737,7 +739,7 @@ class DivaBase: ) elif int(pd_song_max_score[index]) >= int(profile_pd_db_song["score"]): self.data.score.put_best_score( - data["pd_id"], + req.pd_id, self.version, pd_song_list[index], pd_song_difficulty[index], @@ -754,7 +756,7 @@ class DivaBase: pd_song_max_combo[index], ) self.data.score.put_playlog( - data["pd_id"], + req.pd_id, self.version, pd_song_list[index], pd_song_difficulty[index], @@ -772,7 +774,7 @@ class DivaBase: ) elif int(pd_song_max_score[index]) != int(profile_pd_db_song["score"]): self.data.score.put_playlog( - data["pd_id"], + req.pd_id, self.version, pd_song_list[index], pd_song_difficulty[index], @@ -792,7 +794,7 @@ class DivaBase: # Profile saving based on registration list # Calculate new level - best_scores = self.data.score.get_best_scores(data["pd_id"]) + best_scores = self.data.score.get_best_scores(req.pd_id) total_atn_pnt = 0 for best_score in best_scores: @@ -801,6 +803,18 @@ class DivaBase: new_level = (total_atn_pnt // 13979) + 1 new_level_pnt = round((total_atn_pnt % 13979) / 13979 * 100) + resp.lv_num_old = int(profile['lv_num']) + resp.lv_pnt_old = int(profile['lv_pnt']) + resp.lv_num = new_level + resp.lv_str = profile['lv_str'] + resp.lv_pnt = new_level_pnt + resp.lv_efct_id = int(profile['lv_efct_id']) + resp.lv_plt_id = int(profile['lv_plt_id']) + resp.vcld_pts = int(profile['vcld_pts']) + resp.prsnt_vcld_pts = int(profile['vcld_pts']) + if "my_qst_id" not in profile: + resp.my_qst_id = profile['my_qst_id'] + response = "&chllng_kind=-1" response += f"&lv_num_old={int(profile['lv_num'])}" response += f"&lv_pnt_old={int(profile['lv_pnt'])}" @@ -810,16 +824,16 @@ class DivaBase: profile["user"], lv_num=new_level, lv_pnt=new_level_pnt, - vcld_pts=int(data["vcld_pts"]), - hp_vol=int(data["hp_vol"]), - btn_se_vol=int(data["btn_se_vol"]), - sldr_se_vol2=int(data["sldr_se_vol2"]), - sort_kind=int(data["sort_kind"]), - nxt_pv_id=int(data["ply_pv_id"]), - nxt_dffclty=int(data["nxt_dffclty"]), - nxt_edtn=int(data["nxt_edtn"]), - my_qst_id=data["my_qst_id"], - my_qst_sts=data["my_qst_sts"], + vcld_pts=req.vcld_pts, + hp_vol=req.hp_vol, + btn_se_vol=req.btn_se_vol, + sldr_se_vol2=req.sldr_se_vol2, + sort_kind=req.sort_kind, + nxt_pv_id=req.ply_pv_id, + nxt_dffclty=req.nxt_dffclty, + nxt_edtn=req.nxt_edtn, + my_qst_id=req.my_qst_id, + my_qst_sts=req.my_qst_sts, ) response += f"&lv_num={new_level}" @@ -852,15 +866,16 @@ class DivaBase: response += "&my_ccd_r_hnd=-1,-1,-1,-1,-1" response += "&my_ccd_r_vp=-1,-1,-1,-1,-1" - return response + return resp.make() def handle_end_request(self, data: bytes) -> str: - profile = self.data.profile.get_profile(data["pd_id"], self.version) + req = EndRequest(data) + profile = self.data.profile.get_profile(req.pd_id, self.version) self.data.profile.update_profile( - profile["user"], my_qst_id=data["my_qst_id"], my_qst_sts=data["my_qst_sts"] + profile["user"], my_qst_id=req.my_qst_id, my_qst_sts=req.my_qst_sts ) - return f"" + return None def handle_shop_exit_request(self, data: bytes) -> str: self.data.item.put_shop( diff --git a/titles/diva/handlers/base.py b/titles/diva/handlers/base.py index 299f8cc..d89b760 100644 --- a/titles/diva/handlers/base.py +++ b/titles/diva/handlers/base.py @@ -144,8 +144,8 @@ class AttendRequest(BaseRequest): self.is_bb = bool(int(self.power_on)) class AttendResponse(BaseResponse): - def __init__(self, cmd_id: str, req_id: int) -> None: - super().__init__(cmd_id, req_id) + def __init__(self, req_id: int) -> None: + super().__init__("attend", req_id) self.atnd_prm1 = [1] * 100 self.atnd_prm2 = [1] * 100 self.atnd_prm3 = [1] * 100 @@ -177,8 +177,8 @@ class SpendCreditRequest(BaseRequest): raise DivaRequestParseException(f"StartRequest: {e}") class SpendCreditResponse(BaseResponse): - def __init__(self, cmd_id: str, req_id: int) -> None: - super().__init__(cmd_id, req_id) + def __init__(self, req_id: int) -> None: + super().__init__("spend_credit", req_id) self.cmpgn_rslt = ",".join(["-1,-1,x,-1,-1,x,x,-1,x"] * 6) self.cmpgn_rslt_num = 0 self.vcld_pts = 0 diff --git a/titles/diva/handlers/pv.py b/titles/diva/handlers/pv.py index 50e702e..46a10a1 100644 --- a/titles/diva/handlers/pv.py +++ b/titles/diva/handlers/pv.py @@ -22,8 +22,138 @@ class GetPvPdRequest(BaseRequest): raise DivaRequestParseException(f"GetPvPdRequest: {e}") class GetPvPdResponse(BaseResponse): - def __init__(self, cmd_id: str, req_id: int) -> None: - super().__init__(cmd_id, req_id) + def __init__(self, req_id: int) -> None: + super().__init__("get_pv_pd", req_id) self.pd_by_pv_id = "" self.pdddt_flg = 0 - self.pdddt_tm = parse.quote(datetime.now().strftime(DivaConstants.LUT_TIME_FMT)) \ No newline at end of file + self.pdddt_tm = parse.quote(datetime.now().strftime(DivaConstants.LUT_TIME_FMT)) + +class StageResultRequest(BaseRequest): + def __init__(self, raw: str | bytes) -> None: + super().__init__(raw) + try: + self.pd_id = int(self.pd_id) + self.accept_idx = int(self.accept_idx) + self.start_idx = int(self.start_idx) + self.hp_vol = int(self.hp_vol) + self.btn_se_vol = int(self.btn_se_vol) + self.btn_se_vol2 = int(self.btn_se_vol2) + self.sldr_se_vol2 = int(self.sldr_se_vol2) + self.use_pv_mdl_eqp = int(self.use_pv_mdl_eqp) + self.vcld_pts = int(self.vcld_pts) + self.nxt_pv_id = int(self.nxt_pv_id) + self.nxt_dffclty = int(self.nxt_dffclty) + self.nxt_edtn = int(self.nxt_edtn) + self.sort_kind = int(self.sort_kind) + self.nblss_ltt_stts = int(self.nblss_ltt_stts) + self.nblss_ltt_tckt = int(self.nblss_ltt_tckt) + self.free_play = int(self.free_play) + self.game_type = int(self.game_type) + self.ply_pv_id = int(self.ply_pv_id) + self.ttl_vp_add = int(self.ttl_vp_add) + self.ttl_vp_sub = int(self.ttl_vp_sub) + self.continue_cnt = int(self.continue_cnt) + self.cr_cid = int(self.cr_cid) + self.cr_sc = int(self.cr_sc) + self.cr_tv = int(self.cr_tv) + self.cr_if = int(self.cr_if) + + self.my_qst_id: List[int] = [int(x) for x in self.my_qst_id.split(",")] + self.my_qst_sts: List[int] = [int(x) for x in self.my_qst_sts.split(",")] + self.stg_difficulty: List[int] = [int(x) for x in self.stg_difficulty.split(",")] + self.stg_edtn: List[int] = [int(x) for x in self.stg_edtn.split(",")] + self.stg_ply_pv_id: List[int] = [int(x) for x in self.stg_ply_pv_id.split(",")] + self.stg_sel_pv_id: List[int] = [int(x) for x in self.stg_sel_pv_id.split(",")] + self.stg_scrpt_ver: List[int] = [int(x) for x in self.stg_scrpt_ver.split(",")] + self.stg_score: List[int] = [int(x) for x in self.stg_score.split(",")] + self.stg_chllng_kind: List[int] = [int(x) for x in self.stg_chllng_kind.split(",")] + self.stg_chllng_result: List[int] = [int(x) for x in self.stg_chllng_result.split(",")] + self.stg_clr_kind: List[int] = [int(x) for x in self.stg_clr_kind.split(",")] + self.stg_vcld_pts: List[int] = [int(x) for x in self.stg_vcld_pts.split(",")] + self.stg_cool_cnt: List[int] = [int(x) for x in self.stg_cool_cnt.split(",")] + self.stg_cool_pct: List[int] = [int(x) for x in self.stg_cool_pct.split(",")] + self.stg_fine_cnt: List[int] = [int(x) for x in self.stg_fine_cnt.split(",")] + self.stg_fine_pct: List[int] = [int(x) for x in self.stg_fine_pct.split(",")] + self.stg_safe_cnt: List[int] = [int(x) for x in self.stg_safe_cnt.split(",")] + self.stg_safe_pct: List[int] = [int(x) for x in self.stg_safe_pct.split(",")] + self.stg_sad_cnt: List[int] = [int(x) for x in self.stg_sad_cnt.split(",")] + self.stg_sad_pct: List[int] = [int(x) for x in self.stg_sad_pct.split(",")] + self.stg_wt_wg_cnt: List[int] = [int(x) for x in self.stg_wt_wg_cnt.split(",")] + self.stg_wt_wg_pct: List[int] = [int(x) for x in self.stg_wt_wg_pct.split(",")] + self.stg_max_cmb: List[int] = [int(x) for x in self.stg_max_cmb.split(",")] + self.stg_chance_tm: List[int] = [int(x) for x in self.stg_chance_tm.split(",")] + self.stg_sm_hl: List[int] = [int(x) for x in self.stg_sm_hl.split(",")] + self.stg_atn_pnt: List[int] = [int(x) for x in self.stg_atn_pnt.split(",")] + self.stg_skin_id: List[int] = [int(x) for x in self.stg_skin_id.split(",")] + self.stg_btn_se: List[int] = [int(x) for x in self.stg_btn_se.split(",")] + self.stg_btn_se_vol: List[int] = [int(x) for x in self.stg_btn_se_vol.split(",")] + self.stg_sld_se: List[int] = [int(x) for x in self.stg_sld_se.split(",")] + self.stg_chn_sld_se: List[int] = [int(x) for x in self.stg_chn_sld_se.split(",")] + self.stg_sldr_tch_se: List[int] = [int(x) for x in self.stg_sldr_tch_se.split(",")] + self.stg_mdl_id: List[int] = [int(x) for x in self.stg_mdl_id.split(",")] + self.stg_sel_mdl_id: List[int] = [int(x) for x in self.stg_sel_mdl_id.split(",")] + self.stg_rvl_pd_id: List[int] = [int(x) for x in self.stg_rvl_pd_id.split(",")] + self.stg_rvl_wl: List[int] = [int(x) for x in self.stg_rvl_wl.split(",")] + self.stg_cpt_rslt: List[int] = [int(x) for x in self.stg_cpt_rslt.split(",")] + self.stg_sld_scr: List[int] = [int(x) for x in self.stg_sld_scr.split(",")] + self.stg_is_sr_gm: List[int] = [int(x) for x in self.stg_is_sr_gm.split(",")] + self.stg_pv_brnch_rslt: List[int] = [int(x) for x in self.stg_pv_brnch_rslt.split(",")] + self.stg_vcl_chg: List[int] = [int(x) for x in self.stg_vcl_chg.split(",")] + self.stg_c_itm_id: List[int] = [int(x) for x in self.stg_c_itm_id.split(",")] + self.stg_ms_itm_flg: List[int] = [int(x) for x in self.stg_ms_itm_flg.split(",")] + self.stg_rgo: List[int] = [int(x) for x in self.stg_rgo.split(",")] + self.stg_ss_num: List[int] = [int(x) for x in self.stg_ss_num.split(",")] + self.stg_is_cs_scs: List[int] = [int(x) for x in self.stg_is_cs_scs.split(",")] + self.stg_is_nppg_use: List[int] = [int(x) for x in self.stg_is_nppg_use.split(",")] + self.stg_p_std_lo_id: List[int] = [int(x) for x in self.stg_p_std_lo_id.split(",")] + self.stg_p_std_is_to: List[int] = [int(x) for x in self.stg_p_std_is_to.split(",")] + self.stg_p_std_is_ccu: List[int] = [int(x) for x in self.stg_p_std_is_ccu.split(",")] + self.stg_p_std_is_tiu: List[int] = [int(x) for x in self.stg_p_std_is_tiu.split(",")] + self.stg_p_std_is_iu: List[int] = [int(x) for x in self.stg_p_std_is_iu.split(",")] + self.stg_p_std_is_npu: List[int] = [int(x) for x in self.stg_p_std_is_npu.split(",")] + self.stg_p_std_is_du: List[int] = [int(x) for x in self.stg_p_std_is_du.split(",")] + self.gu_cmd: List[int] = [int(x) for x in self.gu_cmd.split(",")] + self.mdl_eqp_cmn_ary: List[int] = [int(x) for x in self.mdl_eqp_cmn_ary.split(",")] + self.c_itm_eqp_cmn_ary: List[int] = [int(x) for x in self.c_itm_eqp_cmn_ary.split(",")] + self.ms_itm_flg_cmn_ary: List[int] = [int(x) for x in self.ms_itm_flg_cmn_ary.split(",")] + self.mdl_eqp_pv_ary: List[int] = [int(x) for x in self.mdl_eqp_pv_ary.split(",")] + self.c_itm_eqp_pv_ary: List[int] = [int(x) for x in self.c_itm_eqp_pv_ary.split(",")] + self.ms_itm_flg_pv_ary: List[int] = [int(x) for x in self.ms_itm_flg_pv_ary.split(",")] + self.stg_mdl_s_sts: List[int] = [int(x) for x in self.stg_mdl_s_sts.split(",")] + self.cr_sp: List[int] = [int(x) for x in parse.unquote(self.cr_sp).split(",")] + + except AttributeError as e: + raise DivaRequestParseException(f"StageResultRequest: {e}") + +class StageResultResponse(BaseResponse): + def __init__(self, req_id: int) -> None: + super().__init__("stage_result", req_id) + self.chllng_kind = -1 + self.lv_num_old = 0 + self.lv_pnt_old = 0 + self.lv_num = 0 + self.lv_str = 0 + self.lv_pnt = 0 + self.lv_efct_id = 0 + self.lv_plt_id = 0 + self.vcld_pts = 0 + self.prsnt_vcld_pts = 0 + self.cerwd_kind = -1 + self.cerwd_value = -1 + self.cerwd_str_0 = "***" + self.cerwd_str_1 = "***" + self.ttl_str_ary = "xxx,xxx,xxx,xxx,xxx" + self.ttl_plt_id_ary = "xxx,xxx,xxx,xxx,xxx" + self.ttl_desc_ary = "xxx,xxx,xxx,xxx,xxx" + self.skin_id_ary = "xxx,xxx,xxx,xxx,xxx" + self.skin_name_ary = "xxx,xxx,xxx,xxx,xxx" + self.skin_illust_ary = "xxx,xxx,xxx,xxx,xxx" + self.skin_desc_ary = "xxx,xxx,xxx,xxx,xxx" + self.my_qst_id = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + self.my_qst_r_qid = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + self.my_qst_r_knd = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + self.my_qst_r_vl = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + self.my_qst_r_nflg = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + self.my_ccd_r_qid = "-1,-1,-1,-1,-1" + self.my_ccd_r_hnd = "-1,-1,-1,-1,-1" + self.my_ccd_r_vp = "-1,-1,-1,-1,-1" diff --git a/titles/diva/handlers/user.py b/titles/diva/handlers/user.py index c979af1..2f1e5d6 100644 --- a/titles/diva/handlers/user.py +++ b/titles/diva/handlers/user.py @@ -1,3 +1,4 @@ +from typing import Union from titles.diva.handlers.base import ( BaseRequest, BaseResponse, @@ -25,10 +26,9 @@ class PreStartRequest(BaseRequest): except AttributeError as e: raise DivaRequestParseException(f"PreStartRequest: {e}") - class PreStartResponse(BaseResponse): - def __init__(self, cmd_id: str, req_id: int, pd_id: int) -> None: - super().__init__(cmd_id, req_id) + def __init__(self, req_id: int, pd_id: int) -> None: + super().__init__("pre_start", req_id) self.ps_result = 1 self.pd_id = pd_id self.accept_idx = 100 @@ -54,7 +54,6 @@ class PreStartResponse(BaseResponse): # But this is how it's stored in the db, so w/e for now self.mdl_eqp_ary = "-999,-999,-999" - class StartRequest(BaseRequest): def __init__(self, raw: str) -> None: super().__init__(raw) @@ -65,10 +64,9 @@ class StartRequest(BaseRequest): except AttributeError as e: raise DivaRequestParseException(f"StartRequest: {e}") - class StartResponse(BaseResponse): - def __init__(self, cmd_id: str, req_id: int, pv_id: int, pv_name: str) -> None: - super().__init__(cmd_id, req_id) + def __init__(self, req_id: int, pv_id: int, pv_name: str) -> None: + super().__init__("start", req_id) self.pd_id: int = pv_id self.start_result: int = 1 self.accept_idx: int = 100 @@ -118,16 +116,15 @@ class StartResponse(BaseResponse): self.ms_itm_flg_ary = ",".join(["1"] * 12) class RegisterRequest(BaseRequest): - pmm: str - idm: str - mmgameid: str - mmuid: str - a_code: str - aime_a_code: str - player_name: str - passwd: str - def __init__(self, raw: str) -> None: + self.pmm: str + self.idm: str + self.mmgameid: str + self.mmuid: str + self.a_code: str + self.aime_a_code: str + self.player_name: str + self.passwd: str super().__init__(raw) try: self.aime_id = int(self.aime_id) @@ -137,7 +134,20 @@ class RegisterRequest(BaseRequest): raise DivaRequestParseException(f"RegisterRequest: {e}") class RegisterResponse(BaseResponse): - def __init__(self, cmd_id: str, req_id: int, pv_id: int) -> None: - super().__init__(cmd_id, req_id) + def __init__(self, req_id: int, pv_id: int) -> None: + super().__init__("register", req_id) self.cd_adm_result: int = 1 self.pd_id: int = pv_id + +class EndRequest(BaseRequest): + def __init__(self, raw: str | bytes) -> None: + self.my_qst_id: str + self.my_qst_sts: str + + super().__init__(raw) + try: + self.pd_id = int(self.pd_id) + + except AttributeError as e: + raise DivaRequestParseException(f"EndRequest: {e}") + \ No newline at end of file