From 21c9b23617836f95408807e92f8bd1aaea89debf Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Mon, 13 Mar 2023 04:04:08 -0400 Subject: [PATCH] diva: add game_init and attend handlers --- titles/diva/base.py | 31 +++++++++++------- titles/diva/handlers/base.py | 63 +++++++++++++++++++++++------------- titles/diva/index.py | 4 +-- 3 files changed, 62 insertions(+), 36 deletions(-) diff --git a/titles/diva/base.py b/titles/diva/base.py index c5cf574..02eb464 100644 --- a/titles/diva/base.py +++ b/titles/diva/base.py @@ -28,21 +28,30 @@ class DivaBase: pass def handle_game_init_request(self, data: bytes) -> str: - pass + req = GameInitRequest(data) + return None def handle_attend_request(self, data: bytes) -> str: - encoded = "&" - params = { - "atnd_prm1": "0,1,1,0,0,0,1,0,100,0,0,0,0,0,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,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,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,1,1,1,1,1,1,1,1,1,1,1", - "atnd_prm2": "30,10,100,4,1,50,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,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,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1", - "atnd_prm3": "100,0,1,1,1,1,1,1,1,1,2,3,4,1,1,1,3,4,5,1,1,1,4,5,6,1,1,1,5,6,7,4,4,4,9,10,14,5,10,10,25,20,50,30,90,5,10,10,25,20,50,30,90,5,10,10,25,20,50,30,90,5,10,10,25,20,50,30,90,5,10,10,25,20,50,30,90,10,30,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", - "atnd_lut": f"{self.time_lut}", - } + req = AttendRequest(data) + resp = AttendResponse(req.cmd, req.req_id) - encoded += parse.urlencode(params) - encoded = encoded.replace("%2C", ",") + for i in [0, 3, 4, 5, 7, 9, 10, 11, 12, 13]: + resp.atnd_prm1[i] = 0 + resp.atnd_prm1[8] = 100 - return encoded + resp.atnd_prm2[:5] = [30, 10, 100, 4, 1, 50] + + resp.atnd_prm3[0] = 100 + resp.atnd_prm3[1] = 0 + resp.atnd_prm3[10:13] = [2, 3, 4] + resp.atnd_prm3[16: 19] = [3, 4, 5] + resp.atnd_prm3[22: 25] = [4, 5, 6] + resp.atnd_prm3[80:] = [0] * 20 + resp.atnd_prm3[28:78] = [5,6,7,4,4,4,9,10,14,5,10,10,25,20,50,30,90,5, + 10,10,25,20,50,30,90,5,10,10,25,20,50,30,90,5,10,10,25,20,50,30,90, + 5,10,10,25,20,50,30,90,10,30] + + return resp.make() def handle_ping_request(self, data: bytes) -> str: encoded = "&" diff --git a/titles/diva/handlers/base.py b/titles/diva/handlers/base.py index 582cc25..0843c88 100644 --- a/titles/diva/handlers/base.py +++ b/titles/diva/handlers/base.py @@ -1,6 +1,6 @@ from urllib import parse from datetime import datetime -from typing import Union +from typing import Union, Dict class DivaRequestParseException(Exception): @@ -45,53 +45,53 @@ class BaseRequest: def __init__(self, raw: Union[str, bytes]) -> None: self.raw = raw - self.raw_dict = dict(parse.parse_qsl(raw)) + self.raw_dict: Dict[bytes, bytes] = dict(parse.parse_qsl(raw)) - if "cmd" not in self.raw_dict: + if b"cmd" not in self.raw_dict: raise DivaRequestParseException(f"cmd not in request data {self.raw_dict}") - if "req_id" not in self.raw_dict: + if b"req_id" not in self.raw_dict: raise DivaRequestParseException( f"req_id not in request data {self.raw_dict}" ) - if "place_id" not in self.raw_dict: + if b"place_id" not in self.raw_dict: raise DivaRequestParseException( f"place_id not in request data {self.raw_dict}" ) - if "start_up_mode" not in self.raw_dict: + if b"start_up_mode" not in self.raw_dict: raise DivaRequestParseException( f"start_up_mode not in request data {self.raw_dict}" ) - if "cmm_dly_mod" not in self.raw_dict: + if b"cmm_dly_mod" not in self.raw_dict: raise DivaRequestParseException( f"cmm_dly_mod not in request data {self.raw_dict}" ) - if "cmm_dly_sec" not in self.raw_dict: + if b"cmm_dly_sec" not in self.raw_dict: raise DivaRequestParseException( f"cmm_dly_sec not in request data {self.raw_dict}" ) - if "cmm_err_mod" not in self.raw_dict: + if b"cmm_err_mod" not in self.raw_dict: raise DivaRequestParseException( f"cmm_err_mod not in request data {self.raw_dict}" ) - if "region_code" not in self.raw_dict: + if b"region_code" not in self.raw_dict: raise DivaRequestParseException( f"region_code not in request data {self.raw_dict}" ) - if "time_stamp" not in self.raw_dict: + if b"time_stamp" not in self.raw_dict: raise DivaRequestParseException( f"time_stamp not in request data {self.raw_dict}" ) - for k, v in self.raw_dict: - setattr(self, k, v) + for k, v in self.raw_dict.items(): + setattr(self, k.decode(), v.decode()) self.place_id = int(self.place_id) self.start_up_mode = int(self.start_up_mode) @@ -110,17 +110,34 @@ class BaseResponse: self.stat = "ok" def make(self) -> str: - all_vars = vars(self) - all_vars.pop("cmd") - all_vars.pop("req_id") - all_vars.pop("stat") + return f"cmd={self.cmd}&req_id={self.req_id}&stat={self.stat}" - ret = f"cmd={self.cmd}&req_id={self.req_id}&stat={self.stat}" - additional_params = parse.urlencode( - all_vars, doseq=True, quote_via=parse.quote, safe="," - ) +class GameInitRequest(BaseRequest): + def __init__(self, raw: Union[str, bytes]) -> None: + super().__init__(raw) - if additional_params != "": - ret += f"&{additional_params}" +class AttendRequest(BaseRequest): + def __init__(self, raw: Union[str, bytes]) -> None: + super().__init__(raw) + self.power_on = int(self.power_on) + 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) + self.atnd_prm1 = [1] * 100 + self.atnd_prm2 = [1] * 100 + self.atnd_prm3 = [1] * 100 + self.atnd_lut = datetime.now() + + def make(self) -> str: + ret = super().make() + ret_dict = { + "atnd_prm1": ','.join([str(i) for i in self.atnd_prm1]), + "atnd_prm2": ','.join([str(i) for i in self.atnd_prm2]), + "atnd_prm3": ','.join([str(i) for i in self.atnd_prm3]), + "atnd_lut": parse.quote(self.atnd_lut.strftime('%Y-%m-%d %H:%M:%S:16.0')) + } + ret += "&" + parse.urlencode(ret_dict, safe=",") return ret + diff --git a/titles/diva/index.py b/titles/diva/index.py index 0108eb7..0f19ea3 100644 --- a/titles/diva/index.py +++ b/titles/diva/index.py @@ -103,9 +103,9 @@ class DivaServlet: self.logger.error(e) return b"stat=0" - self.logger.debug(f"Request: {req_raw}\nHeaders: {url_header}") + self.logger.debug(f"Request: {url_data}\nHeaders: {url_header}") self.logger.info( - f"{req_cls.cmd} request from {req_cls.b_serial} at {req.getClientAddress().host}" + f"{req_cls.cmd} request from {req_cls.kc_serial}/{req_cls.b_serial} at {req.getClientAddress().host}" ) handler_str = f"handle_{req_cls.cmd}_request"