Compare commits
30 Commits
develop
...
diva_handl
Author | SHA1 | Date | |
---|---|---|---|
1a616cba41 | |||
d2d02f9483 | |||
024bc352d7 | |||
4831aa5628 | |||
dd1c7667e0 | |||
2ec1dcadef | |||
81c13f5008 | |||
572b8ddbe5 | |||
2b02ed8684 | |||
b2a01d20d5 | |||
5e03193819 | |||
f836b5dd21 | |||
53c74c6511 | |||
7322bc60dc | |||
c2ee09bce0 | |||
dfea392b03 | |||
998aa70929 | |||
8df1325613 | |||
6ff7827918 | |||
a36170f2c3 | |||
48144b53f0 | |||
3b852ea739 | |||
21c9b23617 | |||
3076bdf575 | |||
5be25f89ff | |||
5443d24352 | |||
56927c049f | |||
2b81ba206c | |||
9718e822f3 | |||
b07e3d6a94 |
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -1,3 +0,0 @@
|
||||
*.csv binary
|
||||
*.txt binary
|
||||
*.json binary
|
@ -1,12 +1,9 @@
|
||||
from typing import Dict, Any, Optional
|
||||
from typing import Dict, Any
|
||||
from types import ModuleType
|
||||
from twisted.web.http import Request
|
||||
import logging
|
||||
import importlib
|
||||
from os import walk
|
||||
import jwt
|
||||
from base64 import b64decode
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from .config import CoreConfig
|
||||
|
||||
@ -63,35 +60,3 @@ class Utils:
|
||||
cls.real_title_port_ssl = cfg.title.port_ssl
|
||||
|
||||
return cls.real_title_port_ssl
|
||||
|
||||
def create_sega_auth_key(aime_id: int, game: str, ver: float, place_id: str, b64_secret: str, err_logger: str = 'aimedb') -> Optional[str]:
|
||||
logger = logging.getLogger(err_logger)
|
||||
try:
|
||||
return jwt.encode({ "aime_id": aime_id, "game": game, "ver": ver, "place_id": place_id, "exp": int(datetime.now(tz=timezone.utc).timestamp()) + 86400 }, b64decode(b64_secret), algorithm="HS256")
|
||||
except jwt.InvalidKeyError:
|
||||
logger.error("Failed to encode Sega Auth Key because the secret is invalid!")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Unknown exception occoured when encoding Sega Auth Key! {e}")
|
||||
return None
|
||||
|
||||
def decode_sega_auth_key(token: str, b64_secret: str, err_logger: str = 'aimedb') -> Optional[Dict]:
|
||||
logger = logging.getLogger(err_logger)
|
||||
try:
|
||||
return jwt.decode(token, "secret", b64decode(b64_secret), algorithms=["HS256"], options={"verify_signature": True})
|
||||
except jwt.ExpiredSignatureError:
|
||||
logger.error("Sega Auth Key failed to validate due to an expired signature!")
|
||||
return None
|
||||
except jwt.InvalidSignatureError:
|
||||
logger.error("Sega Auth Key failed to validate due to an invalid signature!")
|
||||
return None
|
||||
except jwt.DecodeError as e:
|
||||
logger.error(f"Sega Auth Key failed to decode! {e}")
|
||||
return None
|
||||
except jwt.InvalidTokenError as e:
|
||||
logger.error(f"Sega Auth Key is invalid! {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Unknown exception occoured when decoding Sega Auth Key! {e}")
|
||||
return None
|
||||
|
@ -1,6 +1,7 @@
|
||||
server:
|
||||
enable: True
|
||||
loglevel: "info"
|
||||
banner_msg: ""
|
||||
|
||||
mods:
|
||||
unlock_all_modules: True
|
||||
|
@ -1,21 +1,20 @@
|
||||
mypy
|
||||
wheel
|
||||
twisted
|
||||
pytz
|
||||
pyyaml
|
||||
sqlalchemy==1.4.46
|
||||
mysqlclient
|
||||
pyopenssl
|
||||
service_identity
|
||||
PyCryptodome
|
||||
inflection
|
||||
coloredlogs
|
||||
pylibmc; platform_system != "Windows"
|
||||
wacky
|
||||
Routes
|
||||
bcrypt
|
||||
jinja2
|
||||
protobuf
|
||||
autobahn
|
||||
pillow
|
||||
pyjwt
|
||||
mypy
|
||||
wheel
|
||||
twisted
|
||||
pytz
|
||||
pyyaml
|
||||
sqlalchemy==1.4.46
|
||||
mysqlclient
|
||||
pyopenssl
|
||||
service_identity
|
||||
PyCryptodome
|
||||
inflection
|
||||
coloredlogs
|
||||
pylibmc; platform_system != "Windows"
|
||||
wacky
|
||||
Routes
|
||||
bcrypt
|
||||
jinja2
|
||||
protobuf
|
||||
autobahn
|
||||
pillow
|
||||
|
@ -313,13 +313,6 @@ class ChuniBase:
|
||||
"userChargeList": charge_list,
|
||||
}
|
||||
|
||||
def handle_get_user_recent_player_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 0,
|
||||
"userRecentPlayerList": [], # playUserId, playUserName, playDate, friendPoint
|
||||
}
|
||||
|
||||
def handle_get_user_course_api_request(self, data: Dict) -> Dict:
|
||||
user_course_list = self.data.score.get_courses(data["userId"])
|
||||
if user_course_list is None:
|
||||
@ -331,8 +324,8 @@ class ChuniBase:
|
||||
}
|
||||
|
||||
course_list = []
|
||||
next_idx = int(data.get("nextIndex", 0))
|
||||
max_ct = int(data.get("maxCount", 300))
|
||||
next_idx = int(data["nextIndex"])
|
||||
max_ct = int(data["maxCount"])
|
||||
|
||||
for x in range(next_idx, len(user_course_list)):
|
||||
tmp = user_course_list[x]._asdict()
|
||||
@ -409,7 +402,6 @@ class ChuniBase:
|
||||
"userId": data["userId"],
|
||||
"userRivalData": userRivalData
|
||||
}
|
||||
|
||||
def handle_get_user_rival_music_api_request(self, data: Dict) -> Dict:
|
||||
rival_id = data["rivalId"]
|
||||
next_index = int(data["nextIndex"])
|
||||
@ -457,7 +449,6 @@ class ChuniBase:
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
def handle_get_user_favorite_item_api_request(self, data: Dict) -> Dict:
|
||||
user_fav_item_list = []
|
||||
|
||||
@ -747,7 +738,6 @@ class ChuniBase:
|
||||
"aggrDate": data["playDate"],
|
||||
},
|
||||
}
|
||||
|
||||
def handle_get_team_course_setting_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
@ -915,10 +905,6 @@ class ChuniBase:
|
||||
self.data.item.put_login_bonus(
|
||||
user_id, self.version, login["presetId"], isWatched=True
|
||||
)
|
||||
|
||||
if "userRecentPlayerList" in upsert: # TODO: Seen in Air, maybe implement sometime
|
||||
for rp in upsert["userRecentPlayerList"]:
|
||||
pass
|
||||
|
||||
return {"returnCode": "1"}
|
||||
|
||||
|
@ -142,9 +142,9 @@ class ChuniServlet(BaseServlet):
|
||||
|
||||
def get_allnet_info(self, game_code: str, game_ver: int, keychip: str) -> Tuple[str, str]:
|
||||
if not self.core_cfg.server.is_using_proxy and Utils.get_title_port(self.core_cfg) != 80:
|
||||
return (f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_ver}/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_ver}/", "")
|
||||
|
||||
return (f"http://{self.core_cfg.title.hostname}/{game_ver}/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.title.hostname}/{game_ver}/", "")
|
||||
|
||||
def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
endpoint = matchers['endpoint']
|
||||
|
@ -1,9 +0,0 @@
|
||||
1,1412103600,4070908801,1,
|
||||
2,1412103600,4070908801,1,
|
||||
3,1412103600,4070908801,1,
|
||||
4,1412103600,4070908801,1,
|
||||
5,1412103600,4070908801,1,
|
||||
6,1412103600,4070908801,1,
|
||||
7,1412103600,4070908801,1,
|
||||
8,1412103600,4070908801,1,
|
||||
9,1412103600,4070908801,1,
|
|
@ -1,272 +0,0 @@
|
||||
tutori2,10000,100000,10,10,10,10,10,0,0,0,0,0,0,100000,
|
||||
tutori3,10000,100000,10,10,10,10,10,0,0,0,0,0,0,100000,
|
||||
tutori4,10000,10100000,10,10,10,10,10,0,0,0,0,0,0,100000,
|
||||
tutori5,10000,100000,10,10,10,10,10,0,0,0,0,0,0,100000,
|
||||
tutori6,10050,10100000,10,10,10,10,10,0,0,0,0,0,0,100000,
|
||||
wannab,10073,800000,90,230,400,650,50,1,1,1,1,1,3,100001,
|
||||
toucho,10000,802000,90,280,440,650,50,1,1,1,1,1,1,100002,
|
||||
ameoto,10000,802000,120,260,470,630,60,1,1,1,1,1,1,100003,
|
||||
kimito,10000,800000,100,260,490,660,70,1,1,1,1,1,1,100004,
|
||||
landin,10000,802000,260,330,490,670,130,1,1,1,1,1,1,100005,
|
||||
aquali,10104,800000,160,340,580,0,110,1,1,1,0,1,4,100006,
|
||||
yiyoyi,10080,800000,140,330,560,700,70,1,1,1,1,1,3,100007,
|
||||
hontno,10022,801000,120,260,530,660,90,1,1,1,1,1,1,100010,
|
||||
binary,10080,800000,170,350,640,890,140,1,1,1,1,1,1,100014,
|
||||
breakd,10000,803000,230,340,570,740,110,1,1,1,1,1,2,100015,
|
||||
higame,10076,800000,200,300,580,710,130,1,1,1,1,1,3,100016,
|
||||
freakw,10104,800000,220,420,650,660,130,1,1,1,1,1,0,100018,
|
||||
giantk,10000,808000,250,530,710,780,110,1,1,1,1,1,3,100021,
|
||||
theepi,10076,800000,190,400,610,750,140,1,1,1,1,1,3,100022,
|
||||
anomie,10076,800000,220,380,610,770,150,1,1,1,1,1,0,100023,
|
||||
azitat,10022,800000,240,550,700,830,140,1,1,1,1,1,0,100024,
|
||||
dazzlj,10000,802000,350,600,800,900,160,1,1,1,1,1,1,100028,
|
||||
aerial,10100,800000,110,280,560,710,50,1,1,1,1,1,1,100039,
|
||||
gingat,10005,800000,130,290,460,610,50,1,1,1,1,1,0,100041,
|
||||
sundro,10000,807000,240,470,750,830,140,1,1,1,1,1,3,100042,
|
||||
childr,10069,800000,240,390,560,620,140,1,1,1,1,1,0,100043,
|
||||
tsukai,10069,802000,190,440,720,760,130,1,1,1,1,1,1,100044,
|
||||
dennou,10000,801000,290,600,760,870,150,1,1,1,1,1,1,100045,
|
||||
romanc,10104,800000,280,550,780,0,100,1,1,1,0,1,0,100047,
|
||||
makaim,10078,2400000,300,500,770,0,230,1,1,1,0,1,3,100054,
|
||||
gyakut,10078,2400000,150,210,460,640,60,1,1,1,1,1,1,100055,
|
||||
basara,10078,2400000,190,370,640,730,140,1,1,1,1,1,0,100056,
|
||||
howtru,10074,800000,120,250,530,740,80,1,1,1,1,1,0,100057,
|
||||
auflcb,10000,800000,130,430,810,0,80,1,1,1,0,1,0,100063,
|
||||
daisak,10005,800000,280,360,600,750,120,1,1,1,1,1,0,100066,
|
||||
rideon,10069,802000,290,410,600,800,160,1,1,1,1,1,1,100067,
|
||||
hokoro,10000,801000,290,570,710,810,140,1,1,1,1,1,1,100068,
|
||||
ididid,10000,802000,290,460,720,810,160,1,1,1,1,1,1,100093,
|
||||
yukiya,10103,800000,190,400,610,0,110,1,1,1,0,1,3,100096,
|
||||
samalv,10102,800000,190,390,580,770,130,1,1,1,1,1,6,100098,
|
||||
crissc,10076,800000,370,630,860,910,170,1,1,1,1,1,4,100100,
|
||||
drivin,10100,800000,230,400,660,760,80,1,1,1,1,1,7,100111,
|
||||
genzit,10100,800000,180,460,730,820,120,1,1,1,1,1,0,100118,
|
||||
overlp,10103,800000,170,300,510,0,90,1,1,1,0,1,7,100119,
|
||||
zankyo,10103,800000,180,380,570,740,100,1,1,1,1,1,5,100124,
|
||||
megaro,10000,800000,550,800,930,980,0,1,1,1,1,1,0,100129,
|
||||
sateli,10000,800000,280,490,770,820,170,1,1,1,1,1,0,100300,
|
||||
nature,10000,40802000,140,240,530,750,50,1,1,1,1,1,3,100301,
|
||||
reseed3,10000,800000,200,550,760,800,100,1,1,1,1,1,0,100306,
|
||||
purple,10000,800000,220,540,640,730,140,1,1,1,1,1,0,100307,
|
||||
hearts,10000,800000,180,380,680,770,80,1,1,1,1,1,0,100308,
|
||||
syoujo,10003,802000,190,350,530,780,80,1,1,1,1,1,1,100309,
|
||||
phasea,10000,800000,160,380,650,750,90,1,1,1,1,1,0,100310,
|
||||
planet,10000,802000,170,360,490,710,100,1,1,1,1,1,1,100311,
|
||||
touchn,10050,804000,270,460,680,860,150,1,1,1,1,1,8,100312,
|
||||
upside,10050,802000,180,270,480,670,80,1,1,1,1,1,1,100313,
|
||||
firefo,10000,800000,130,360,570,830,70,1,1,1,1,1,0,100314,
|
||||
kounen,10000,808000,210,400,660,780,100,1,1,1,1,1,3,100315,
|
||||
essenc,10000,800000,250,500,700,760,110,1,1,1,1,1,0,100316,
|
||||
summer,10000,800000,230,570,790,890,130,1,1,1,1,1,0,100317,
|
||||
tanosi,10000,802000,250,450,700,800,160,1,1,1,1,1,7,100319,
|
||||
picora,10000,802000,150,380,660,750,80,1,1,1,1,1,1,100320,
|
||||
istanb,10050,806000,410,490,900,980,230,1,1,1,1,1,3,100322,
|
||||
devils,10000,800000,270,400,800,0,150,1,1,1,0,1,0,100323,
|
||||
speedy,10076,800000,220,550,770,0,110,1,1,1,0,1,8,100324,
|
||||
irohaa,10008,800000,190,410,550,760,120,1,1,1,1,1,0,100325,
|
||||
ibelie,10008,800000,270,470,780,820,140,1,1,1,1,1,0,100326,
|
||||
letmeg,10021,802000,180,320,500,720,120,1,1,1,1,1,1,100327,
|
||||
techno,10000,802000,160,380,510,740,90,1,1,1,1,1,1,100328,
|
||||
angeli,10000,800000,330,560,820,900,220,1,1,1,1,1,0,100330,
|
||||
glowww,10000,40802000,170,280,420,600,80,1,1,1,1,1,7,100335,
|
||||
powerr,10000,800000,190,380,690,790,120,1,1,1,1,1,0,100336,
|
||||
laught,10022,801000,200,350,510,710,70,1,1,1,1,1,1,100337,
|
||||
chaset,10019,803000,150,310,580,760,80,1,1,1,1,1,9999,100338,
|
||||
amater,10000,800000,210,480,650,790,130,1,1,1,1,1,0,100340,
|
||||
moonli,10000,803000,140,430,610,730,80,1,1,1,1,1,9999,100342,
|
||||
sayona,10050,803000,200,340,530,710,100,1,1,1,1,1,9999,100343,
|
||||
hosita,10000,802000,160,360,480,650,100,1,1,1,1,1,9999,100344,
|
||||
ascand,10069,800000,320,540,800,900,180,1,1,1,1,1,0,100347,
|
||||
pinkym,10000,800000,240,440,740,810,160,1,1,1,1,1,0,100348,
|
||||
advers,10000,802000,150,480,710,830,90,1,1,1,1,1,1,100349,
|
||||
straye,10050,800000,250,360,610,730,140,1,1,1,1,1,4,100350,
|
||||
destru,10003,800000,190,410,620,720,100,1,1,1,1,1,0,100352,
|
||||
venera,10000,800000,150,430,680,750,80,1,1,1,1,1,0,100353,
|
||||
dazaii,10000,803000,210,430,730,770,120,1,1,1,1,1,3,100357,
|
||||
rearhy,10050,802000,170,320,520,690,70,1,1,1,1,1,9999,100358,
|
||||
onlyll,10050,802000,210,320,560,690,130,1,1,1,1,1,9999,100359,
|
||||
hellom,10022,801000,180,370,580,720,70,1,1,1,1,1,1,100360,
|
||||
megaro2,10100,800000,0,0,990,1000,0,0,0,1,1,0,4,100361,
|
||||
tomorr,10003,803000,150,240,440,620,80,1,1,1,1,1,7,100362,
|
||||
daybyd,10003,803000,130,260,380,590,60,1,1,1,1,1,7,100363,
|
||||
thesig,10000,802000,210,380,560,730,100,1,1,1,1,1,3,100365,
|
||||
zonzon,10066,800000,160,330,630,670,50,1,1,1,1,1,1,100367,
|
||||
yumemi,10000,802000,120,350,590,690,60,1,1,1,1,1,9999,100369,
|
||||
dynami2,10000,804000,180,510,780,800,80,1,1,1,1,1,0,100370,
|
||||
memori,10050,803000,260,380,650,840,130,1,1,1,1,1,9999,100371,
|
||||
bluede,10000,802000,220,410,580,700,120,1,1,1,1,1,5,100372,
|
||||
emerao,10000,802000,300,530,850,0,190,1,1,1,0,1,1,100373,
|
||||
auflcb3,10007,802000,160,360,660,860,60,1,1,1,1,1,9999,100374,
|
||||
paradi,10005,801000,160,280,530,640,100,1,1,1,1,1,3,100376,
|
||||
pigooo,10005,800000,190,340,590,840,130,1,1,1,1,1,6,100377,
|
||||
flameu,10050,801000,180,360,570,650,100,1,1,1,1,1,1,100380,
|
||||
season,10006,1607000,150,280,440,650,80,1,1,1,1,1,1,100386,
|
||||
canonn,10006,1607000,170,280,500,830,70,1,1,1,1,1,1,100387,
|
||||
rhapso,10006,1607000,180,340,620,740,60,1,1,1,1,1,1,100388,
|
||||
turkis,10006,1607000,190,390,640,840,110,1,1,1,1,1,1,100389,
|
||||
biohaz,10006,1609000,150,300,510,640,60,1,1,1,1,1,9999,100390,
|
||||
monhan,10006,1609000,100,260,360,540,50,1,1,1,1,1,9999,100391,
|
||||
gyakut2,10006,1609000,130,350,430,560,50,1,1,1,1,1,9999,100392,
|
||||
street,10006,1609000,130,340,470,660,70,1,1,1,1,1,9999,100393,
|
||||
rockma2,10006,1609000,210,340,490,760,140,1,1,1,1,1,9999,100394,
|
||||
monhan2,10014,1609000,120,240,430,680,60,1,1,1,1,1,9999,100409,
|
||||
monhan3,10014,1609000,180,280,450,730,80,1,1,1,1,1,9999,100410,
|
||||
orbita,10050,803000,200,380,620,740,120,1,1,1,1,1,5,100411,
|
||||
metall,10021,803000,160,280,570,770,80,1,1,1,1,1,1,100412,
|
||||
xmasss,10017,1607000,180,380,560,770,80,1,1,1,1,1,101,100417,
|
||||
yejiii,10019,800000,220,360,630,790,100,1,1,1,1,1,0,100418,
|
||||
histor,10019,800000,200,360,560,820,110,1,1,1,1,1,0,100419,
|
||||
silbur,10026,801000,200,350,540,750,90,1,1,1,1,1,1,100421,
|
||||
spicaa,10026,801000,230,360,560,780,100,1,1,1,1,1,1,100422,
|
||||
street2,10025,1609000,210,370,550,730,140,1,1,1,1,1,9999,100423,
|
||||
street3,10025,1609000,240,380,570,740,130,1,1,1,1,1,9999,100424,
|
||||
street4,10025,1609000,170,320,510,780,110,1,1,1,1,1,9999,100425,
|
||||
bluede2,10024,801000,160,360,560,810,90,1,1,1,1,1,1,100426,
|
||||
pyroma,10050,800000,220,420,700,840,80,1,1,1,1,1,4,100427,
|
||||
avemar,10050,1607000,160,310,530,750,80,1,1,1,1,1,5,100428,
|
||||
mateki,10050,1607000,180,350,540,790,100,1,1,1,1,1,5,100429,
|
||||
densho,10050,800000,280,420,740,900,170,1,1,1,1,1,5,100430,
|
||||
sunglo,10050,801000,180,390,590,720,100,1,1,1,1,1,7,100431,
|
||||
hereco,10050,801000,160,340,510,680,110,1,1,1,1,1,4,100432,
|
||||
dddddd,10050,800000,130,330,530,690,90,1,1,1,1,1,5,100433,
|
||||
raidon,10050,801000,300,380,580,870,130,1,1,1,1,1,1,100434,
|
||||
thisis,10050,800000,230,370,600,740,120,1,1,1,1,1,4,100435,
|
||||
rising,10050,800000,230,380,660,850,140,1,1,1,1,1,4,100436,
|
||||
riseup,10050,800000,180,410,670,770,70,1,1,1,1,1,4,100437,
|
||||
tricko,10050,800000,230,340,560,750,110,1,1,1,1,1,0,100438,
|
||||
kinbos,10050,800000,220,380,640,770,120,1,1,1,1,1,3,100439,
|
||||
thesun,10050,800000,250,400,720,870,130,1,1,1,1,1,4,100441,
|
||||
lovech,10050,801000,160,300,460,680,80,1,1,1,1,1,7,100445,
|
||||
machup,10061,801000,170,320,410,710,90,1,1,1,1,1,6,100447,
|
||||
cyberg,10104,801000,230,350,600,0,120,1,1,1,0,1,0,100448,
|
||||
harmon,10050,801000,200,360,490,650,120,1,1,1,1,1,7,100449,
|
||||
kansho,10056,801000,130,270,550,740,70,1,1,1,1,1,9999,100450,
|
||||
cantst,10103,800000,230,420,650,0,110,1,1,1,0,1,0,100455,
|
||||
takeit,10050,800000,200,380,650,830,120,1,1,1,1,1,4,100457,
|
||||
lespri,10063,800000,250,570,800,0,130,1,1,1,0,1,5,100465,
|
||||
notoss,10061,800000,120,420,650,910,80,1,1,1,1,1,4,100466,
|
||||
codena,10055,801000,180,350,480,680,90,1,1,1,1,1,1,100468,
|
||||
aiohoo,10050,101000,180,290,420,660,100,1,1,1,1,1,1,100471,
|
||||
entert,10050,1607000,150,330,540,870,90,1,1,1,1,1,6,100472,
|
||||
akaihe,10051,101000,210,320,500,690,80,1,1,1,1,1,1,100473,
|
||||
juicys,10051,101000,180,260,450,830,100,1,1,1,1,1,7,100474,
|
||||
groove,10055,1601000,220,400,520,730,100,1,1,1,1,1,103,100475,
|
||||
groove2,10058,1601000,150,400,580,850,90,1,1,1,1,1,9999,100480,
|
||||
everyt,10063,801000,220,300,740,0,130,1,1,1,0,1,5,100482,
|
||||
taikoo,10058,1609000,130,390,500,750,60,1,1,1,1,1,104,100483,
|
||||
overcl2,10057,809000,230,420,580,740,120,1,1,1,1,1,3,100486,
|
||||
overcl,10059,809000,120,350,570,860,80,1,1,1,1,1,4,100487,
|
||||
groove3,10062,2009000,180,340,640,850,100,1,1,1,1,1,105,100488,
|
||||
groove4,10062,2009000,220,350,500,750,120,1,1,1,1,1,106,100489,
|
||||
honeyo,10064,802000,320,630,880,930,240,1,1,1,1,1,6,100490,
|
||||
groove5,10064,1609000,240,370,670,0,140,1,1,1,0,1,107,100491,
|
||||
nekofu,10064,1607000,220,340,570,800,100,1,1,1,1,1,6,100493,
|
||||
groove6,10065,1609000,300,640,790,0,220,1,1,1,0,1,3,100494,
|
||||
sunglo2,10065,801000,210,360,670,810,110,1,1,1,1,1,6,100495,
|
||||
monhan4,10066,1609000,120,400,510,620,50,1,1,1,1,1,9999,100496,
|
||||
monhan5,10066,1609000,120,350,420,650,100,1,1,1,1,1,9999,100497,
|
||||
fourte,10066,800000,240,500,740,800,140,1,1,1,1,1,5,100498,
|
||||
cirnon,10069,409000,240,400,600,790,170,1,1,1,1,1,9999,100499,
|
||||
marisa,10069,409000,250,410,620,850,180,1,1,1,1,1,9999,100500,
|
||||
yakini,10069,409000,250,340,580,820,130,1,1,1,1,1,9999,100501,
|
||||
justic,10069,409000,190,360,570,830,140,1,1,1,1,1,1,100502,
|
||||
sintyo,10069,401000,250,460,700,830,160,1,1,1,1,1,6,100503,
|
||||
darkpa,10068,800000,260,390,700,840,160,1,1,1,1,1,3,100504,
|
||||
hervor,10068,800000,280,390,730,810,180,1,1,1,1,1,5,100505,
|
||||
blackl,10069,800000,190,410,730,840,120,1,1,1,1,1,3,100506,
|
||||
minest,10070,800000,210,390,620,760,130,1,1,1,1,1,1,100507,
|
||||
ordine,10070,800000,250,430,730,820,190,1,1,1,1,1,3,100508,
|
||||
dreamw,10072,800000,260,370,620,750,160,1,1,1,1,1,0,100509,
|
||||
minerv,10072,800000,320,610,900,0,250,1,1,1,0,1,4,100510,
|
||||
sekain,10073,800000,260,390,690,780,160,1,1,1,1,1,1,100511,
|
||||
farawa,10074,800000,230,360,600,760,180,1,1,1,1,1,7,100512,
|
||||
xxxrev,10076,800000,210,340,560,730,150,1,1,1,1,1,0,100513,
|
||||
daybre,10080,201000,160,320,530,720,90,1,1,1,1,1,0,100514,
|
||||
umiyur,10080,201000,140,280,460,640,80,1,1,1,1,1,1,100515,
|
||||
chalur,10080,201000,180,400,600,720,140,1,1,1,1,1,9999,100516,
|
||||
melanc,10080,201000,150,300,500,630,100,1,1,1,1,1,7,100517,
|
||||
konofu,10080,201000,230,350,620,810,110,1,1,1,1,1,1,100518,
|
||||
redhea,10081,401000,270,390,590,720,100,1,1,1,1,1,0,100519,
|
||||
warnin,10081,401000,250,360,610,740,120,1,1,1,1,1,9999,100520,
|
||||
topsec,10081,401000,240,340,510,640,130,1,1,1,1,1,9999,100521,
|
||||
dddoll,10081,401000,260,380,550,630,140,1,1,1,1,1,9999,100522,
|
||||
crocus,10077,800000,260,370,600,720,150,1,1,1,1,1,7,100524,
|
||||
moonsh,10102,800000,230,360,620,0,100,1,1,1,0,1,3,100525,
|
||||
bladem,10078,800000,280,380,630,750,170,1,1,1,1,1,4,100526,
|
||||
primaa,10104,800000,180,350,540,750,120,1,1,1,1,1,0,100527,
|
||||
fracta,10103,800000,310,520,830,0,190,1,1,1,0,1,3,100529,
|
||||
regene,10100,800000,200,300,560,700,130,1,1,1,1,1,0,100530,
|
||||
cthugh,10104,800000,250,480,730,0,140,1,1,1,0,1,0,100531,
|
||||
einher,10100,800000,290,400,740,800,160,1,1,1,1,1,4,100532,
|
||||
southw,10078,800000,180,270,570,680,120,1,1,1,1,1,7,100536,
|
||||
ryuuse,10078,800000,210,320,590,0,130,1,1,1,0,1,1,100537,
|
||||
ariell,10100,800000,190,320,640,730,150,1,1,1,1,1,7,100540,
|
||||
chipnn,10077,800000,270,340,610,790,160,1,1,1,1,1,6,100541,
|
||||
firstl,10100,800000,250,360,650,770,170,1,1,1,1,1,1,100542,
|
||||
lighto,10100,800000,250,330,600,740,120,1,1,1,1,1,1,100543,
|
||||
palpit,10102,800000,290,550,840,920,180,1,1,1,1,1,8,100544,
|
||||
lavien,10077,800000,270,410,710,800,180,1,1,1,1,1,5,100546,
|
||||
prizmm,10102,800000,210,300,540,0,120,1,1,1,0,1,1,100547,
|
||||
tracee,10081,401000,190,310,490,650,90,1,1,1,1,1,0,100548,
|
||||
allelu,10100,800000,280,350,640,750,160,1,1,1,1,1,9999,100549,
|
||||
heartl,10100,800000,230,300,640,0,110,1,1,1,0,1,1,100550,
|
||||
erasee,10100,800000,220,350,580,680,120,1,1,1,1,1,0,100551,
|
||||
termin,10100,800000,240,340,630,790,130,1,1,1,1,1,7,100552,
|
||||
kokoro,10103,800000,200,430,650,690,120,1,1,1,1,1,1,100554,
|
||||
nisenn,10103,800000,0,0,760,0,0,0,0,1,0,0,8,100555,
|
||||
ryuuse2,10101,800000,200,360,620,750,130,1,1,1,1,1,1,100556,
|
||||
gainen,10102,801000,260,370,630,0,150,1,1,1,0,1,9999,100558,
|
||||
moonki,10102,800000,250,390,640,0,130,1,1,1,0,1,1,100559,
|
||||
moonri,10102,800000,210,380,580,850,140,1,1,1,1,1,0,100560,
|
||||
goaway,10103,800000,230,450,590,700,100,1,1,1,1,1,0,100561,
|
||||
poweri,10103,800000,260,490,750,910,130,1,1,1,1,1,4,100563,
|
||||
memorm,10103,800000,260,370,730,0,150,1,1,1,0,1,0,100565,
|
||||
itback,10103,800000,230,380,710,0,120,1,1,1,0,1,3,100567,
|
||||
actual,10103,800000,250,380,800,0,140,1,1,1,0,1,0,100568,
|
||||
redhhh,10103,800000,240,390,770,0,130,1,1,1,0,1,4,100569,
|
||||
thetaa,10104,800000,210,340,620,0,110,1,1,1,0,1,1,100571,
|
||||
takesc,10104,800000,270,370,690,0,100,1,1,1,0,1,1,100572,
|
||||
kotobu,10104,800000,320,710,900,0,250,1,1,1,0,1,0,100573,
|
||||
galaxy,10000,101000,160,320,430,670,100,1,1,1,1,1,0,100600,
|
||||
levelf,10000,101000,110,280,450,630,50,1,1,1,1,1,0,100605,
|
||||
unbeli,10000,101000,130,260,380,620,70,1,1,1,1,1,0,100608,
|
||||
fiveee,10000,101000,180,370,610,710,100,1,1,1,1,1,0,100614,
|
||||
replay,10000,101000,180,440,630,700,80,1,1,1,1,1,0,100618,
|
||||
aheadd,10000,101000,130,250,350,580,70,1,1,1,1,1,0,100620,
|
||||
musicr1,10000,800000,220,330,580,740,120,1,1,1,1,1,0,100621,
|
||||
getthe,10000,101000,170,370,490,660,60,1,1,1,1,1,0,100622,
|
||||
hopesb,10000,101000,100,250,440,610,70,1,1,1,1,1,0,100625,
|
||||
shooti,10000,101000,150,370,490,690,70,1,1,1,1,1,0,100626,
|
||||
lightm,10000,101000,260,330,540,710,110,1,1,1,1,1,0,100629,
|
||||
miiroo,10000,101000,220,390,580,680,110,1,1,1,1,1,0,100630,
|
||||
vividd,10000,101000,160,350,550,650,90,1,1,1,1,1,0,100633,
|
||||
donuth,10000,201000,220,400,540,800,110,1,1,1,1,1,100,100635,
|
||||
senbon,10000,301000,200,280,540,740,120,1,1,1,1,1,0,100636,
|
||||
kmtyju,10000,101000,240,310,570,740,120,1,1,1,1,1,0,100637,
|
||||
childe,10000,101000,90,240,340,560,40,1,1,1,1,1,0,100640,
|
||||
flower,10000,101000,70,200,400,650,60,1,1,1,1,1,0,100643,
|
||||
musicr4,10000,800000,190,320,580,0,120,1,1,1,0,1,0,100647,
|
||||
breaka,10000,101000,150,310,450,680,70,1,1,1,1,1,0,100657,
|
||||
izimed,10000,101000,190,390,690,770,90,1,1,1,1,1,0,100665,
|
||||
godkno,10000,101000,100,260,450,640,60,1,1,1,1,1,0,100670,
|
||||
roadof,10000,101000,150,360,500,750,70,1,1,1,1,1,0,100671,
|
||||
rokuch,10000,301000,210,350,620,810,110,1,1,1,1,1,0,100672,
|
||||
valent,10000,800000,270,330,590,770,100,1,1,1,1,1,102,100673,
|
||||
unfini,10000,101000,160,320,500,710,80,1,1,1,1,1,0,100674,
|
||||
dropou,10000,101000,170,310,460,690,140,1,1,1,1,1,0,100678,
|
||||
xencou,10000,101000,200,320,520,600,80,1,1,1,1,1,0,100679,
|
||||
killyk,10000,101000,130,420,630,760,60,1,1,1,1,1,0,100680,
|
||||
burstt,10000,101000,120,250,460,630,70,1,1,1,1,1,0,100682,
|
||||
musicr2,10000,800000,220,330,580,0,120,1,1,1,0,1,0,100683,
|
||||
musicr3,10000,800000,190,320,580,720,120,1,1,1,1,1,0,100687,
|
||||
sugars,10000,101000,170,300,420,660,60,1,1,1,1,1,0,100689,
|
||||
wegooo,10000,101000,180,340,540,680,100,1,1,1,1,1,0,100692,
|
||||
alonee,10000,101000,110,210,360,480,50,1,1,1,1,1,0,100693,
|
||||
granro,10000,101000,150,280,430,600,80,1,1,1,1,1,0,100695,
|
||||
sister,10000,101000,100,270,460,630,70,1,1,1,1,1,0,100696,
|
||||
flawli,10000,101000,170,300,400,590,80,1,1,1,1,1,0,100699,
|
||||
inneru,10000,101000,220,360,480,670,90,1,1,1,1,1,0,100703,
|
||||
bokuwa,10000,101000,230,340,550,690,160,1,1,1,1,1,0,100706,
|
||||
showww,10000,101000,180,350,510,790,150,1,1,1,1,1,0,100707,
|
||||
nevers,10000,101000,260,320,650,750,150,1,1,1,1,1,0,100708,
|
||||
bleeze,10000,101000,160,310,470,620,90,1,1,1,1,1,0,100709,
|
|
@ -175,8 +175,8 @@ class CxbServlet(BaseServlet):
|
||||
internal_ver = CxbConstants.VER_CROSSBEATS_REV_SUNRISE_S2
|
||||
|
||||
if not hasattr(self.versions[internal_ver], func_to_find):
|
||||
self.logger.warn(f"{version_string} has no handler for filetype {filetype} / {func_to_find}")
|
||||
return({"data":""})
|
||||
self.logger.warn(f"{version_string} has no handler for filetype {filetype}")
|
||||
return ""
|
||||
|
||||
self.logger.info(f"{version_string} request for filetype {filetype}")
|
||||
self.logger.debug(req_json)
|
||||
|
@ -122,7 +122,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
def handle_data_ex0001_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_one_more_extra_list_request(self, data: Dict) -> Dict:
|
||||
@ -131,7 +131,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_oexxxx_request(self, data: Dict) -> Dict:
|
||||
def handle_data_oe0001_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
|
@ -22,17 +22,8 @@ class CxbRevSunriseS2(CxbBase):
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
version = data["dldate"]["filetype"].split("/")[0]
|
||||
ret_str = ""
|
||||
|
||||
if "10104" in version:
|
||||
self.logger.warning("Game Version is Season 2 Non-Omni")
|
||||
file = "titles/cxb/data/rss2/MusicArchiveList-NonOmni.csv"
|
||||
else:
|
||||
self.logger.warning("Game Version is Season 2 Omnimix")
|
||||
file = "titles/cxb/data/rss2/MusicArchiveList.csv"
|
||||
|
||||
with open(rf"{file}") as music:
|
||||
with open(r"titles/cxb/data/rss2/MusicArchiveList.csv") as music:
|
||||
lines = music.readlines()
|
||||
for line in lines:
|
||||
line_split = line.split(",")
|
||||
@ -129,14 +120,9 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
ret_str=""
|
||||
with open(r"titles/cxb/data/rss2/ExtraStageList.csv") as extra:
|
||||
lines = extra.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return({"data":ret_str})
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
def handle_data_ex0001_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_one_more_extra_list_request(self, data: Dict) -> Dict:
|
||||
@ -145,16 +131,11 @@ class CxbRevSunriseS2(CxbBase):
|
||||
def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_oexxxx_request(self, data: Dict) -> Dict:
|
||||
def handle_data_oe0001_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
ret_str=""
|
||||
with open(r"titles/cxb/data/rss2/FreeCoupon.csv") as coupon:
|
||||
lines = coupon.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return({"data":ret_str})
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
|
@ -1,4 +1,4 @@
|
||||
import datetime
|
||||
from datetime import datetime
|
||||
from typing import Any, List, Dict
|
||||
import logging
|
||||
import json
|
||||
@ -9,6 +9,7 @@ from core.config import CoreConfig
|
||||
from titles.diva.config import DivaConfig
|
||||
from titles.diva.const import DivaConstants
|
||||
from titles.diva.database import DivaData
|
||||
from titles.diva.handlers import *
|
||||
|
||||
|
||||
class DivaBase:
|
||||
@ -21,33 +22,42 @@ class DivaBase:
|
||||
self.game = DivaConstants.GAME_CODE
|
||||
self.version = DivaConstants.VER_PROJECT_DIVA_ARCADE_FUTURE_TONE
|
||||
|
||||
dt = datetime.datetime.now()
|
||||
self.time_lut = urllib.parse.quote(dt.strftime("%Y-%m-%d %H:%M:%S:16.0"))
|
||||
dt = datetime.now()
|
||||
self.time_lut = parse.quote(dt.strftime("%Y-%m-%d %H:%M:%S:16.0"))
|
||||
|
||||
def handle_test_request(self, data: Dict) -> Dict:
|
||||
return ""
|
||||
def handle_test_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_game_init_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_game_init_request(self, data: bytes) -> str:
|
||||
req = GameInitRequest(data)
|
||||
return None
|
||||
|
||||
def handle_attend_request(self, data: Dict) -> Dict:
|
||||
def handle_attend_request(self, data: bytes) -> str:
|
||||
req = AttendRequest(data)
|
||||
resp = AttendResponse(req.req_id)
|
||||
|
||||
for i in [0, 3, 4, 5, 7, 9, 10, 11, 12, 13]:
|
||||
resp.atnd_prm1[i] = 0
|
||||
resp.atnd_prm1[8] = 100
|
||||
|
||||
resp.atnd_prm2[:6] = [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:79] = [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 = "&"
|
||||
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}",
|
||||
}
|
||||
|
||||
encoded += urllib.parse.urlencode(params)
|
||||
encoded = encoded.replace("%2C", ",")
|
||||
|
||||
return encoded
|
||||
|
||||
def handle_ping_request(self, data: Dict) -> Dict:
|
||||
encoded = "&"
|
||||
params = {
|
||||
"ping_b_msg": f"Welcome to {self.core_cfg.server.name} network!",
|
||||
"ping_b_msg": f"Welcome to {self.core_cfg.server.name} network!" if not self.game_config.server.banner_msg else self.game_config.server.banner_msg,
|
||||
"ping_m_msg": "xxx",
|
||||
"atnd_lut": f"{self.time_lut}",
|
||||
"fi_lut": f"{self.time_lut}",
|
||||
@ -83,13 +93,12 @@ class DivaBase:
|
||||
"nblss_ltt_ed_tm": "2019-09-22 12:00:00.0",
|
||||
}
|
||||
|
||||
encoded += urllib.parse.urlencode(params)
|
||||
encoded += parse.urlencode(params, safe=",")
|
||||
encoded = encoded.replace("+", "%20")
|
||||
encoded = encoded.replace("%2C", ",")
|
||||
|
||||
return encoded
|
||||
|
||||
def handle_pv_list_request(self, data: Dict) -> Dict:
|
||||
def handle_pv_list_request(self, data: bytes) -> str:
|
||||
pvlist = ""
|
||||
with open(r"titles/diva/data/PvList0.dat", encoding="utf-8") as shop:
|
||||
lines = shop.readlines()
|
||||
@ -126,7 +135,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_shop_catalog_request(self, data: Dict) -> Dict:
|
||||
def handle_shop_catalog_request(self, data: bytes) -> str:
|
||||
catalog = ""
|
||||
|
||||
shopList = self.data.static.get_enabled_shops(self.version)
|
||||
@ -134,8 +143,8 @@ class DivaBase:
|
||||
with open(r"titles/diva/data/ShopCatalog.dat", encoding="utf-8") as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
line = urllib.parse.quote(line) + ","
|
||||
catalog += f"{urllib.parse.quote(line)}"
|
||||
line = parse.quote(line) + ","
|
||||
catalog += f"{parse.quote(line)}"
|
||||
|
||||
else:
|
||||
for shop in shopList:
|
||||
@ -154,8 +163,8 @@ class DivaBase:
|
||||
+ ","
|
||||
+ str(shop["type"])
|
||||
)
|
||||
line = urllib.parse.quote(line) + ","
|
||||
catalog += f"{urllib.parse.quote(line)}"
|
||||
line = parse.quote(line) + ","
|
||||
catalog += f"{parse.quote(line)}"
|
||||
|
||||
catalog = catalog.replace("+", "%20")
|
||||
|
||||
@ -164,7 +173,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_buy_module_request(self, data: Dict) -> Dict:
|
||||
def handle_buy_module_request(self, data: bytes) -> str:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
module = self.data.static.get_enabled_shop(self.version, int(data["mdl_id"]))
|
||||
|
||||
@ -191,7 +200,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_cstmz_itm_ctlg_request(self, data: Dict) -> Dict:
|
||||
def handle_cstmz_itm_ctlg_request(self, data: bytes) -> str:
|
||||
catalog = ""
|
||||
|
||||
itemList = self.data.static.get_enabled_items(self.version)
|
||||
@ -199,8 +208,8 @@ class DivaBase:
|
||||
with open(r"titles/diva/data/ItemCatalog.dat", encoding="utf-8") as item:
|
||||
lines = item.readlines()
|
||||
for line in lines:
|
||||
line = urllib.parse.quote(line) + ","
|
||||
catalog += f"{urllib.parse.quote(line)}"
|
||||
line = parse.quote(line) + ","
|
||||
catalog += f"{parse.quote(line)}"
|
||||
|
||||
else:
|
||||
for item in itemList:
|
||||
@ -219,8 +228,8 @@ class DivaBase:
|
||||
+ ","
|
||||
+ str(item["type"])
|
||||
)
|
||||
line = urllib.parse.quote(line) + ","
|
||||
catalog += f"{urllib.parse.quote(line)}"
|
||||
line = parse.quote(line) + ","
|
||||
catalog += f"{parse.quote(line)}"
|
||||
|
||||
catalog = catalog.replace("+", "%20")
|
||||
|
||||
@ -229,7 +238,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_buy_cstmz_itm_request(self, data: Dict) -> Dict:
|
||||
def handle_buy_cstmz_itm_request(self, data: bytes) -> str:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
item = self.data.static.get_enabled_item(
|
||||
self.version, int(data["cstmz_itm_id"])
|
||||
@ -264,7 +273,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_festa_info_request(self, data: Dict) -> Dict:
|
||||
def handle_festa_info_request(self, data: bytes) -> str:
|
||||
encoded = "&"
|
||||
params = {
|
||||
"fi_id": "1,2",
|
||||
@ -277,17 +286,17 @@ class DivaBase:
|
||||
"fi_add_vp": "20,5",
|
||||
"fi_mul_vp": "1,2",
|
||||
"fi_st": "2019-01-01 00:00:00.0,2019-01-01 00:00:00.0",
|
||||
"fi_et": "2029-01-01 00:00:00.0,2029-01-01 00:00:00.0",
|
||||
"fi_lut": "{self.time_lut}",
|
||||
"fi_et": "2029-01-01 00:00:00.0,2029-01-01 00:00:00.0", # TODO: make this last longer
|
||||
"fi_lut": f"{self.time_lut}",
|
||||
}
|
||||
|
||||
encoded += urllib.parse.urlencode(params)
|
||||
encoded += parse.urlencode(params)
|
||||
encoded = encoded.replace("+", "%20")
|
||||
encoded = encoded.replace("%2C", ",")
|
||||
|
||||
return encoded
|
||||
|
||||
def handle_contest_info_request(self, data: Dict) -> Dict:
|
||||
def handle_contest_info_request(self, data: bytes) -> str:
|
||||
response = ""
|
||||
|
||||
response += f"&ci_lut={self.time_lut}"
|
||||
@ -295,7 +304,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_qst_inf_request(self, data: Dict) -> Dict:
|
||||
def handle_qst_inf_request(self, data: bytes) -> str:
|
||||
quest = ""
|
||||
|
||||
questList = self.data.static.get_enabled_quests(self.version)
|
||||
@ -303,7 +312,7 @@ class DivaBase:
|
||||
with open(r"titles/diva/data/QuestInfo.dat", encoding="utf-8") as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
quest += f"{urllib.parse.quote(line)},"
|
||||
quest += f"{parse.quote(line)},"
|
||||
|
||||
response = ""
|
||||
response += f"&qi_lut={self.time_lut}"
|
||||
@ -331,7 +340,7 @@ class DivaBase:
|
||||
+ ","
|
||||
+ str(quests["quest_enable"])
|
||||
)
|
||||
quest += f"{urllib.parse.quote(line)}%0A,"
|
||||
quest += f"{parse.quote(line)}%0A,"
|
||||
|
||||
responseline = f"{quest[:-1]},"
|
||||
for i in range(len(questList), 59):
|
||||
@ -345,166 +354,108 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_nv_ranking_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_nv_ranking_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_ps_ranking_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_ps_ranking_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_ng_word_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_ng_word_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_rmt_wp_list_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_rmt_wp_list_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_pv_def_chr_list_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_pv_def_chr_list_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_pv_ng_mdl_list_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_pv_ng_mdl_list_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_cstmz_itm_ng_mdl_lst_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_cstmz_itm_ng_mdl_lst_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_banner_info_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_banner_info_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_banner_data_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_banner_data_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_cm_ply_info_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_cm_ply_info_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_pstd_h_ctrl_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_pstd_h_ctrl_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_pstd_item_ng_lst_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_pstd_item_ng_lst_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_pre_start_request(self, data: Dict) -> str:
|
||||
profile = self.data.profile.get_profile(data["aime_id"], self.version)
|
||||
profile_shop = self.data.item.get_shop(data["aime_id"], self.version)
|
||||
def handle_pre_start_request(self, data: bytes) -> str:
|
||||
req = PreStartRequest(data)
|
||||
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)
|
||||
|
||||
if profile is None:
|
||||
return f"&ps_result=-3"
|
||||
else:
|
||||
response = "&ps_result=1"
|
||||
response += "&accept_idx=100"
|
||||
response += "&nblss_ltt_stts=-1"
|
||||
response += "&nblss_ltt_tckt=-1"
|
||||
response += "&nblss_ltt_is_opn=-1"
|
||||
response += f"&pd_id={data['aime_id']}"
|
||||
response += f"&player_name={profile['player_name']}"
|
||||
response += f"&sort_kind={profile['player_name']}"
|
||||
response += f"&lv_efct_id={profile['lv_efct_id']}"
|
||||
response += f"&lv_plt_id={profile['lv_plt_id']}"
|
||||
response += f"&lv_str={profile['lv_str']}"
|
||||
response += f"&lv_num={profile['lv_num']}"
|
||||
response += f"&lv_pnt={profile['lv_pnt']}"
|
||||
response += f"&vcld_pts={profile['vcld_pts']}"
|
||||
response += f"&skn_eqp={profile['skn_eqp']}"
|
||||
response += f"&btn_se_eqp={profile['btn_se_eqp']}"
|
||||
response += f"&sld_se_eqp={profile['sld_se_eqp']}"
|
||||
response += f"&chn_sld_se_eqp={profile['chn_sld_se_eqp']}"
|
||||
response += f"&sldr_tch_se_eqp={profile['sldr_tch_se_eqp']}"
|
||||
response += f"&passwd_stat={profile['passwd_stat']}"
|
||||
|
||||
# Store stuff to add to rework
|
||||
response += f"&mdl_eqp_tm={self.time_lut}"
|
||||
profile_dict = profile._asdict()
|
||||
profile_dict.pop("id")
|
||||
profile_dict.pop("user")
|
||||
profile_dict.pop("version")
|
||||
|
||||
mdl_eqp_ary = "-999,-999,-999"
|
||||
for k, v in profile_dict.items():
|
||||
if hasattr(resp, k):
|
||||
setattr(resp, k, v)
|
||||
|
||||
# get the common_modules from the profile shop
|
||||
if profile_shop:
|
||||
mdl_eqp_ary = profile_shop["mdl_eqp_ary"]
|
||||
if profile_shop is not None and profile_shop:
|
||||
resp.mdl_eqp_ary = profile_shop["mdl_eqp_ary"]
|
||||
|
||||
response += f"&mdl_eqp_ary={mdl_eqp_ary}"
|
||||
return resp.make()
|
||||
|
||||
return response
|
||||
|
||||
def handle_registration_request(self, data: Dict) -> Dict:
|
||||
self.data.profile.create_profile(
|
||||
self.version, data["aime_id"], data["player_name"]
|
||||
def handle_registration_request(self, data: bytes) -> str:
|
||||
req = RegisterRequest(data)
|
||||
pd_id = self.data.profile.create_profile(
|
||||
self.version, req.aime_id, req.player_name
|
||||
)
|
||||
return f"&cd_adm_result=1&pd_id={data['aime_id']}"
|
||||
if pd_id is None:
|
||||
return "&cd_adm_result=-1"
|
||||
return RegisterResponse(req.req_id, req.aime_id).make()
|
||||
|
||||
def handle_start_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
profile_shop = self.data.item.get_shop(data["pd_id"], self.version)
|
||||
def handle_start_request(self, data: bytes) -> str:
|
||||
req = StartRequest(data)
|
||||
profile = self.data.profile.get_profile(req.pd_id, self.version)
|
||||
profile_shop = self.data.item.get_shop(req.pd_id, self.version)
|
||||
if profile is None:
|
||||
return
|
||||
|
||||
resp = StartResponse(req.req_id, req.pd_id, profile['player_name'])
|
||||
|
||||
profile_dict = profile._asdict()
|
||||
profile_dict.pop("id")
|
||||
profile_dict.pop("user")
|
||||
profile_dict.pop("version")
|
||||
|
||||
for k, v in profile_dict.items():
|
||||
if hasattr(resp, k):
|
||||
setattr(resp, k, v)
|
||||
|
||||
mdl_have = "F" * 250
|
||||
# generate the mdl_have string if "unlock_all_modules" is disabled
|
||||
if not self.game_config.mods.unlock_all_modules:
|
||||
mdl_have = self.data.module.get_modules_have_string(
|
||||
data["pd_id"], self.version
|
||||
resp.mdl_have = self.data.module.get_modules_have_string(
|
||||
req.pd_id, self.version
|
||||
)
|
||||
|
||||
cstmz_itm_have = "F" * 250
|
||||
# generate the cstmz_itm_have string if "unlock_all_items" is disabled
|
||||
if not self.game_config.mods.unlock_all_items:
|
||||
cstmz_itm_have = self.data.customize.get_customize_items_have_string(
|
||||
data["pd_id"], self.version
|
||||
resp.cstmz_itm_have = self.data.customize.get_customize_items_have_string(
|
||||
req.pd_id, self.version
|
||||
)
|
||||
|
||||
response = f"&pd_id={data['pd_id']}"
|
||||
response += "&start_result=1"
|
||||
|
||||
response += "&accept_idx=100"
|
||||
response += f"&hp_vol={profile['hp_vol']}"
|
||||
response += f"&btn_se_vol={profile['btn_se_vol']}"
|
||||
response += f"&btn_se_vol2={profile['btn_se_vol2']}"
|
||||
response += f"&sldr_se_vol2={profile['sldr_se_vol2']}"
|
||||
response += f"&sort_kind={profile['sort_kind']}"
|
||||
response += f"&player_name={profile['player_name']}"
|
||||
response += f"&lv_num={profile['lv_num']}"
|
||||
response += f"&lv_pnt={profile['lv_pnt']}"
|
||||
response += f"&lv_efct_id={profile['lv_efct_id']}"
|
||||
response += f"&lv_plt_id={profile['lv_plt_id']}"
|
||||
response += f"&mdl_have={mdl_have}"
|
||||
response += f"&cstmz_itm_have={cstmz_itm_have}"
|
||||
response += f"&use_pv_mdl_eqp={int(profile['use_pv_mdl_eqp'])}"
|
||||
response += f"&use_mdl_pri={int(profile['use_mdl_pri'])}"
|
||||
response += f"&use_pv_skn_eqp={int(profile['use_pv_skn_eqp'])}"
|
||||
response += f"&use_pv_btn_se_eqp={int(profile['use_pv_btn_se_eqp'])}"
|
||||
response += f"&use_pv_sld_se_eqp={int(profile['use_pv_sld_se_eqp'])}"
|
||||
response += f"&use_pv_chn_sld_se_eqp={int(profile['use_pv_chn_sld_se_eqp'])}"
|
||||
response += f"&use_pv_sldr_tch_se_eqp={int(profile['use_pv_sldr_tch_se_eqp'])}"
|
||||
response += f"&vcld_pts={profile['lv_efct_id']}"
|
||||
response += f"&nxt_pv_id={profile['nxt_pv_id']}"
|
||||
response += f"&nxt_dffclty={profile['nxt_dffclty']}"
|
||||
response += f"&nxt_edtn={profile['nxt_edtn']}"
|
||||
response += f"&dsp_clr_brdr={profile['dsp_clr_brdr']}"
|
||||
response += f"&dsp_intrm_rnk={profile['dsp_intrm_rnk']}"
|
||||
response += f"&dsp_clr_sts={profile['dsp_clr_sts']}"
|
||||
response += f"&rgo_sts={profile['rgo_sts']}"
|
||||
|
||||
# Contest progress
|
||||
response += f"&cv_cid=-1,-1,-1,-1"
|
||||
response += f"&cv_sc=-1,-1,-1,-1"
|
||||
response += f"&cv_bv=-1,-1,-1,-1"
|
||||
response += f"&cv_bv=-1,-1,-1,-1"
|
||||
response += f"&cv_bf=-1,-1,-1,-1"
|
||||
|
||||
# Contest now playing id, return -1 if no current playing contest
|
||||
response += f"&cnp_cid={profile['cnp_cid']}"
|
||||
response += f"&cnp_val={profile['cnp_val']}"
|
||||
# border can be 0=bronzem 1=silver, 2=gold
|
||||
response += f"&cnp_rr={profile['cnp_rr']}"
|
||||
# only show contest specifier if it is not empty
|
||||
response += f"&cnp_sp={profile['cnp_sp']}" if profile["cnp_sp"] != "" else ""
|
||||
|
||||
# To be fully fixed
|
||||
if "my_qst_id" not in profile:
|
||||
response += f"&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"
|
||||
response += f"&my_qst_sts=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"
|
||||
else:
|
||||
response += f"&my_qst_id={profile['my_qst_id']}"
|
||||
response += f"&my_qst_sts={profile['my_qst_sts']}"
|
||||
|
||||
response += f"&my_qst_prgrs=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"
|
||||
response += f"&my_qst_et=2022-06-19%2010%3A28%3A52.0,2022-06-19%2010%3A28%3A52.0,2022-06-19%2010%3A28%3A52.0,2100-01-01%2008%3A59%3A59.0,2100-01-01%2008%3A59%3A59.0,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx"
|
||||
if "my_qst_id" in profile:
|
||||
resp.my_qst_id = profile['my_qst_id']
|
||||
resp.my_qst_sts = profile['my_qst_sts']
|
||||
|
||||
# define a helper class to store all counts for clear, great,
|
||||
# excellent and perfect
|
||||
@ -525,7 +476,7 @@ class DivaBase:
|
||||
}
|
||||
|
||||
# get clear status from user scores
|
||||
pv_records = self.data.score.get_best_scores(data["pd_id"])
|
||||
pv_records = self.data.score.get_best_scores(req.pd_id)
|
||||
clear_status = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||
|
||||
if pv_records is not None:
|
||||
@ -561,46 +512,33 @@ class DivaBase:
|
||||
|
||||
clear_status = ",".join(map(str, clear_list))
|
||||
|
||||
response += f"&clr_sts={clear_status}"
|
||||
|
||||
# Store stuff to add to rework
|
||||
response += f"&mdl_eqp_tm={self.time_lut}"
|
||||
|
||||
mdl_eqp_ary = "-999,-999,-999"
|
||||
c_itm_eqp_ary = "-999,-999,-999,-999,-999,-999,-999,-999,-999,-999,-999,-999"
|
||||
ms_itm_flg_ary = "1,1,1,1,1,1,1,1,1,1,1,1"
|
||||
resp.clr_sts = clear_status
|
||||
|
||||
# get the common_modules, customize_items and customize_item_flags
|
||||
# from the profile shop
|
||||
if profile_shop:
|
||||
mdl_eqp_ary = profile_shop["mdl_eqp_ary"]
|
||||
c_itm_eqp_ary = profile_shop["c_itm_eqp_ary"]
|
||||
ms_itm_flg_ary = profile_shop["ms_itm_flg_ary"]
|
||||
resp.mdl_eqp_ary = profile_shop["mdl_eqp_ary"]
|
||||
resp.c_itm_eqp_ary = profile_shop["c_itm_eqp_ary"]
|
||||
resp.ms_itm_flg_ary = profile_shop["ms_itm_flg_ary"]
|
||||
|
||||
response += f"&mdl_eqp_ary={mdl_eqp_ary}"
|
||||
response += f"&c_itm_eqp_ary={c_itm_eqp_ary}"
|
||||
response += f"&ms_itm_flg_ary={ms_itm_flg_ary}"
|
||||
return resp.make()
|
||||
|
||||
return response
|
||||
def handle_pd_unlock_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_pd_unlock_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_spend_credit_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
def handle_spend_credit_request(self, data: bytes) -> str:
|
||||
req = SpendCreditRequest(data)
|
||||
profile = self.data.profile.get_profile(req.pd_id, self.version)
|
||||
if profile is None:
|
||||
return
|
||||
|
||||
response = ""
|
||||
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']
|
||||
resp.lv_plt_id = profile['lv_plt_id']
|
||||
|
||||
response += "&cmpgn_rslt=-1,-1,x,-1,-1,x,x,-1,x,-1,-1,x,-1,-1,x,x,-1,x,-1,-1,x,-1,-1,x,x,-1,x,-1,-1,x,-1,-1,x,x,-1,x,-1,-1,x,-1,-1,x,x,-1,x,-1,-1,x,-1,-1,x,x,-1,x"
|
||||
response += "&cmpgn_rslt_num=0"
|
||||
response += f"&vcld_pts={profile['vcld_pts']}"
|
||||
response += f"&lv_str={profile['lv_str']}"
|
||||
response += f"&lv_efct_id={profile['lv_efct_id']}"
|
||||
response += f"&lv_plt_id={profile['lv_plt_id']}"
|
||||
|
||||
return response
|
||||
return resp.make()
|
||||
|
||||
def _get_pv_pd_result(
|
||||
self,
|
||||
@ -664,31 +602,31 @@ class DivaBase:
|
||||
|
||||
return pv_result
|
||||
|
||||
def task_generateScoreData(self, data: Dict, pd_by_pv_id, song):
|
||||
def task_generateScoreData(self, pd_id: int, difficulty: int, pd_by_pv_id: str, song: int):
|
||||
|
||||
if int(song) > 0:
|
||||
# the request do not send a edition so just perform a query best score and ranking for each edition.
|
||||
# 0=ORIGINAL, 1=EXTRA
|
||||
pd_db_song_0 = self.data.score.get_best_user_score(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=0
|
||||
pd_id, int(song), difficulty, edition=0
|
||||
)
|
||||
pd_db_song_1 = self.data.score.get_best_user_score(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=1
|
||||
pd_id, int(song), difficulty, edition=1
|
||||
)
|
||||
|
||||
pd_db_ranking_0, pd_db_ranking_1 = None, None
|
||||
if pd_db_song_0:
|
||||
pd_db_ranking_0 = self.data.score.get_global_ranking(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=0
|
||||
pd_id, int(song), difficulty, edition=0
|
||||
)
|
||||
|
||||
if pd_db_song_1:
|
||||
pd_db_ranking_1 = self.data.score.get_global_ranking(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=1
|
||||
pd_id, int(song), difficulty, edition=1
|
||||
)
|
||||
|
||||
pd_db_customize = self.data.pv_customize.get_pv_customize(
|
||||
data["pd_id"], int(song)
|
||||
pd_id, int(song)
|
||||
)
|
||||
|
||||
# generate the pv_result string with the ORIGINAL edition and the EXTRA edition appended
|
||||
@ -706,14 +644,14 @@ class DivaBase:
|
||||
pd_by_pv_id.append(",")
|
||||
|
||||
def handle_get_pv_pd_request(self, data: Dict) -> Dict:
|
||||
song_id = data["pd_pv_id_lst"].split(",")
|
||||
req = GetPvPdRequest(data)
|
||||
pv = ""
|
||||
|
||||
threads = []
|
||||
pd_by_pv_id = []
|
||||
|
||||
for song in song_id:
|
||||
thread_ScoreData = Thread(target=self.task_generateScoreData(data, pd_by_pv_id, song))
|
||||
for song in req.pd_pv_id_lst:
|
||||
thread_ScoreData = Thread(target=self.task_generateScoreData(req.pd_id, req.difficulty, pd_by_pv_id, song))
|
||||
threads.append(thread_ScoreData)
|
||||
|
||||
for x in threads:
|
||||
@ -725,44 +663,48 @@ class DivaBase:
|
||||
for x in pd_by_pv_id:
|
||||
pv += x
|
||||
|
||||
resp = GetPvPdResponse(req.req_id)
|
||||
resp.pd_by_pv_id = pv[:-1]
|
||||
response = ""
|
||||
response += f"&pd_by_pv_id={pv[:-1]}"
|
||||
response += "&pdddt_flg=0"
|
||||
response += f"&pdddt_tm={self.time_lut}"
|
||||
|
||||
return response
|
||||
return resp.make()
|
||||
|
||||
def handle_stage_start_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
def handle_stage_start_request(self, data: bytes) -> str:
|
||||
pass
|
||||
|
||||
def handle_stage_result_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
def handle_stage_result_request(self, data: bytes) -> str:
|
||||
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],
|
||||
@ -779,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],
|
||||
@ -797,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],
|
||||
@ -814,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],
|
||||
@ -832,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],
|
||||
@ -852,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:
|
||||
@ -861,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'])}"
|
||||
@ -870,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}"
|
||||
@ -912,17 +866,18 @@ 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: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
def handle_end_request(self, data: bytes) -> str:
|
||||
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: Dict) -> Dict:
|
||||
def handle_shop_exit_request(self, data: bytes) -> str:
|
||||
self.data.item.put_shop(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
|
@ -18,6 +18,12 @@ class DivaServerConfig:
|
||||
self.__config, "diva", "server", "loglevel", default="info"
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def banner_msg(self) -> str:
|
||||
CoreConfig.get_config_field(
|
||||
self.__config, "diva", "server", "banner_msg", default=""
|
||||
)
|
||||
|
||||
|
||||
class DivaModsConfig:
|
||||
|
@ -6,6 +6,8 @@ class DivaConstants:
|
||||
VER_PROJECT_DIVA_ARCADE = 0
|
||||
VER_PROJECT_DIVA_ARCADE_FUTURE_TONE = 1
|
||||
|
||||
LUT_TIME_FMT = "%Y-%m-%d %H:%M:%S:16.0"
|
||||
|
||||
VERSION_NAMES = ("Project Diva Arcade", "Project Diva Arcade Future Tone")
|
||||
|
||||
@classmethod
|
||||
|
3
titles/diva/handlers/__init__.py
Normal file
3
titles/diva/handlers/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .base import *
|
||||
from .user import *
|
||||
from .pv import *
|
275
titles/diva/handlers/base.py
Normal file
275
titles/diva/handlers/base.py
Normal file
@ -0,0 +1,275 @@
|
||||
from urllib import parse
|
||||
from urllib.parse import quote
|
||||
from datetime import datetime
|
||||
from typing import Union, Dict, List, Any
|
||||
|
||||
from ..const import DivaConstants
|
||||
|
||||
def lazy_http_form_parse(src: Union[str, bytes]) -> Dict[bytes, bytes]:
|
||||
out = {}
|
||||
if type(src) == str:
|
||||
src = src.encode()
|
||||
for param in src.split(b"&"):
|
||||
kvp = param.split(b"=")
|
||||
out[parse.unquote(kvp[0])] = parse.unquote(kvp[1])
|
||||
|
||||
return out
|
||||
|
||||
class DivaRequestParseException(Exception):
|
||||
"""
|
||||
Exception raised when there is a fault in parsing a diva request,
|
||||
either due to a malformed request, or missing required items
|
||||
"""
|
||||
|
||||
def __init__(self, message: str) -> None:
|
||||
self.message = message
|
||||
super().__init__(self.message)
|
||||
|
||||
class BaseBinaryRequest:
|
||||
cmd: str
|
||||
req_id: str
|
||||
|
||||
def __init__(self, raw: bytes) -> None:
|
||||
self.raw = raw
|
||||
self.raw_dict = dict(parse.parse_qsl(raw))
|
||||
|
||||
if "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:
|
||||
raise DivaRequestParseException(
|
||||
f"req_id not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
for k, v in self.raw_dict.items():
|
||||
setattr(self, k, v)
|
||||
|
||||
class BaseRequest:
|
||||
def __init__(self, raw: Union[str, bytes]) -> None:
|
||||
self.raw = raw
|
||||
try:
|
||||
self.raw_dict: Dict[str, str] = lazy_http_form_parse(raw)
|
||||
except UnicodeDecodeError as e:
|
||||
raise DivaRequestParseException(f"Could not decode data {raw} - {e}")
|
||||
|
||||
if "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:
|
||||
raise DivaRequestParseException(
|
||||
f"req_id not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
if "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:
|
||||
raise DivaRequestParseException(
|
||||
f"start_up_mode not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
if "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:
|
||||
raise DivaRequestParseException(
|
||||
f"cmm_dly_sec not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
if "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:
|
||||
raise DivaRequestParseException(
|
||||
f"region_code not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
if "time_stamp" not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"time_stamp not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
self.cmd: str = self.raw_dict.get('cmd')
|
||||
self.req_id: str = self.raw_dict.get('req_id')
|
||||
self.game_id: str = self.raw_dict.get('game_id')
|
||||
self.r_rev: str = self.raw_dict.get('r_rev')
|
||||
self.kc_serial: str = self.raw_dict.get('kc_serial')
|
||||
self.b_serial: str = self.raw_dict.get('b_serial')
|
||||
self.country_code: str = self.raw_dict.get('country_code')
|
||||
self.place_id = int(self.raw_dict['place_id'], 16)
|
||||
self.start_up_mode = int(self.raw_dict.get('start_up_mode'))
|
||||
self.cmm_dly_mod = int(self.raw_dict.get('cmm_dly_mod'))
|
||||
self.cmm_dly_sec = int(self.raw_dict.get('cmm_dly_sec'))
|
||||
self.cmm_err_mod = int(self.raw_dict.get('cmm_err_mod'))
|
||||
self.region_code = int(self.raw_dict.get('region_code'))
|
||||
# datetime.now().astimezone().replace(microsecond=0).isoformat()
|
||||
self.time_stamp = datetime.strptime(self.raw_dict.get('time_stamp'), "%Y-%m-%dT%H:%M:%S%z")
|
||||
|
||||
class BaseResponse:
|
||||
def __init__(self, cmd_id: str, req_id: int) -> None:
|
||||
self.cmd = cmd_id
|
||||
self.req_id = req_id
|
||||
self.stat = "ok"
|
||||
|
||||
def make(self) -> str:
|
||||
itms: List[str] = []
|
||||
|
||||
for k, v in vars(self).items():
|
||||
if type(v) == int:
|
||||
itms.append(encode_int(k, v))
|
||||
elif type(v) == bool:
|
||||
itms.append(encode_bool(k, v))
|
||||
elif type(v) == datetime:
|
||||
itms.append(encode_date(k, v))
|
||||
elif type(v) == list:
|
||||
itms.append(encode_list(k, v))
|
||||
else:
|
||||
itms.append(encode_str(k, v))
|
||||
|
||||
return "&".join(itms)
|
||||
|
||||
class GameInitRequest(BaseRequest):
|
||||
def __init__(self, raw: Union[str, bytes]) -> None:
|
||||
super().__init__(raw)
|
||||
|
||||
class AttendRequest(BaseRequest):
|
||||
def __init__(self, raw: Union[str, bytes]) -> None:
|
||||
super().__init__(raw)
|
||||
if 'power_on' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"power_on not in request data {self.raw_dict}"
|
||||
)
|
||||
if 'is_bb' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"is_bb not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
self.power_on = int(self.raw_dict.get('power_on'))
|
||||
self.is_bb = bool(int(self.raw_dict.get('is_bb')))
|
||||
|
||||
class AttendResponse(BaseResponse):
|
||||
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
|
||||
self.atnd_lut = datetime.now()
|
||||
|
||||
def make(self) -> str:
|
||||
return quote(super().make(), safe=",&=")
|
||||
|
||||
class SpendCreditRequest(BaseRequest):
|
||||
def __init__(self, raw: Union[str, bytes]) -> None:
|
||||
super().__init__(raw)
|
||||
if 'pd_id' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"pd_id not in request data {self.raw_dict}"
|
||||
)
|
||||
if 'my_qst_id' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"my_qst_id not in request data {self.raw_dict}"
|
||||
)
|
||||
if 'my_qst_sts' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"my_qst_sts not in request data {self.raw_dict}"
|
||||
)
|
||||
if 'crdt_typ' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"crdt_typ not in request data {self.raw_dict}"
|
||||
)
|
||||
if 'cmpgn_id' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"cmpgn_id not in request data {self.raw_dict}"
|
||||
)
|
||||
if 'cmpgn_pb' not in self.raw_dict:
|
||||
raise DivaRequestParseException(
|
||||
f"cmpgn_pb not in request data {self.raw_dict}"
|
||||
)
|
||||
|
||||
self.pd_id = int(self.raw_dict.get('pd_id'))
|
||||
self.my_qst_id = decode_list_int(self.raw_dict.get('my_qst_id'))
|
||||
self.my_qst_sts = decode_list_int(self.raw_dict.get('my_qst_sts'))
|
||||
self.crdt_typ = int(self.raw_dict.get('crdt_typ'))
|
||||
self.cmpgn_id = decode_list_int(self.raw_dict.get('cmpgn_id'))
|
||||
self.cmpgn_pb = decode_list_int(self.raw_dict.get('cmpgn_pb'))
|
||||
|
||||
class SpendCreditResponse(BaseResponse):
|
||||
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
|
||||
self.lv_str = ""
|
||||
self.lv_efct_id = 0
|
||||
self.lv_plt_id = 0
|
||||
|
||||
def encode_int(key: str, val: Union[int, None] = None) -> str:
|
||||
if type(val) != int:
|
||||
val = -1
|
||||
|
||||
return f"{key}={val}"
|
||||
|
||||
def encode_bool(key: str, val: Union[bool, None] = None) -> str:
|
||||
if not val:
|
||||
return encode_int(key, 0)
|
||||
|
||||
return encode_int(key, 1)
|
||||
|
||||
def encode_str(key: str, val: Union[str, None] = None, urlencode_val: bool = False) -> str:
|
||||
if type(val) != str:
|
||||
val = "xxx"
|
||||
|
||||
if urlencode_val:
|
||||
val = quote(val)
|
||||
|
||||
return f"{key}={val}"
|
||||
|
||||
def encode_date(key: str, val: Union[datetime, None], urlencode_val: bool = True, fmt: str = DivaConstants.LUT_TIME_FMT) -> str:
|
||||
if type(val) != datetime:
|
||||
val = datetime.now().astimezone()
|
||||
|
||||
val = val.replace(microsecond=0)
|
||||
|
||||
dt_fmt = val.strftime(fmt)
|
||||
if urlencode_val:
|
||||
dt_fmt = quote(dt_fmt)
|
||||
|
||||
return f"{key}={dt_fmt}"
|
||||
|
||||
def encode_list(key: str, val: Union[List[Any], None], urlencode_final_val: bool = False, urlencode_vals: bool = False) -> str:
|
||||
if not val:
|
||||
return f"{key}="
|
||||
|
||||
for x in range(len(val)):
|
||||
if val[x] is None:
|
||||
val[x] = "x"
|
||||
|
||||
if type(val[x]) == datetime:
|
||||
val[x] = val[x].replace(microsecond=0).strftime(DivaConstants.LUT_TIME_FMT)
|
||||
|
||||
elif type(val[x]) == bool:
|
||||
val[x] = str(int(val[x]))
|
||||
|
||||
elif type(val[x]) == int:
|
||||
val[x] = str(val[x])
|
||||
|
||||
if urlencode_vals:
|
||||
val[x] = quote(val[x])
|
||||
|
||||
all_vals = ",".join(val)
|
||||
if urlencode_final_val:
|
||||
all_vals = quote(all_vals)
|
||||
|
||||
return f"{key}={all_vals}"
|
||||
|
||||
def decode_list_int(val: str) -> List[int]:
|
||||
return [int(x) for x in val.split(",")]
|
||||
|
||||
def decode_list(val: str) -> List[str]:
|
||||
return [x for x in val.split(",")]
|
156
titles/diva/handlers/pv.py
Normal file
156
titles/diva/handlers/pv.py
Normal file
@ -0,0 +1,156 @@
|
||||
from typing import Union, List
|
||||
from titles.diva.handlers.base import (
|
||||
BaseRequest,
|
||||
BaseResponse,
|
||||
DivaRequestParseException,
|
||||
decode_list_int
|
||||
)
|
||||
from datetime import datetime
|
||||
from urllib import parse
|
||||
from ..const import DivaConstants
|
||||
|
||||
class GetPvPdRequest(BaseRequest):
|
||||
def __init__(self, raw: Union[str, bytes]) -> None:
|
||||
super().__init__(raw)
|
||||
try:
|
||||
self.pd_id = int(self.raw_dict.get('pd_id'))
|
||||
self.accept_idx = int(self.raw_dict.get('accept_idx'))
|
||||
self.start_idx = int(self.raw_dict.get('start_idx'))
|
||||
self.difficulty = int(self.raw_dict.get('difficulty'))
|
||||
self.pd_pv_id_lst: List[int] = [int(x) for x in self.pd_pv_id_lst.split(',')]
|
||||
|
||||
except AttributeError as e:
|
||||
raise DivaRequestParseException(f"GetPvPdRequest: {e}")
|
||||
|
||||
class GetPvPdResponse(BaseResponse):
|
||||
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))
|
||||
|
||||
class StageResultRequest(BaseRequest):
|
||||
def __init__(self, raw: Union[str, bytes]) -> None:
|
||||
super().__init__(raw)
|
||||
self.pd_id = int(self.raw_dict.get('pd_id'))
|
||||
self.accept_idx = int(self.raw_dict.get('accept_idx'))
|
||||
self.start_idx = int(self.raw_dict.get('start_idx'))
|
||||
self.hp_vol = int(self.raw_dict.get('hp_vol'))
|
||||
self.btn_se_vol = int(self.raw_dict.get('btn_se_vol'))
|
||||
self.btn_se_vol2 = int(self.raw_dict.get('btn_se_vol2'))
|
||||
self.sldr_se_vol2 = int(self.raw_dict.get('sldr_se_vol2'))
|
||||
self.use_pv_mdl_eqp = int(self.raw_dict.get('use_pv_mdl_eqp'))
|
||||
self.vcld_pts = int(self.raw_dict.get('vcld_pts'))
|
||||
self.nxt_pv_id = int(self.raw_dict.get('nxt_pv_id'))
|
||||
self.nxt_dffclty = int(self.raw_dict.get('nxt_dffclty'))
|
||||
self.nxt_edtn = int(self.raw_dict.get('nxt_edtn'))
|
||||
self.sort_kind = int(self.raw_dict.get('sort_kind'))
|
||||
self.nblss_ltt_stts = int(self.raw_dict.get('nblss_ltt_stts'))
|
||||
self.nblss_ltt_tckt = int(self.raw_dict.get('nblss_ltt_tckt'))
|
||||
self.free_play = int(self.raw_dict.get('free_play'))
|
||||
self.game_type = int(self.raw_dict.get('game_type'))
|
||||
self.ply_pv_id = int(self.raw_dict.get('ply_pv_id'))
|
||||
self.ttl_vp_add = int(self.raw_dict.get('ttl_vp_add'))
|
||||
self.ttl_vp_sub = int(self.raw_dict.get('ttl_vp_sub'))
|
||||
self.continue_cnt = int(self.raw_dict.get('continue_cnt'))
|
||||
self.cr_cid = int(self.raw_dict.get('cr_cid'))
|
||||
self.cr_sc = int(self.raw_dict.get('cr_sc'))
|
||||
self.cr_tv = int(self.raw_dict.get('cr_tv'))
|
||||
self.cr_if = int(self.raw_dict.get('cr_if'))
|
||||
|
||||
self.my_qst_id: List[int] = decode_list_int(self.raw_dict.get('my_qst_id'))
|
||||
self.my_qst_sts: List[int] = decode_list_int(self.raw_dict.get('my_qst_sts'))
|
||||
self.stg_difficulty: List[int] = decode_list_int(self.raw_dict.get('stg_difficulty'))
|
||||
self.stg_edtn: List[int] = decode_list_int(self.raw_dict.get('stg_edtn'))
|
||||
self.stg_ply_pv_id: List[int] = decode_list_int(self.raw_dict.get('stg_ply_pv_id'))
|
||||
self.stg_sel_pv_id: List[int] = decode_list_int(self.raw_dict.get('stg_sel_pv_id'))
|
||||
self.stg_scrpt_ver: List[int] = decode_list_int(self.raw_dict.get('stg_scrpt_ver'))
|
||||
self.stg_score: List[int] = decode_list_int(self.raw_dict.get('stg_score'))
|
||||
self.stg_chllng_kind: List[int] = decode_list_int(self.raw_dict.get('stg_chllng_kind'))
|
||||
self.stg_chllng_result: List[int] = decode_list_int(self.raw_dict.get('stg_chllng_result'))
|
||||
self.stg_clr_kind: List[int] = decode_list_int(self.raw_dict.get('stg_clr_kind'))
|
||||
self.stg_vcld_pts: List[int] = decode_list_int(self.raw_dict.get('stg_vcld_pts'))
|
||||
self.stg_cool_cnt: List[int] = decode_list_int(self.raw_dict.get('stg_cool_cnt'))
|
||||
self.stg_cool_pct: List[int] = decode_list_int(self.raw_dict.get('stg_cool_pct'))
|
||||
self.stg_fine_cnt: List[int] = decode_list_int(self.raw_dict.get('stg_fine_cnt'))
|
||||
self.stg_fine_pct: List[int] = decode_list_int(self.raw_dict.get('stg_fine_pct'))
|
||||
self.stg_safe_cnt: List[int] = decode_list_int(self.raw_dict.get('stg_safe_cnt'))
|
||||
self.stg_safe_pct: List[int] = decode_list_int(self.raw_dict.get('stg_safe_pct'))
|
||||
self.stg_sad_cnt: List[int] = decode_list_int(self.raw_dict.get('stg_sad_cnt'))
|
||||
self.stg_sad_pct: List[int] = decode_list_int(self.raw_dict.get('stg_sad_pct'))
|
||||
self.stg_wt_wg_cnt: List[int] = decode_list_int(self.raw_dict.get('stg_wt_wg_cnt'))
|
||||
self.stg_wt_wg_pct: List[int] = decode_list_int(self.raw_dict.get('stg_wt_wg_pct'))
|
||||
self.stg_max_cmb: List[int] = decode_list_int(self.raw_dict.get('stg_max_cmb'))
|
||||
self.stg_chance_tm: List[int] = decode_list_int(self.raw_dict.get('stg_chance_tm'))
|
||||
self.stg_sm_hl: List[int] = decode_list_int(self.raw_dict.get('stg_sm_hl'))
|
||||
self.stg_atn_pnt: List[int] = decode_list_int(self.raw_dict.get('stg_atn_pnt'))
|
||||
self.stg_skin_id: List[int] = decode_list_int(self.raw_dict.get('stg_skin_id'))
|
||||
self.stg_btn_se: List[int] = decode_list_int(self.raw_dict.get('stg_btn_se'))
|
||||
self.stg_btn_se_vol: List[int] = decode_list_int(self.raw_dict.get('stg_btn_se_vol'))
|
||||
self.stg_sld_se: List[int] = decode_list_int(self.raw_dict.get('stg_sld_se'))
|
||||
self.stg_chn_sld_se: List[int] = decode_list_int(self.raw_dict.get('stg_chn_sld_se'))
|
||||
self.stg_sldr_tch_se: List[int] = decode_list_int(self.raw_dict.get('stg_sldr_tch_se'))
|
||||
self.stg_mdl_id: List[int] = decode_list_int(self.raw_dict.get('stg_mdl_id'))
|
||||
self.stg_sel_mdl_id: List[int] = decode_list_int(self.raw_dict.get('stg_sel_mdl_id'))
|
||||
self.stg_rvl_pd_id: List[int] = decode_list_int(self.raw_dict.get('stg_rvl_pd_id'))
|
||||
self.stg_rvl_wl: List[int] = decode_list_int(self.raw_dict.get('stg_rvl_wl'))
|
||||
self.stg_cpt_rslt: List[int] = decode_list_int(self.raw_dict.get('stg_cpt_rslt'))
|
||||
self.stg_sld_scr: List[int] = decode_list_int(self.raw_dict.get('stg_sld_scr'))
|
||||
self.stg_is_sr_gm: List[int] = decode_list_int(self.raw_dict.get('stg_is_sr_gm'))
|
||||
self.stg_pv_brnch_rslt: List[int] = decode_list_int(self.raw_dict.get('stg_pv_brnch_rslt'))
|
||||
self.stg_vcl_chg: List[int] = decode_list_int(self.raw_dict.get('stg_vcl_chg'))
|
||||
self.stg_c_itm_id: List[int] = decode_list_int(self.raw_dict.get('stg_c_itm_id'))
|
||||
self.stg_ms_itm_flg: List[int] = decode_list_int(self.raw_dict.get('stg_ms_itm_flg'))
|
||||
self.stg_rgo: List[int] = decode_list_int(self.raw_dict.get('stg_rgo'))
|
||||
self.stg_ss_num: List[int] = decode_list_int(self.raw_dict.get('stg_ss_num'))
|
||||
self.stg_is_cs_scs: List[int] = decode_list_int(self.raw_dict.get('stg_is_cs_scs'))
|
||||
self.stg_is_nppg_use: List[int] = decode_list_int(self.raw_dict.get('stg_is_nppg_use'))
|
||||
self.stg_p_std_lo_id: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_lo_id'))
|
||||
self.stg_p_std_is_to: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_is_to'))
|
||||
self.stg_p_std_is_ccu: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_is_ccu'))
|
||||
self.stg_p_std_is_tiu: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_is_tiu'))
|
||||
self.stg_p_std_is_iu: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_is_iu'))
|
||||
self.stg_p_std_is_npu: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_is_npu'))
|
||||
self.stg_p_std_is_du: List[int] = decode_list_int(self.raw_dict.get('stg_p_std_is_du'))
|
||||
self.gu_cmd: List[int] = decode_list_int(self.raw_dict.get('gu_cmd'))
|
||||
self.mdl_eqp_cmn_ary: List[int] = decode_list_int(self.raw_dict.get('mdl_eqp_cmn_ary'))
|
||||
self.c_itm_eqp_cmn_ary: List[int] = decode_list_int(self.raw_dict.get('c_itm_eqp_cmn_ary'))
|
||||
self.ms_itm_flg_cmn_ary: List[int] = decode_list_int(self.raw_dict.get('ms_itm_flg_cmn_ary'))
|
||||
self.mdl_eqp_pv_ary: List[int] = decode_list_int(self.raw_dict.get('mdl_eqp_pv_ary'))
|
||||
self.c_itm_eqp_pv_ary: List[int] = decode_list_int(self.raw_dict.get('c_itm_eqp_pv_ary'))
|
||||
self.ms_itm_flg_pv_ary: List[int] = decode_list_int(self.raw_dict.get('ms_itm_flg_pv_ary'))
|
||||
self.stg_mdl_s_sts: List[int] = decode_list_int(self.raw_dict.get('stg_mdl_s_sts'))
|
||||
self.cr_sp: List[int] = decode_list_int(parse.unquote(self.raw_dict.get('cr_sp')))
|
||||
|
||||
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"
|
140
titles/diva/handlers/user.py
Normal file
140
titles/diva/handlers/user.py
Normal file
@ -0,0 +1,140 @@
|
||||
from typing import Union
|
||||
from titles.diva.handlers.base import (
|
||||
BaseRequest,
|
||||
BaseResponse,
|
||||
DivaRequestParseException,
|
||||
)
|
||||
from datetime import datetime
|
||||
from urllib import parse
|
||||
from ..const import DivaConstants
|
||||
|
||||
class PreStartRequest(BaseRequest):
|
||||
def __init__(self, raw: str) -> None:
|
||||
super().__init__(raw)
|
||||
self.pmm: str = self.raw_dict.get('pmm')
|
||||
self.idm: str = self.raw_dict.get('idm')
|
||||
self.mmgameid: str = self.raw_dict.get('mmgameid')
|
||||
self.mmuid: str = self.raw_dict.get('mmuid')
|
||||
self.a_code: str = self.raw_dict.get('a_code')
|
||||
self.aime_id: str = self.raw_dict.get('aime_id')
|
||||
self.aime_a_code: str = self.raw_dict.get('aime_a_code')
|
||||
self.key_obj_type = int(self.raw_dict.get('key_obj_type'))
|
||||
self.exec_vu = int(self.raw_dict.get('exec_vu'))
|
||||
|
||||
class PreStartResponse(BaseResponse):
|
||||
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
|
||||
self.nblss_ltt_stts = -1
|
||||
self.nblss_ltt_tckt = -1
|
||||
self.nblss_ltt_is_opn = -1
|
||||
self.player_name: str = ""
|
||||
self.sort_kind: str = ""
|
||||
self.lv_efct_id: str = ""
|
||||
self.lv_plt_id: str = ""
|
||||
self.lv_str: str = ""
|
||||
self.lv_num: str = ""
|
||||
self.lv_pnt: str = ""
|
||||
self.vcld_pts: str = ""
|
||||
self.skn_eqp: str = ""
|
||||
self.btn_se_eqp: str = ""
|
||||
self.sld_se_eqp: str = ""
|
||||
self.chn_sld_se_eqp: str = ""
|
||||
self.sldr_tch_se_eqp: str = ""
|
||||
self.passwd_stat: str = ""
|
||||
self.mdl_eqp_tm: str = ""
|
||||
# Ideally this would be a real array that would get converted later
|
||||
# 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)
|
||||
self.pd_id = int(self.raw_dict.get('pd_id'))
|
||||
self.accept_idx = int(self.raw_dict.get('accept_idx'))
|
||||
|
||||
class StartResponse(BaseResponse):
|
||||
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
|
||||
self.hp_vol: int = 0
|
||||
self.btn_se_vol: int = 1
|
||||
self.btn_se_vol2: int = 1
|
||||
self.sldr_se_vol2: int = 1
|
||||
self.sort_kind: int = 1
|
||||
self.player_name: str = pv_name
|
||||
self.lv_num: int = 1
|
||||
self.lv_pnt: int = 0
|
||||
self.lv_efct_id: int = 1
|
||||
self.lv_plt_id: int = 1
|
||||
self.mdl_have: str = "F" * 250
|
||||
self.cstmz_itm_have: str = "F" * 250
|
||||
self.use_pv_mdl_eqp: int = 0
|
||||
self.use_mdl_pri: int = 0
|
||||
self.use_pv_skn_eqp: int = 1
|
||||
self.use_pv_btn_se_eqp: int = 1
|
||||
self.use_pv_sld_se_eqp: int = 1
|
||||
self.use_pv_chn_sld_se_eqp: int = 1
|
||||
self.use_pv_sldr_tch_se_eqp: int = 1
|
||||
self.vcld_pts: int = 0
|
||||
self.nxt_pv_id: int = 1
|
||||
self.nxt_dffclty: int = 1
|
||||
self.nxt_edtn: int = 0
|
||||
self.dsp_clr_brdr: int = 0
|
||||
self.dsp_intrm_rnk: int = 0
|
||||
self.dsp_clr_sts: int = 0
|
||||
self.rgo_sts: int = 0
|
||||
self.cv_cid: str = "-1,-1,-1,-1"
|
||||
self.cv_sc: str = "-1,-1,-1,-1"
|
||||
#self.cv_bv: str = "-1,-1,-1,-1"
|
||||
self.cv_bv: str = "-1,-1,-1,-1"
|
||||
self.cv_bf: str = "-1,-1,-1,-1"
|
||||
self.cnp_cid=-1
|
||||
self.cnp_val=-1
|
||||
self.cnp_rr=-1
|
||||
self.my_qst_id: str = ",".join(["-1"] * 25)
|
||||
self.my_qst_sts: str = ",".join("0" * 5) + "," + ",".join(["-1"] * 20)
|
||||
self.my_qst_prgrs: str = ",".join("0" * 5) + "," + ",".join(["-1"] * 20)
|
||||
self.my_qst_et: str = ",".join([parse.quote(datetime.now().strftime(DivaConstants.LUT_TIME_FMT))] * 5) + "," + ",".join(["xxx"] * 20)
|
||||
self.clr_sts: str = ",".join("0" * 5) + "," + ",".join(["-1"] * 20)
|
||||
self.mdl_eqp_tm: str = parse.quote(datetime.now().strftime(DivaConstants.LUT_TIME_FMT))
|
||||
self.mdl_eqp_ary = ",".join(["-999"] * 3)
|
||||
self.c_itm_eqp_ary = ",".join(["-999"] * 12)
|
||||
self.ms_itm_flg_ary = ",".join(["1"] * 12)
|
||||
|
||||
class RegisterRequest(BaseRequest):
|
||||
def __init__(self, raw: str) -> None:
|
||||
super().__init__(raw)
|
||||
self.pmm: str = self.raw_dict.get('pmm')
|
||||
self.idm: str = self.raw_dict.get('idm')
|
||||
self.mmgameid: str = self.raw_dict.get('mmgameid')
|
||||
self.mmuid: str = self.raw_dict.get('mmuid')
|
||||
self.a_code: str = self.raw_dict.get('a_code')
|
||||
self.aime_a_code: str = self.raw_dict.get('aime_a_code')
|
||||
self.player_name: str = self.raw_dict.get('player_name')
|
||||
self.passwd: str = self.raw_dict.get('passwd')
|
||||
self.aime_id = int(self.raw_dict.get('aime_id'))
|
||||
self.key_obj_type = int(self.raw_dict.get('key_obj_type'))
|
||||
|
||||
class RegisterResponse(BaseResponse):
|
||||
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: Union[str, bytes]) -> None:
|
||||
self.my_qst_id: str = self.raw_dict.get('my_qst_id')
|
||||
self.my_qst_sts: str = self.raw_dict.get('my_qst_sts')
|
||||
|
||||
super().__init__(raw)
|
||||
try:
|
||||
self.pd_id = int(self.raw_dict.get('pd_id'))
|
||||
|
||||
except AttributeError as e:
|
||||
raise DivaRequestParseException(f"EndRequest: {e}")
|
||||
|
@ -4,11 +4,11 @@ import logging, coloredlogs
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
import zlib
|
||||
import json
|
||||
import urllib.parse
|
||||
import base64
|
||||
from os import path
|
||||
from typing import Tuple, Dict, List
|
||||
|
||||
from titles.diva.handlers.base import *
|
||||
from core.config import CoreConfig
|
||||
from core.title import BaseServlet
|
||||
from core.utils import Utils
|
||||
@ -59,9 +59,9 @@ class DivaServlet(BaseServlet):
|
||||
|
||||
def get_allnet_info(self, game_code: str, game_ver: int, keychip: str) -> Tuple[str, str]:
|
||||
if not self.core_cfg.server.is_using_proxy and Utils.get_title_port(self.core_cfg) != 80:
|
||||
return (f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/DivaServlet/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/DivaServlet/", "")
|
||||
|
||||
return (f"http://{self.core_cfg.title.hostname}/DivaServlet/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.title.hostname}/DivaServlet/", "")
|
||||
|
||||
@classmethod
|
||||
def is_game_enabled(
|
||||
@ -82,86 +82,52 @@ class DivaServlet(BaseServlet):
|
||||
req_raw = request.content.getvalue()
|
||||
url_header = request.getAllHeaders()
|
||||
|
||||
# Ping Dispatch
|
||||
if "THIS_STRING_SEPARATES" in str(url_header):
|
||||
binary_request = req_raw.splitlines()
|
||||
binary_cmd_decoded = binary_request[3].decode("utf-8")
|
||||
binary_array = binary_cmd_decoded.split("&")
|
||||
url_data = binary_cmd_decoded # for logging
|
||||
req_cls = BaseBinaryRequest(binary_cmd_decoded)
|
||||
|
||||
bin_req_data = {}
|
||||
else:
|
||||
json_string = json.dumps(
|
||||
req_raw.decode("utf-8")
|
||||
) # Take the response and decode as UTF-8 and dump
|
||||
b64string = json_string.replace(
|
||||
r"\n", "\n"
|
||||
) # Remove all \n and separate them as new lines
|
||||
gz_string = base64.b64decode(b64string) # Decompressing the base64 string
|
||||
|
||||
for kvp in binary_array:
|
||||
split_bin = kvp.split("=")
|
||||
bin_req_data[split_bin[0]] = split_bin[1]
|
||||
try:
|
||||
url_data = zlib.decompress(gz_string) # Decompressing the gzip
|
||||
except zlib.error as e:
|
||||
self.logger.error(f"Failed to defalte! {e} -> {gz_string}")
|
||||
return b"stat=0"
|
||||
|
||||
self.logger.info(f"Binary {bin_req_data['cmd']} Request")
|
||||
self.logger.debug(bin_req_data)
|
||||
try:
|
||||
req_cls = BaseRequest(url_data)
|
||||
except DivaRequestParseException as e:
|
||||
self.logger.error(e)
|
||||
return b"stat=0"
|
||||
|
||||
handler = getattr(self.base, f"handle_{bin_req_data['cmd']}_request")
|
||||
resp = handler(bin_req_data)
|
||||
|
||||
self.logger.debug(
|
||||
f"Response cmd={bin_req_data['cmd']}&req_id={bin_req_data['req_id']}&stat=ok{resp}"
|
||||
)
|
||||
return f"cmd={bin_req_data['cmd']}&req_id={bin_req_data['req_id']}&stat=ok{resp}".encode(
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
# Main Dispatch
|
||||
json_string = json.dumps(
|
||||
req_raw.decode("utf-8")
|
||||
) # Take the response and decode as UTF-8 and dump
|
||||
b64string = json_string.replace(
|
||||
r"\n", "\n"
|
||||
) # Remove all \n and separate them as new lines
|
||||
gz_string = base64.b64decode(b64string) # Decompressing the base64 string
|
||||
|
||||
try:
|
||||
url_data = zlib.decompress(gz_string).decode(
|
||||
"utf-8"
|
||||
) # Decompressing the gzip
|
||||
except zlib.error as e:
|
||||
self.logger.error(f"Failed to defalte! {e} -> {gz_string}")
|
||||
return "stat=0"
|
||||
|
||||
req_kvp = urllib.parse.unquote(url_data)
|
||||
req_data = {}
|
||||
|
||||
# We then need to split each parts with & so we can reuse them to fill out the requests
|
||||
splitted_request = str.split(req_kvp, "&")
|
||||
for kvp in splitted_request:
|
||||
split = kvp.split("=")
|
||||
req_data[split[0]] = split[1]
|
||||
|
||||
self.logger.info(f"{req_data['cmd']} Request")
|
||||
self.logger.debug(req_data)
|
||||
|
||||
func_to_find = f"handle_{req_data['cmd']}_request"
|
||||
|
||||
# Load the requests
|
||||
try:
|
||||
handler = getattr(self.base, func_to_find)
|
||||
resp = handler(req_data)
|
||||
|
||||
except AttributeError as e:
|
||||
self.logger.warning(f"Unhandled {req_data['cmd']} request {e}")
|
||||
return f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok".encode(
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error handling method {func_to_find} {e}")
|
||||
return f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok".encode(
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
request.responseHeaders.addRawHeader(b"content-type", b"text/plain")
|
||||
self.logger.debug(
|
||||
f"Response cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok{resp}"
|
||||
self.logger.debug(f"Request: {url_data}\nHeaders: {url_header}")
|
||||
self.logger.info(
|
||||
f"{req_cls.cmd} request from {req_cls.kc_serial}/{req_cls.b_serial} at {Utils.get_ip_addr(request)}"
|
||||
)
|
||||
|
||||
return (
|
||||
f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok{resp}".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
handler_str = f"handle_{req_cls.cmd}_request"
|
||||
|
||||
if not hasattr(self.base, handler_str):
|
||||
self.logger.warn(f"Unhandled cmd {req_cls.cmd}")
|
||||
return BaseResponse(req_cls.cmd, req_cls.req_id).make().encode()
|
||||
|
||||
handler = getattr(self.base, handler_str)
|
||||
|
||||
response = handler(req_cls.raw)
|
||||
if response is None or response == "":
|
||||
response = BaseResponse(req_cls.cmd, req_cls.req_id).make()
|
||||
|
||||
if not response.startswith("cmd="):
|
||||
response = f"cmd={req_cls.cmd}&req_id={req_cls.req_id}&stat=ok" + response
|
||||
|
||||
self.logger.debug(f"Response: {response}")
|
||||
return response.encode(errors="ignore")
|
||||
|
@ -228,8 +228,8 @@ class Mai2Base:
|
||||
user_id,
|
||||
charge["chargeId"],
|
||||
charge["stock"],
|
||||
charge["purchaseDate"], # Ideally these should be datetimes, but db was
|
||||
charge["validDate"] # set up with them being str, so str it is for now
|
||||
datetime.strptime(charge["purchaseDate"], Mai2Constants.DATE_TIME_FORMAT),
|
||||
datetime.strptime(charge["validDate"], Mai2Constants.DATE_TIME_FORMAT),
|
||||
)
|
||||
|
||||
return {"returnCode": 1, "apiName": "UpsertUserChargelogApi"}
|
||||
@ -303,8 +303,12 @@ class Mai2Base:
|
||||
user_id,
|
||||
charge["chargeId"],
|
||||
charge["stock"],
|
||||
charge["purchaseDate"],
|
||||
charge["validDate"]
|
||||
datetime.strptime(
|
||||
charge["purchaseDate"], Mai2Constants.DATE_TIME_FORMAT
|
||||
),
|
||||
datetime.strptime(
|
||||
charge["validDate"], Mai2Constants.DATE_TIME_FORMAT
|
||||
),
|
||||
)
|
||||
|
||||
if "userCharacterList" in upsert and len(upsert["userCharacterList"]) > 0:
|
||||
@ -454,6 +458,12 @@ class Mai2Base:
|
||||
tmp = charge._asdict()
|
||||
tmp.pop("id")
|
||||
tmp.pop("user")
|
||||
tmp["purchaseDate"] = datetime.strftime(
|
||||
tmp["purchaseDate"], Mai2Constants.DATE_TIME_FORMAT
|
||||
)
|
||||
tmp["validDate"] = datetime.strftime(
|
||||
tmp["validDate"], Mai2Constants.DATE_TIME_FORMAT
|
||||
)
|
||||
|
||||
user_charge_list.append(tmp)
|
||||
|
||||
|
@ -501,8 +501,8 @@ class Mai2ItemData(BaseData):
|
||||
user_id: int,
|
||||
charge_id: int,
|
||||
stock: int,
|
||||
purchase_date: str,
|
||||
valid_date: str,
|
||||
purchase_date: datetime,
|
||||
valid_date: datetime,
|
||||
) -> Optional[Row]:
|
||||
sql = insert(charge).values(
|
||||
user=user_id,
|
||||
|
@ -639,9 +639,8 @@ class OngekiItemData(BaseData):
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_tech_event(self, aime_id: int, version: int, tech_event_data: Dict) -> Optional[int]:
|
||||
def put_tech_event(self, aime_id: int, tech_event_data: Dict) -> Optional[int]:
|
||||
tech_event_data["user"] = aime_id
|
||||
tech_event_data["version"] = version
|
||||
|
||||
sql = insert(tech_event).values(**tech_event_data)
|
||||
conflict = sql.on_duplicate_key_update(**tech_event_data)
|
||||
@ -652,7 +651,7 @@ class OngekiItemData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def put_tech_event_ranking(self, aime_id: int, version: int, tech_event_data: Dict) -> Optional[int]:
|
||||
def put_tech_event_ranking(self, version: int, aime_id: int, tech_event_data: Dict) -> Optional[int]:
|
||||
tech_event_data["user"] = aime_id
|
||||
tech_event_data["version"] = version
|
||||
tech_event_data.pop("isRankingRewarded")
|
||||
|
@ -89,10 +89,10 @@ class WaccaServlet:
|
||||
if not self.core_cfg.server.is_using_proxy and Utils.get_title_port(self.core_cfg) != 80:
|
||||
return (
|
||||
f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/WaccaServlet",
|
||||
self.core_cfg.title.hostname,
|
||||
"",
|
||||
)
|
||||
|
||||
return (f"http://{self.core_cfg.title.hostname}/WaccaServlet", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.title.hostname}/WaccaServlet", "")
|
||||
|
||||
def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
def end(resp: Dict) -> bytes:
|
||||
|
Reference in New Issue
Block a user