forked from Hay1tsme/artemis
Merge branch 'develop' into diva_handler_classes
This commit is contained in:
commit
a36170f2c3
@ -95,14 +95,21 @@ class AllnetServlet:
|
|||||||
|
|
||||||
self.logger.debug(f"Allnet request: {vars(req)}")
|
self.logger.debug(f"Allnet request: {vars(req)}")
|
||||||
if req.game_id not in self.uri_registry:
|
if req.game_id not in self.uri_registry:
|
||||||
msg = f"Unrecognised game {req.game_id} attempted allnet auth from {request_ip}."
|
if not self.config.server.is_develop:
|
||||||
self.data.base.log_event(
|
msg = f"Unrecognised game {req.game_id} attempted allnet auth from {request_ip}."
|
||||||
"allnet", "ALLNET_AUTH_UNKNOWN_GAME", logging.WARN, msg
|
self.data.base.log_event(
|
||||||
)
|
"allnet", "ALLNET_AUTH_UNKNOWN_GAME", logging.WARN, msg
|
||||||
self.logger.warn(msg)
|
)
|
||||||
|
self.logger.warn(msg)
|
||||||
|
|
||||||
resp.stat = 0
|
resp.stat = 0
|
||||||
return self.dict_to_http_form_string([vars(resp)])
|
return self.dict_to_http_form_string([vars(resp)])
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.logger.info(f"Allowed unknown game {req.game_id} v{req.ver} to authenticate from {request_ip} due to 'is_develop' being enabled. S/N: {req.serial}")
|
||||||
|
resp.uri = f"http://{self.config.title.hostname}:{self.config.title.port}/{req.game_id}/{req.ver.replace('.', '')}/"
|
||||||
|
resp.host = f"{self.config.title.hostname}:{self.config.title.port}"
|
||||||
|
return self.dict_to_http_form_string([vars(resp)])
|
||||||
|
|
||||||
resp.uri, resp.host = self.uri_registry[req.game_id]
|
resp.uri, resp.host = self.uri_registry[req.game_id]
|
||||||
|
|
||||||
@ -181,7 +188,9 @@ class AllnetServlet:
|
|||||||
self.logger.error(e)
|
self.logger.error(e)
|
||||||
return b""
|
return b""
|
||||||
|
|
||||||
|
self.logger.info(f"DownloadOrder from {request_ip} -> {req.game_id} v{req.ver} serial {req.serial}")
|
||||||
resp = AllnetDownloadOrderResponse()
|
resp = AllnetDownloadOrderResponse()
|
||||||
|
|
||||||
if not self.config.allnet.allow_online_updates:
|
if not self.config.allnet.allow_online_updates:
|
||||||
return self.dict_to_http_form_string([vars(resp)])
|
return self.dict_to_http_form_string([vars(resp)])
|
||||||
|
|
||||||
@ -190,7 +199,7 @@ class AllnetServlet:
|
|||||||
|
|
||||||
def handle_billing_request(self, request: Request, _: Dict):
|
def handle_billing_request(self, request: Request, _: Dict):
|
||||||
req_dict = self.billing_req_to_dict(request.content.getvalue())
|
req_dict = self.billing_req_to_dict(request.content.getvalue())
|
||||||
request_ip = request.getClientAddress()
|
request_ip = Utils.get_ip_addr(request)
|
||||||
if req_dict is None:
|
if req_dict is None:
|
||||||
self.logger.error(f"Failed to parse request {request.content.getvalue()}")
|
self.logger.error(f"Failed to parse request {request.content.getvalue()}")
|
||||||
return b""
|
return b""
|
||||||
@ -223,7 +232,7 @@ class AllnetServlet:
|
|||||||
return self.dict_to_http_form_string([vars(resp)])
|
return self.dict_to_http_form_string([vars(resp)])
|
||||||
|
|
||||||
msg = (
|
msg = (
|
||||||
f"Billing checkin from {request.getClientIP()}: game {kc_game} keychip {kc_serial} playcount "
|
f"Billing checkin from {request_ip}: game {kc_game} keychip {kc_serial} playcount "
|
||||||
f"{kc_playcount} billing_type {kc_billigtype} nearfull {kc_nearfull} playlimit {kc_playlimit}"
|
f"{kc_playcount} billing_type {kc_billigtype} nearfull {kc_nearfull} playlimit {kc_playlimit}"
|
||||||
)
|
)
|
||||||
self.logger.info(msg)
|
self.logger.info(msg)
|
||||||
|
@ -145,25 +145,49 @@ class Data:
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not os.path.exists(
|
if action == "upgrade":
|
||||||
f"core/data/schema/versions/{game.upper()}_{version}_{action}.sql"
|
for x in range(old_ver, version):
|
||||||
):
|
if not os.path.exists(
|
||||||
self.logger.error(
|
f"core/data/schema/versions/{game.upper()}_{x + 1}_{action}.sql"
|
||||||
f"Could not find {action} script {game.upper()}_{version}_{action}.sql in core/data/schema/versions folder"
|
):
|
||||||
)
|
self.logger.error(
|
||||||
return
|
f"Could not find {action} script {game.upper()}_{x + 1}_{action}.sql in core/data/schema/versions folder"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
with open(
|
with open(
|
||||||
f"core/data/schema/versions/{game.upper()}_{version}_{action}.sql",
|
f"core/data/schema/versions/{game.upper()}_{x + 1}_{action}.sql",
|
||||||
"r",
|
"r",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
) as f:
|
) as f:
|
||||||
sql = f.read()
|
sql = f.read()
|
||||||
|
|
||||||
result = self.base.execute(sql)
|
result = self.base.execute(sql)
|
||||||
if result is None:
|
if result is None:
|
||||||
self.logger.error("Error execuing sql script!")
|
self.logger.error("Error execuing sql script!")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
else:
|
||||||
|
for x in range(old_ver, version, -1):
|
||||||
|
if not os.path.exists(
|
||||||
|
f"core/data/schema/versions/{game.upper()}_{x - 1}_{action}.sql"
|
||||||
|
):
|
||||||
|
self.logger.error(
|
||||||
|
f"Could not find {action} script {game.upper()}_{x - 1}_{action}.sql in core/data/schema/versions folder"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(
|
||||||
|
f"core/data/schema/versions/{game.upper()}_{x - 1}_{action}.sql",
|
||||||
|
"r",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
sql = f.read()
|
||||||
|
|
||||||
|
result = self.base.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
self.logger.error("Error execuing sql script!")
|
||||||
|
return None
|
||||||
|
|
||||||
result = self.base.set_schema_ver(version, game)
|
result = self.base.set_schema_ver(version, game)
|
||||||
if result is None:
|
if result is None:
|
||||||
@ -237,3 +261,19 @@ class Data:
|
|||||||
if not cards:
|
if not cards:
|
||||||
self.logger.info(f"Delete hanging user {user['id']}")
|
self.logger.info(f"Delete hanging user {user['id']}")
|
||||||
self.user.delete_user(user["id"])
|
self.user.delete_user(user["id"])
|
||||||
|
|
||||||
|
def autoupgrade(self) -> None:
|
||||||
|
all_games = self.base.get_all_schema_vers()
|
||||||
|
if all_games is None:
|
||||||
|
self.logger.warn("Failed to get schema versions")
|
||||||
|
|
||||||
|
for x in all_games:
|
||||||
|
game = x["game"].upper()
|
||||||
|
update_ver = 1
|
||||||
|
for y in range(2, 100):
|
||||||
|
if os.path.exists(f"core/data/schema/versions/{game}_{y}_upgrade.sql"):
|
||||||
|
update_ver = y
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.migrate_database(game, update_ver, "upgrade")
|
@ -2,6 +2,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
from random import randrange
|
from random import randrange
|
||||||
from typing import Any, Optional, Dict, List
|
from typing import Any, Optional, Dict, List
|
||||||
|
from sqlalchemy.engine import Row
|
||||||
from sqlalchemy.engine.cursor import CursorResult
|
from sqlalchemy.engine.cursor import CursorResult
|
||||||
from sqlalchemy.engine.base import Connection
|
from sqlalchemy.engine.base import Connection
|
||||||
from sqlalchemy.sql import text, func, select
|
from sqlalchemy.sql import text, func, select
|
||||||
@ -80,6 +81,14 @@ class BaseData:
|
|||||||
Generate a random 5-7 digit id
|
Generate a random 5-7 digit id
|
||||||
"""
|
"""
|
||||||
return randrange(10000, 9999999)
|
return randrange(10000, 9999999)
|
||||||
|
|
||||||
|
def get_all_schema_vers(self) -> Optional[List[Row]]:
|
||||||
|
sql = select(schema_ver)
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchall()
|
||||||
|
|
||||||
def get_schema_ver(self, game: str) -> Optional[int]:
|
def get_schema_ver(self, game: str) -> Optional[int]:
|
||||||
sql = select(schema_ver).where(schema_ver.c.game == game)
|
sql = select(schema_ver).where(schema_ver.c.game == game)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
SET FOREIGN_KEY_CHECKS=0;
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
ALTER TABLE diva_score DROP COLUMN edition;
|
|
||||||
ALTER TABLE diva_playlog DROP COLUMN edition;
|
|
||||||
|
|
||||||
ALTER TABLE diva_score DROP FOREIGN KEY diva_score_ibfk_1;
|
ALTER TABLE diva_score DROP FOREIGN KEY diva_score_ibfk_1;
|
||||||
ALTER TABLE diva_score DROP CONSTRAINT diva_score_uk;
|
ALTER TABLE diva_score DROP CONSTRAINT diva_score_uk;
|
||||||
ALTER TABLE diva_score ADD CONSTRAINT diva_score_uk UNIQUE (user, pv_id, difficulty);
|
ALTER TABLE diva_score ADD CONSTRAINT diva_score_uk UNIQUE (user, pv_id, difficulty);
|
||||||
ALTER TABLE diva_score ADD CONSTRAINT diva_score_ibfk_1 FOREIGN KEY (user) REFERENCES aime_user(id) ON DELETE CASCADE;
|
ALTER TABLE diva_score ADD CONSTRAINT diva_score_ibfk_1 FOREIGN KEY (user) REFERENCES aime_user(id) ON DELETE CASCADE;
|
||||||
|
|
||||||
|
ALTER TABLE diva_score DROP COLUMN edition;
|
||||||
|
ALTER TABLE diva_playlog DROP COLUMN edition;
|
||||||
SET FOREIGN_KEY_CHECKS=1;
|
SET FOREIGN_KEY_CHECKS=1;
|
21
core/data/schema/versions/SDEZ_2_rollback.sql
Normal file
21
core/data/schema/versions/SDEZ_2_rollback.sql
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
ALTER TABLE mai2_item_card
|
||||||
|
CHANGE COLUMN cardId card_id INT NOT NULL AFTER user,
|
||||||
|
CHANGE COLUMN cardTypeId card_kind INT NOT NULL,
|
||||||
|
CHANGE COLUMN charaId chara_id INT NOT NULL,
|
||||||
|
CHANGE COLUMN mapId map_id INT NOT NULL,
|
||||||
|
CHANGE COLUMN startDate start_date TIMESTAMP NULL DEFAULT '2018-01-01 00:00:00',
|
||||||
|
CHANGE COLUMN endDate end_date TIMESTAMP NULL DEFAULT '2038-01-01 00:00:00';
|
||||||
|
|
||||||
|
ALTER TABLE mai2_item_item
|
||||||
|
CHANGE COLUMN itemId item_id INT NOT NULL AFTER user,
|
||||||
|
CHANGE COLUMN itemKind item_kind INT NOT NULL,
|
||||||
|
CHANGE COLUMN isValid is_valid TINYINT(1) NOT NULL DEFAULT '1';
|
||||||
|
|
||||||
|
ALTER TABLE mai2_item_character
|
||||||
|
CHANGE COLUMN characterId character_id INT NOT NULL,
|
||||||
|
CHANGE COLUMN useCount use_count INT NOT NULL DEFAULT '0';
|
||||||
|
|
||||||
|
ALTER TABLE mai2_item_charge
|
||||||
|
CHANGE COLUMN chargeId charge_id INT NOT NULL,
|
||||||
|
CHANGE COLUMN purchaseDate purchase_date TIMESTAMP NOT NULL,
|
||||||
|
CHANGE COLUMN validDate valid_date TIMESTAMP NOT NULL;
|
@ -3,8 +3,8 @@ CHANGE COLUMN card_id cardId INT NOT NULL AFTER user,
|
|||||||
CHANGE COLUMN card_kind cardTypeId INT NOT NULL,
|
CHANGE COLUMN card_kind cardTypeId INT NOT NULL,
|
||||||
CHANGE COLUMN chara_id charaId INT NOT NULL,
|
CHANGE COLUMN chara_id charaId INT NOT NULL,
|
||||||
CHANGE COLUMN map_id mapId INT NOT NULL,
|
CHANGE COLUMN map_id mapId INT NOT NULL,
|
||||||
CHANGE COLUMN startDate startDate TIMESTAMP NULL DEFAULT '2018-01-01 00:00:00',
|
CHANGE COLUMN start_date startDate TIMESTAMP NULL DEFAULT '2018-01-01 00:00:00',
|
||||||
CHANGE COLUMN endDate endDate TIMESTAMP NULL DEFAULT '2038-01-01 00:00:00';
|
CHANGE COLUMN end_date endDate TIMESTAMP NULL DEFAULT '2038-01-01 00:00:00';
|
||||||
|
|
||||||
ALTER TABLE mai2_item_item
|
ALTER TABLE mai2_item_item
|
||||||
CHANGE COLUMN item_id itemId INT NOT NULL AFTER user,
|
CHANGE COLUMN item_id itemId INT NOT NULL AFTER user,
|
||||||
|
@ -30,7 +30,7 @@ class UserSession(object):
|
|||||||
|
|
||||||
class FrontendServlet(resource.Resource):
|
class FrontendServlet(resource.Resource):
|
||||||
def getChild(self, name: bytes, request: Request):
|
def getChild(self, name: bytes, request: Request):
|
||||||
self.logger.debug(f"{request.getClientIP()} -> {name.decode()}")
|
self.logger.debug(f"{Utils.get_ip_addr(request)} -> {name.decode()}")
|
||||||
if name == b"":
|
if name == b"":
|
||||||
return self
|
return self
|
||||||
return resource.Resource.getChild(self, name, request)
|
return resource.Resource.getChild(self, name, request)
|
||||||
@ -84,7 +84,7 @@ class FrontendServlet(resource.Resource):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def render_GET(self, request):
|
def render_GET(self, request):
|
||||||
self.logger.debug(f"{request.getClientIP()} -> {request.uri.decode()}")
|
self.logger.debug(f"{Utils.get_ip_addr(request)} -> {request.uri.decode()}")
|
||||||
template = self.environment.get_template("core/frontend/index.jinja")
|
template = self.environment.get_template("core/frontend/index.jinja")
|
||||||
return template.render(
|
return template.render(
|
||||||
server_name=self.config.server.name,
|
server_name=self.config.server.name,
|
||||||
@ -113,7 +113,7 @@ class FE_Base(resource.Resource):
|
|||||||
|
|
||||||
class FE_Gate(FE_Base):
|
class FE_Gate(FE_Base):
|
||||||
def render_GET(self, request: Request):
|
def render_GET(self, request: Request):
|
||||||
self.logger.debug(f"{request.getClientIP()} -> {request.uri.decode()}")
|
self.logger.debug(f"{Utils.get_ip_addr(request)} -> {request.uri.decode()}")
|
||||||
uri: str = request.uri.decode()
|
uri: str = request.uri.decode()
|
||||||
|
|
||||||
sesh = request.getSession()
|
sesh = request.getSession()
|
||||||
|
@ -64,6 +64,9 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
data.migrate_database(args.game, int(args.version), args.action)
|
data.migrate_database(args.game, int(args.version), args.action)
|
||||||
|
|
||||||
|
elif args.action == "autoupgrade":
|
||||||
|
data.autoupgrade()
|
||||||
|
|
||||||
elif args.action == "create-owner":
|
elif args.action == "create-owner":
|
||||||
data.create_owner(args.email)
|
data.create_owner(args.email)
|
||||||
|
|
||||||
|
@ -8,13 +8,13 @@ using the megaime database. Clean installations always create the latest databas
|
|||||||
|
|
||||||
# Table of content
|
# Table of content
|
||||||
|
|
||||||
- [Supported Games](#Supported-Games)
|
- [Supported Games](#supported-games)
|
||||||
- [Chunithm](#Chunithm)
|
- [Chunithm](#chunithm)
|
||||||
- [crossbeats REV.](#crossbeats-REV)
|
- [crossbeats REV.](#crossbeats-rev)
|
||||||
- [maimai DX](#maimai-DX)
|
- [maimai DX](#maimai-dx)
|
||||||
- [O.N.G.E.K.I.](#ONGEKI)
|
- [O.N.G.E.K.I.](#o-n-g-e-k-i)
|
||||||
- [Card Maker](#Card-Maker)
|
- [Card Maker](#card-maker)
|
||||||
- [WACCA](#WACCA)
|
- [WACCA](#wacca)
|
||||||
|
|
||||||
|
|
||||||
# Supported Games
|
# Supported Games
|
||||||
|
@ -2,5 +2,19 @@ server:
|
|||||||
enable: True
|
enable: True
|
||||||
loglevel: "info"
|
loglevel: "info"
|
||||||
|
|
||||||
|
team:
|
||||||
|
name: ARTEMiS
|
||||||
|
|
||||||
|
mods:
|
||||||
|
use_login_bonus: True
|
||||||
|
|
||||||
|
version:
|
||||||
|
11:
|
||||||
|
rom: 2.00.00
|
||||||
|
data: 2.00.00
|
||||||
|
12:
|
||||||
|
rom: 2.05.00
|
||||||
|
data: 2.05.00
|
||||||
|
|
||||||
crypto:
|
crypto:
|
||||||
encrypted_only: False
|
encrypted_only: False
|
@ -7,4 +7,4 @@ index = ChuniServlet
|
|||||||
database = ChuniData
|
database = ChuniData
|
||||||
reader = ChuniReader
|
reader = ChuniReader
|
||||||
game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW]
|
game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW]
|
||||||
current_schema_version = 1
|
current_schema_version = 3
|
||||||
|
@ -23,7 +23,98 @@ class ChuniBase:
|
|||||||
self.version = ChuniConstants.VER_CHUNITHM
|
self.version = ChuniConstants.VER_CHUNITHM
|
||||||
|
|
||||||
def handle_game_login_api_request(self, data: Dict) -> Dict:
|
def handle_game_login_api_request(self, data: Dict) -> Dict:
|
||||||
# self.data.base.log_event("chuni", "login", logging.INFO, {"version": self.version, "user": data["userId"]})
|
"""
|
||||||
|
Handles the login bonus logic, required for the game because
|
||||||
|
getUserLoginBonus gets called after getUserItem and therefore the
|
||||||
|
items needs to be inserted in the database before they get requested.
|
||||||
|
|
||||||
|
Adds a bonusCount after a user logged in after 24 hours, makes sure
|
||||||
|
loginBonus 30 gets looped, only show the login banner every 24 hours,
|
||||||
|
adds the bonus to items (itemKind 6)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ignore the login bonus if disabled in config
|
||||||
|
if not self.game_cfg.mods.use_login_bonus:
|
||||||
|
return {"returnCode": 1}
|
||||||
|
|
||||||
|
user_id = data["userId"]
|
||||||
|
login_bonus_presets = self.data.static.get_login_bonus_presets(self.version)
|
||||||
|
|
||||||
|
for preset in login_bonus_presets:
|
||||||
|
# check if a user already has some pogress and if not add the
|
||||||
|
# login bonus entry
|
||||||
|
user_login_bonus = self.data.item.get_login_bonus(
|
||||||
|
user_id, self.version, preset["id"]
|
||||||
|
)
|
||||||
|
if user_login_bonus is None:
|
||||||
|
self.data.item.put_login_bonus(user_id, self.version, preset["id"])
|
||||||
|
# yeah i'm lazy
|
||||||
|
user_login_bonus = self.data.item.get_login_bonus(
|
||||||
|
user_id, self.version, preset["id"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# skip the login bonus entirely if its already finished
|
||||||
|
if user_login_bonus["isFinished"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# make sure the last login is more than 24 hours ago
|
||||||
|
if user_login_bonus["lastUpdateDate"] < datetime.now() - timedelta(
|
||||||
|
hours=24
|
||||||
|
):
|
||||||
|
# increase the login day counter and update the last login date
|
||||||
|
bonus_count = user_login_bonus["bonusCount"] + 1
|
||||||
|
last_update_date = datetime.now()
|
||||||
|
|
||||||
|
all_login_boni = self.data.static.get_login_bonus(
|
||||||
|
self.version, preset["id"]
|
||||||
|
)
|
||||||
|
|
||||||
|
# skip the current bonus preset if no boni were found
|
||||||
|
if all_login_boni is None or len(all_login_boni) < 1:
|
||||||
|
self.logger.warn(
|
||||||
|
f"No bonus entries found for bonus preset {preset['id']}"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
max_needed_days = all_login_boni[0]["needLoginDayCount"]
|
||||||
|
|
||||||
|
# make sure to not show login boni after all days got redeemed
|
||||||
|
is_finished = False
|
||||||
|
if bonus_count > max_needed_days:
|
||||||
|
# assume that all login preset ids under 3000 needs to be
|
||||||
|
# looped, like 30 and 40 are looped, 40 does not work?
|
||||||
|
if preset["id"] < 3000:
|
||||||
|
bonus_count = 1
|
||||||
|
else:
|
||||||
|
is_finished = True
|
||||||
|
|
||||||
|
# grab the item for the corresponding day
|
||||||
|
login_item = self.data.static.get_login_bonus_by_required_days(
|
||||||
|
self.version, preset["id"], bonus_count
|
||||||
|
)
|
||||||
|
if login_item is not None:
|
||||||
|
# now add the present to the database so the
|
||||||
|
# handle_get_user_item_api_request can grab them
|
||||||
|
self.data.item.put_item(
|
||||||
|
user_id,
|
||||||
|
{
|
||||||
|
"itemId": login_item["presentId"],
|
||||||
|
"itemKind": 6,
|
||||||
|
"stock": login_item["itemNum"],
|
||||||
|
"isValid": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.data.item.put_login_bonus(
|
||||||
|
user_id,
|
||||||
|
self.version,
|
||||||
|
preset["id"],
|
||||||
|
bonusCount=bonus_count,
|
||||||
|
lastUpdateDate=last_update_date,
|
||||||
|
isWatched=False,
|
||||||
|
isFinished=is_finished,
|
||||||
|
)
|
||||||
|
|
||||||
return {"returnCode": 1}
|
return {"returnCode": 1}
|
||||||
|
|
||||||
def handle_game_logout_api_request(self, data: Dict) -> Dict:
|
def handle_game_logout_api_request(self, data: Dict) -> Dict:
|
||||||
@ -33,6 +124,9 @@ class ChuniBase:
|
|||||||
def handle_get_game_charge_api_request(self, data: Dict) -> Dict:
|
def handle_get_game_charge_api_request(self, data: Dict) -> Dict:
|
||||||
game_charge_list = self.data.static.get_enabled_charges(self.version)
|
game_charge_list = self.data.static.get_enabled_charges(self.version)
|
||||||
|
|
||||||
|
if game_charge_list is None or len(game_charge_list) == 0:
|
||||||
|
return {"length": 0, "gameChargeList": []}
|
||||||
|
|
||||||
charges = []
|
charges = []
|
||||||
for x in range(len(game_charge_list)):
|
for x in range(len(game_charge_list)):
|
||||||
charges.append(
|
charges.append(
|
||||||
@ -52,6 +146,14 @@ class ChuniBase:
|
|||||||
def handle_get_game_event_api_request(self, data: Dict) -> Dict:
|
def handle_get_game_event_api_request(self, data: Dict) -> Dict:
|
||||||
game_events = self.data.static.get_enabled_events(self.version)
|
game_events = self.data.static.get_enabled_events(self.version)
|
||||||
|
|
||||||
|
if game_events is None or len(game_events) == 0:
|
||||||
|
self.logger.warn("No enabled events, did you run the reader?")
|
||||||
|
return {
|
||||||
|
"type": data["type"],
|
||||||
|
"length": 0,
|
||||||
|
"gameEventList": [],
|
||||||
|
}
|
||||||
|
|
||||||
event_list = []
|
event_list = []
|
||||||
for evt_row in game_events:
|
for evt_row in game_events:
|
||||||
tmp = {}
|
tmp = {}
|
||||||
@ -119,7 +221,7 @@ class ChuniBase:
|
|||||||
return {
|
return {
|
||||||
"userId": data["userId"],
|
"userId": data["userId"],
|
||||||
"length": len(activity_list),
|
"length": len(activity_list),
|
||||||
"kind": data["kind"],
|
"kind": int(data["kind"]),
|
||||||
"userActivityList": activity_list,
|
"userActivityList": activity_list,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,26 +400,29 @@ class ChuniBase:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def handle_get_user_login_bonus_api_request(self, data: Dict) -> Dict:
|
def handle_get_user_login_bonus_api_request(self, data: Dict) -> Dict:
|
||||||
"""
|
user_id = data["userId"]
|
||||||
Unsure how to get this to trigger...
|
user_login_bonus = self.data.item.get_all_login_bonus(user_id, self.version)
|
||||||
"""
|
# ignore the loginBonus request if its disabled in config
|
||||||
|
if user_login_bonus is None or not self.game_cfg.mods.use_login_bonus:
|
||||||
|
return {"userId": user_id, "length": 0, "userLoginBonusList": []}
|
||||||
|
|
||||||
|
user_login_list = []
|
||||||
|
for bonus in user_login_bonus:
|
||||||
|
user_login_list.append(
|
||||||
|
{
|
||||||
|
"presetId": bonus["presetId"],
|
||||||
|
"bonusCount": bonus["bonusCount"],
|
||||||
|
"lastUpdateDate": datetime.strftime(
|
||||||
|
bonus["lastUpdateDate"], "%Y-%m-%d %H:%M:%S"
|
||||||
|
),
|
||||||
|
"isWatched": bonus["isWatched"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"userId": data["userId"],
|
"userId": user_id,
|
||||||
"length": 2,
|
"length": len(user_login_list),
|
||||||
"userLoginBonusList": [
|
"userLoginBonusList": user_login_list,
|
||||||
{
|
|
||||||
"presetId": "10",
|
|
||||||
"bonusCount": "0",
|
|
||||||
"lastUpdateDate": "1970-01-01 09:00:00",
|
|
||||||
"isWatched": "true",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"presetId": "20",
|
|
||||||
"bonusCount": "0",
|
|
||||||
"lastUpdateDate": "1970-01-01 09:00:00",
|
|
||||||
"isWatched": "true",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle_get_user_map_api_request(self, data: Dict) -> Dict:
|
def handle_get_user_map_api_request(self, data: Dict) -> Dict:
|
||||||
@ -440,13 +545,13 @@ class ChuniBase:
|
|||||||
"playerLevel": profile["playerLevel"],
|
"playerLevel": profile["playerLevel"],
|
||||||
"rating": profile["rating"],
|
"rating": profile["rating"],
|
||||||
"headphone": profile["headphone"],
|
"headphone": profile["headphone"],
|
||||||
"chargeState": "1",
|
"chargeState": 1,
|
||||||
"userNameEx": profile["userName"],
|
"userNameEx": profile["userName"],
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle_get_user_recent_rating_api_request(self, data: Dict) -> Dict:
|
def handle_get_user_recent_rating_api_request(self, data: Dict) -> Dict:
|
||||||
recet_rating_list = self.data.profile.get_profile_recent_rating(data["userId"])
|
recent_rating_list = self.data.profile.get_profile_recent_rating(data["userId"])
|
||||||
if recet_rating_list is None:
|
if recent_rating_list is None:
|
||||||
return {
|
return {
|
||||||
"userId": data["userId"],
|
"userId": data["userId"],
|
||||||
"length": 0,
|
"length": 0,
|
||||||
@ -455,8 +560,8 @@ class ChuniBase:
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"userId": data["userId"],
|
"userId": data["userId"],
|
||||||
"length": len(recet_rating_list["recentRating"]),
|
"length": len(recent_rating_list["recentRating"]),
|
||||||
"userRecentRatingList": recet_rating_list["recentRating"],
|
"userRecentRatingList": recent_rating_list["recentRating"],
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle_get_user_region_api_request(self, data: Dict) -> Dict:
|
def handle_get_user_region_api_request(self, data: Dict) -> Dict:
|
||||||
@ -468,8 +573,24 @@ class ChuniBase:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def handle_get_user_team_api_request(self, data: Dict) -> Dict:
|
def handle_get_user_team_api_request(self, data: Dict) -> Dict:
|
||||||
# TODO: Team
|
# TODO: use the database "chuni_profile_team" with a GUI
|
||||||
return {"userId": data["userId"], "teamId": 0}
|
team_name = self.game_cfg.team.team_name
|
||||||
|
if team_name == "":
|
||||||
|
return {"userId": data["userId"], "teamId": 0}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"userId": data["userId"],
|
||||||
|
"teamId": 1,
|
||||||
|
"teamRank": 1,
|
||||||
|
"teamName": team_name,
|
||||||
|
"userTeamPoint": {
|
||||||
|
"userId": data["userId"],
|
||||||
|
"teamId": 1,
|
||||||
|
"orderId": 1,
|
||||||
|
"teamPoint": 1,
|
||||||
|
"aggrDate": data["playDate"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
def handle_get_team_course_setting_api_request(self, data: Dict) -> Dict:
|
def handle_get_team_course_setting_api_request(self, data: Dict) -> Dict:
|
||||||
return {
|
return {
|
||||||
@ -569,9 +690,18 @@ class ChuniBase:
|
|||||||
for emoney in upsert["userEmoneyList"]:
|
for emoney in upsert["userEmoneyList"]:
|
||||||
self.data.profile.put_profile_emoney(user_id, emoney)
|
self.data.profile.put_profile_emoney(user_id, emoney)
|
||||||
|
|
||||||
|
if "userLoginBonusList" in upsert:
|
||||||
|
for login in upsert["userLoginBonusList"]:
|
||||||
|
self.data.item.put_login_bonus(
|
||||||
|
user_id, self.version, login["presetId"], isWatched=True
|
||||||
|
)
|
||||||
|
|
||||||
return {"returnCode": "1"}
|
return {"returnCode": "1"}
|
||||||
|
|
||||||
def handle_upsert_user_chargelog_api_request(self, data: Dict) -> Dict:
|
def handle_upsert_user_chargelog_api_request(self, data: Dict) -> Dict:
|
||||||
|
# add tickets after they got bought, this makes sure the tickets are
|
||||||
|
# still valid after an unsuccessful logout
|
||||||
|
self.data.profile.put_profile_charge(data["userId"], data["userCharge"])
|
||||||
return {"returnCode": "1"}
|
return {"returnCode": "1"}
|
||||||
|
|
||||||
def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||||
@ -592,7 +722,5 @@ class ChuniBase:
|
|||||||
def handle_get_user_net_battle_data_api_request(self, data: Dict) -> Dict:
|
def handle_get_user_net_battle_data_api_request(self, data: Dict) -> Dict:
|
||||||
return {
|
return {
|
||||||
"userId": data["userId"],
|
"userId": data["userId"],
|
||||||
"userNetBattleData": {
|
"userNetBattleData": {"recentNBSelectMusicList": []},
|
||||||
"recentNBSelectMusicList": []
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -21,6 +21,42 @@ class ChuniServerConfig:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ChuniTeamConfig:
|
||||||
|
def __init__(self, parent_config: "ChuniConfig") -> None:
|
||||||
|
self.__config = parent_config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def team_name(self) -> str:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config, "chuni", "team", "name", default=""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ChuniModsConfig:
|
||||||
|
def __init__(self, parent_config: "ChuniConfig") -> None:
|
||||||
|
self.__config = parent_config
|
||||||
|
|
||||||
|
@property
|
||||||
|
def use_login_bonus(self) -> bool:
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config, "chuni", "mods", "use_login_bonus", default=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ChuniVersionConfig:
|
||||||
|
def __init__(self, parent_config: "ChuniConfig") -> None:
|
||||||
|
self.__config = parent_config
|
||||||
|
|
||||||
|
def version(self, version: int) -> Dict:
|
||||||
|
"""
|
||||||
|
in the form of:
|
||||||
|
11: {"rom": 2.00.00, "data": 2.00.00}
|
||||||
|
"""
|
||||||
|
return CoreConfig.get_config_field(
|
||||||
|
self.__config, "chuni", "version", default={}
|
||||||
|
)[version]
|
||||||
|
|
||||||
|
|
||||||
class ChuniCryptoConfig:
|
class ChuniCryptoConfig:
|
||||||
def __init__(self, parent_config: "ChuniConfig") -> None:
|
def __init__(self, parent_config: "ChuniConfig") -> None:
|
||||||
self.__config = parent_config
|
self.__config = parent_config
|
||||||
@ -46,4 +82,7 @@ class ChuniCryptoConfig:
|
|||||||
class ChuniConfig(dict):
|
class ChuniConfig(dict):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.server = ChuniServerConfig(self)
|
self.server = ChuniServerConfig(self)
|
||||||
|
self.team = ChuniTeamConfig(self)
|
||||||
|
self.mods = ChuniModsConfig(self)
|
||||||
|
self.version = ChuniVersionConfig(self)
|
||||||
self.crypto = ChuniCryptoConfig(self)
|
self.crypto = ChuniCryptoConfig(self)
|
||||||
|
@ -49,8 +49,8 @@ class ChuniNew(ChuniBase):
|
|||||||
"matchEndTime": match_end,
|
"matchEndTime": match_end,
|
||||||
"matchTimeLimit": 99,
|
"matchTimeLimit": 99,
|
||||||
"matchErrorLimit": 9999,
|
"matchErrorLimit": 9999,
|
||||||
"romVersion": "2.00.00",
|
"romVersion": self.game_cfg.version.version(self.version)["rom"],
|
||||||
"dataVersion": "2.00.00",
|
"dataVersion": self.game_cfg.version.version(self.version)["data"],
|
||||||
"matchingUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
"matchingUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
||||||
"matchingUriX": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
"matchingUriX": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
||||||
"udpHolePunchUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
"udpHolePunchUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
||||||
@ -269,10 +269,10 @@ class ChuniNew(ChuniBase):
|
|||||||
tmp = user_print_list[x]._asdict()
|
tmp = user_print_list[x]._asdict()
|
||||||
print_list.append(tmp["cardId"])
|
print_list.append(tmp["cardId"])
|
||||||
|
|
||||||
if len(user_print_list) >= max_ct:
|
if len(print_list) >= max_ct:
|
||||||
break
|
break
|
||||||
|
|
||||||
if len(user_print_list) >= max_ct:
|
if len(print_list) >= max_ct:
|
||||||
next_idx = next_idx + max_ct
|
next_idx = next_idx + max_ct
|
||||||
else:
|
else:
|
||||||
next_idx = -1
|
next_idx = -1
|
||||||
@ -454,9 +454,7 @@ class ChuniNew(ChuniBase):
|
|||||||
|
|
||||||
# set the card print state to success and use the orderId as the key
|
# set the card print state to success and use the orderId as the key
|
||||||
self.data.item.put_user_print_state(
|
self.data.item.put_user_print_state(
|
||||||
user_id,
|
user_id, id=upsert["orderId"], hasCompleted=True
|
||||||
id=upsert["orderId"],
|
|
||||||
hasCompleted=True
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return {"returnCode": "1", "apiName": "CMUpsertUserPrintSubtractApi"}
|
return {"returnCode": "1", "apiName": "CMUpsertUserPrintSubtractApi"}
|
||||||
@ -467,10 +465,6 @@ class ChuniNew(ChuniBase):
|
|||||||
|
|
||||||
# set the card print state to success and use the orderId as the key
|
# set the card print state to success and use the orderId as the key
|
||||||
for order_id in order_ids:
|
for order_id in order_ids:
|
||||||
self.data.item.put_user_print_state(
|
self.data.item.put_user_print_state(user_id, id=order_id, hasCompleted=True)
|
||||||
user_id,
|
|
||||||
id=order_id,
|
|
||||||
hasCompleted=True
|
|
||||||
)
|
|
||||||
|
|
||||||
return {"returnCode": "1", "apiName": "CMUpsertUserPrintCancelApi"}
|
return {"returnCode": "1", "apiName": "CMUpsertUserPrintCancelApi"}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
import pytz
|
|
||||||
|
|
||||||
from core.config import CoreConfig
|
from core.config import CoreConfig
|
||||||
from titles.chuni.new import ChuniNew
|
from titles.chuni.new import ChuniNew
|
||||||
@ -15,8 +13,8 @@ class ChuniNewPlus(ChuniNew):
|
|||||||
|
|
||||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||||
ret = super().handle_get_game_setting_api_request(data)
|
ret = super().handle_get_game_setting_api_request(data)
|
||||||
ret["gameSetting"]["romVersion"] = "2.05.00"
|
ret["gameSetting"]["romVersion"] = self.game_cfg.version.version(self.version)["rom"]
|
||||||
ret["gameSetting"]["dataVersion"] = "2.05.00"
|
ret["gameSetting"]["dataVersion"] = self.game_cfg.version.version(self.version)["data"]
|
||||||
ret["gameSetting"][
|
ret["gameSetting"][
|
||||||
"matchingUri"
|
"matchingUri"
|
||||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
||||||
|
@ -42,6 +42,80 @@ class ChuniReader(BaseReader):
|
|||||||
self.read_music(f"{dir}/music")
|
self.read_music(f"{dir}/music")
|
||||||
self.read_charges(f"{dir}/chargeItem")
|
self.read_charges(f"{dir}/chargeItem")
|
||||||
self.read_avatar(f"{dir}/avatarAccessory")
|
self.read_avatar(f"{dir}/avatarAccessory")
|
||||||
|
self.read_login_bonus(f"{dir}/")
|
||||||
|
|
||||||
|
def read_login_bonus(self, root_dir: str) -> None:
|
||||||
|
for root, dirs, files in walk(f"{root_dir}loginBonusPreset"):
|
||||||
|
for dir in dirs:
|
||||||
|
if path.exists(f"{root}/{dir}/LoginBonusPreset.xml"):
|
||||||
|
with open(f"{root}/{dir}/LoginBonusPreset.xml", "rb") as fp:
|
||||||
|
bytedata = fp.read()
|
||||||
|
strdata = bytedata.decode("UTF-8")
|
||||||
|
|
||||||
|
xml_root = ET.fromstring(strdata)
|
||||||
|
for name in xml_root.findall("name"):
|
||||||
|
id = name.find("id").text
|
||||||
|
name = name.find("str").text
|
||||||
|
is_enabled = (
|
||||||
|
True if xml_root.find("disableFlag").text == "false" else False
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.data.static.put_login_bonus_preset(
|
||||||
|
self.version, id, name, is_enabled
|
||||||
|
)
|
||||||
|
|
||||||
|
if result is not None:
|
||||||
|
self.logger.info(f"Inserted login bonus preset {id}")
|
||||||
|
else:
|
||||||
|
self.logger.warn(f"Failed to insert login bonus preset {id}")
|
||||||
|
|
||||||
|
for bonus in xml_root.find("infos").findall("LoginBonusDataInfo"):
|
||||||
|
for name in bonus.findall("loginBonusName"):
|
||||||
|
bonus_id = name.find("id").text
|
||||||
|
bonus_name = name.find("str").text
|
||||||
|
|
||||||
|
if path.exists(
|
||||||
|
f"{root_dir}/loginBonus/loginBonus{bonus_id}/LoginBonus.xml"
|
||||||
|
):
|
||||||
|
with open(
|
||||||
|
f"{root_dir}/loginBonus/loginBonus{bonus_id}/LoginBonus.xml",
|
||||||
|
"rb",
|
||||||
|
) as fp:
|
||||||
|
bytedata = fp.read()
|
||||||
|
strdata = bytedata.decode("UTF-8")
|
||||||
|
|
||||||
|
bonus_root = ET.fromstring(strdata)
|
||||||
|
|
||||||
|
for present in bonus_root.findall("present"):
|
||||||
|
present_id = present.find("id").text
|
||||||
|
present_name = present.find("str").text
|
||||||
|
|
||||||
|
item_num = int(bonus_root.find("itemNum").text)
|
||||||
|
need_login_day_count = int(
|
||||||
|
bonus_root.find("needLoginDayCount").text
|
||||||
|
)
|
||||||
|
login_bonus_category_type = int(
|
||||||
|
bonus_root.find("loginBonusCategoryType").text
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.data.static.put_login_bonus(
|
||||||
|
self.version,
|
||||||
|
id,
|
||||||
|
bonus_id,
|
||||||
|
bonus_name,
|
||||||
|
present_id,
|
||||||
|
present_name,
|
||||||
|
item_num,
|
||||||
|
need_login_day_count,
|
||||||
|
login_bonus_category_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
if result is not None:
|
||||||
|
self.logger.info(f"Inserted login bonus {bonus_id}")
|
||||||
|
else:
|
||||||
|
self.logger.warn(
|
||||||
|
f"Failed to insert login bonus {bonus_id}"
|
||||||
|
)
|
||||||
|
|
||||||
def read_events(self, evt_dir: str) -> None:
|
def read_events(self, evt_dir: str) -> None:
|
||||||
for root, dirs, files in walk(evt_dir):
|
for root, dirs, files in walk(evt_dir):
|
||||||
|
@ -184,8 +184,73 @@ print_detail = Table(
|
|||||||
mysql_charset="utf8mb4",
|
mysql_charset="utf8mb4",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
login_bonus = Table(
|
||||||
|
"chuni_item_login_bonus",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column(
|
||||||
|
"user",
|
||||||
|
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
Column("version", Integer, nullable=False),
|
||||||
|
Column("presetId", Integer, nullable=False),
|
||||||
|
Column("bonusCount", Integer, nullable=False, server_default="0"),
|
||||||
|
Column("lastUpdateDate", TIMESTAMP, server_default="2018-01-01 00:00:00.0"),
|
||||||
|
Column("isWatched", Boolean, server_default="0"),
|
||||||
|
Column("isFinished", Boolean, server_default="0"),
|
||||||
|
UniqueConstraint("version", "user", "presetId", name="chuni_item_login_bonus_uk"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ChuniItemData(BaseData):
|
class ChuniItemData(BaseData):
|
||||||
|
def put_login_bonus(
|
||||||
|
self, user_id: int, version: int, preset_id: int, **login_bonus_data
|
||||||
|
) -> Optional[int]:
|
||||||
|
sql = insert(login_bonus).values(
|
||||||
|
version=version, user=user_id, presetId=preset_id, **login_bonus_data
|
||||||
|
)
|
||||||
|
|
||||||
|
conflict = sql.on_duplicate_key_update(presetId=preset_id, **login_bonus_data)
|
||||||
|
|
||||||
|
result = self.execute(conflict)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.lastrowid
|
||||||
|
|
||||||
|
def get_all_login_bonus(
|
||||||
|
self, user_id: int, version: int, is_finished: bool = False
|
||||||
|
) -> Optional[List[Row]]:
|
||||||
|
sql = login_bonus.select(
|
||||||
|
and_(
|
||||||
|
login_bonus.c.version == version,
|
||||||
|
login_bonus.c.user == user_id,
|
||||||
|
login_bonus.c.isFinished == is_finished,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchall()
|
||||||
|
|
||||||
|
def get_login_bonus(
|
||||||
|
self, user_id: int, version: int, preset_id: int
|
||||||
|
) -> Optional[Row]:
|
||||||
|
sql = login_bonus.select(
|
||||||
|
and_(
|
||||||
|
login_bonus.c.version == version,
|
||||||
|
login_bonus.c.user == user_id,
|
||||||
|
login_bonus.c.presetId == preset_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
def put_character(self, user_id: int, character_data: Dict) -> Optional[int]:
|
def put_character(self, user_id: int, character_data: Dict) -> Optional[int]:
|
||||||
character_data["user"] = user_id
|
character_data["user"] = user_id
|
||||||
|
|
||||||
@ -335,7 +400,7 @@ class ChuniItemData(BaseData):
|
|||||||
sql = print_state.select(
|
sql = print_state.select(
|
||||||
and_(
|
and_(
|
||||||
print_state.c.user == aime_id,
|
print_state.c.user == aime_id,
|
||||||
print_state.c.hasCompleted == has_completed
|
print_state.c.hasCompleted == has_completed,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -351,7 +416,7 @@ class ChuniItemData(BaseData):
|
|||||||
and_(
|
and_(
|
||||||
print_state.c.user == aime_id,
|
print_state.c.user == aime_id,
|
||||||
print_state.c.gachaId == gacha_id,
|
print_state.c.gachaId == gacha_id,
|
||||||
print_state.c.hasCompleted == has_completed
|
print_state.c.hasCompleted == has_completed,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -380,9 +445,7 @@ class ChuniItemData(BaseData):
|
|||||||
user=aime_id, serialId=serial_id, **user_print_data
|
user=aime_id, serialId=serial_id, **user_print_data
|
||||||
)
|
)
|
||||||
|
|
||||||
conflict = sql.on_duplicate_key_update(
|
conflict = sql.on_duplicate_key_update(user=aime_id, **user_print_data)
|
||||||
user=aime_id, **user_print_data
|
|
||||||
)
|
|
||||||
result = self.execute(conflict)
|
result = self.execute(conflict)
|
||||||
|
|
||||||
if result is None:
|
if result is None:
|
||||||
@ -390,4 +453,4 @@ class ChuniItemData(BaseData):
|
|||||||
f"put_user_print_detail: Failed to insert! aime_id: {aime_id}"
|
f"put_user_print_detail: Failed to insert! aime_id: {aime_id}"
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
return result.lastrowid
|
return result.lastrowid
|
||||||
|
@ -558,8 +558,10 @@ class ChuniProfileData(BaseData):
|
|||||||
return result.lastrowid
|
return result.lastrowid
|
||||||
|
|
||||||
def get_profile_activity(self, aime_id: int, kind: int) -> Optional[List[Row]]:
|
def get_profile_activity(self, aime_id: int, kind: int) -> Optional[List[Row]]:
|
||||||
sql = select(activity).where(
|
sql = (
|
||||||
and_(activity.c.user == aime_id, activity.c.kind == kind)
|
select(activity)
|
||||||
|
.where(and_(activity.c.user == aime_id, activity.c.kind == kind))
|
||||||
|
.order_by(activity.c.sortNumber.desc()) # to get the last played track
|
||||||
)
|
)
|
||||||
|
|
||||||
result = self.execute(sql)
|
result = self.execute(sql)
|
||||||
|
@ -122,8 +122,148 @@ gacha_cards = Table(
|
|||||||
mysql_charset="utf8mb4",
|
mysql_charset="utf8mb4",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
login_bonus_preset = Table(
|
||||||
|
"chuni_static_login_bonus_preset",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("version", Integer, nullable=False),
|
||||||
|
Column("presetName", String(255), nullable=False),
|
||||||
|
Column("isEnabled", Boolean, server_default="1"),
|
||||||
|
UniqueConstraint("version", "id", name="chuni_static_login_bonus_preset_uk"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
login_bonus = Table(
|
||||||
|
"chuni_static_login_bonus",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("version", Integer, nullable=False),
|
||||||
|
Column(
|
||||||
|
"presetId",
|
||||||
|
ForeignKey(
|
||||||
|
"chuni_static_login_bonus_preset.id",
|
||||||
|
ondelete="cascade",
|
||||||
|
onupdate="cascade",
|
||||||
|
),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
Column("loginBonusId", Integer, nullable=False),
|
||||||
|
Column("loginBonusName", String(255), nullable=False),
|
||||||
|
Column("presentId", Integer, nullable=False),
|
||||||
|
Column("presentName", String(255), nullable=False),
|
||||||
|
Column("itemNum", Integer, nullable=False),
|
||||||
|
Column("needLoginDayCount", Integer, nullable=False),
|
||||||
|
Column("loginBonusCategoryType", Integer, nullable=False),
|
||||||
|
UniqueConstraint(
|
||||||
|
"version", "presetId", "loginBonusId", name="chuni_static_login_bonus_uk"
|
||||||
|
),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ChuniStaticData(BaseData):
|
class ChuniStaticData(BaseData):
|
||||||
|
def put_login_bonus(
|
||||||
|
self,
|
||||||
|
version: int,
|
||||||
|
preset_id: int,
|
||||||
|
login_bonus_id: int,
|
||||||
|
login_bonus_name: str,
|
||||||
|
present_id: int,
|
||||||
|
present_ame: str,
|
||||||
|
item_num: int,
|
||||||
|
need_login_day_count: int,
|
||||||
|
login_bonus_category_type: int,
|
||||||
|
) -> Optional[int]:
|
||||||
|
sql = insert(login_bonus).values(
|
||||||
|
version=version,
|
||||||
|
presetId=preset_id,
|
||||||
|
loginBonusId=login_bonus_id,
|
||||||
|
loginBonusName=login_bonus_name,
|
||||||
|
presentId=present_id,
|
||||||
|
presentName=present_ame,
|
||||||
|
itemNum=item_num,
|
||||||
|
needLoginDayCount=need_login_day_count,
|
||||||
|
loginBonusCategoryType=login_bonus_category_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
conflict = sql.on_duplicate_key_update(
|
||||||
|
loginBonusName=login_bonus_name,
|
||||||
|
presentName=present_ame,
|
||||||
|
itemNum=item_num,
|
||||||
|
needLoginDayCount=need_login_day_count,
|
||||||
|
loginBonusCategoryType=login_bonus_category_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(conflict)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.lastrowid
|
||||||
|
|
||||||
|
def get_login_bonus(
|
||||||
|
self, version: int, preset_id: int,
|
||||||
|
) -> Optional[List[Row]]:
|
||||||
|
sql = login_bonus.select(
|
||||||
|
and_(
|
||||||
|
login_bonus.c.version == version,
|
||||||
|
login_bonus.c.presetId == preset_id,
|
||||||
|
)
|
||||||
|
).order_by(login_bonus.c.needLoginDayCount.desc())
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchall()
|
||||||
|
|
||||||
|
def get_login_bonus_by_required_days(
|
||||||
|
self, version: int, preset_id: int, need_login_day_count: int
|
||||||
|
) -> Optional[Row]:
|
||||||
|
sql = login_bonus.select(
|
||||||
|
and_(
|
||||||
|
login_bonus.c.version == version,
|
||||||
|
login_bonus.c.presetId == preset_id,
|
||||||
|
login_bonus.c.needLoginDayCount == need_login_day_count,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
|
def put_login_bonus_preset(
|
||||||
|
self, version: int, preset_id: int, preset_name: str, is_enabled: bool
|
||||||
|
) -> Optional[int]:
|
||||||
|
sql = insert(login_bonus_preset).values(
|
||||||
|
id=preset_id,
|
||||||
|
version=version,
|
||||||
|
presetName=preset_name,
|
||||||
|
isEnabled=is_enabled,
|
||||||
|
)
|
||||||
|
|
||||||
|
conflict = sql.on_duplicate_key_update(
|
||||||
|
presetName=preset_name, isEnabled=is_enabled
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(conflict)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.lastrowid
|
||||||
|
|
||||||
|
def get_login_bonus_presets(
|
||||||
|
self, version: int, is_enabled: bool = True
|
||||||
|
) -> Optional[List[Row]]:
|
||||||
|
sql = login_bonus_preset.select(
|
||||||
|
and_(
|
||||||
|
login_bonus_preset.c.version == version,
|
||||||
|
login_bonus_preset.c.isEnabled == is_enabled,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchall()
|
||||||
|
|
||||||
def put_event(
|
def put_event(
|
||||||
self, version: int, event_id: int, type: int, name: str
|
self, version: int, event_id: int, type: int, name: str
|
||||||
) -> Optional[int]:
|
) -> Optional[int]:
|
||||||
@ -390,20 +530,17 @@ class ChuniStaticData(BaseData):
|
|||||||
return None
|
return None
|
||||||
return result.fetchall()
|
return result.fetchall()
|
||||||
|
|
||||||
def get_gacha_card_by_character(self, gacha_id: int, chara_id: int) -> Optional[Dict]:
|
def get_gacha_card_by_character(
|
||||||
|
self, gacha_id: int, chara_id: int
|
||||||
|
) -> Optional[Dict]:
|
||||||
sql_sub = (
|
sql_sub = (
|
||||||
select(cards.c.cardId)
|
select(cards.c.cardId).filter(cards.c.charaId == chara_id).scalar_subquery()
|
||||||
.filter(
|
|
||||||
cards.c.charaId == chara_id
|
|
||||||
)
|
|
||||||
.scalar_subquery()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Perform the main query, also rename the resulting column to ranking
|
# Perform the main query, also rename the resulting column to ranking
|
||||||
sql = gacha_cards.select(and_(
|
sql = gacha_cards.select(
|
||||||
gacha_cards.c.gachaId == gacha_id,
|
and_(gacha_cards.c.gachaId == gacha_id, gacha_cards.c.cardId == sql_sub)
|
||||||
gacha_cards.c.cardId == sql_sub
|
)
|
||||||
))
|
|
||||||
|
|
||||||
result = self.execute(sql)
|
result = self.execute(sql)
|
||||||
if result is None:
|
if result is None:
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import json, logging
|
import json, logging
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
import random
|
||||||
|
|
||||||
from core.config import CoreConfig
|
from core.data import Data
|
||||||
|
from core import CoreConfig
|
||||||
from titles.pokken.config import PokkenConfig
|
from titles.pokken.config import PokkenConfig
|
||||||
from titles.pokken.proto import jackal_pb2
|
from titles.pokken.proto import jackal_pb2
|
||||||
|
|
||||||
@ -13,6 +15,7 @@ class PokkenBase:
|
|||||||
self.game_cfg = game_cfg
|
self.game_cfg = game_cfg
|
||||||
self.version = 0
|
self.version = 0
|
||||||
self.logger = logging.getLogger("pokken")
|
self.logger = logging.getLogger("pokken")
|
||||||
|
self.data = Data(core_cfg)
|
||||||
|
|
||||||
def handle_noop(self, request: Any) -> bytes:
|
def handle_noop(self, request: Any) -> bytes:
|
||||||
res = jackal_pb2.Response()
|
res = jackal_pb2.Response()
|
||||||
@ -123,7 +126,94 @@ class PokkenBase:
|
|||||||
ranking.event_end = True
|
ranking.event_end = True
|
||||||
ranking.modify_date = int(datetime.now().timestamp() / 1000)
|
ranking.modify_date = int(datetime.now().timestamp() / 1000)
|
||||||
res.load_ranking.CopyFrom(ranking)
|
res.load_ranking.CopyFrom(ranking)
|
||||||
|
return res.SerializeToString()
|
||||||
|
|
||||||
|
def handle_load_user(self, request: jackal_pb2.Request) -> bytes:
|
||||||
|
res = jackal_pb2.Response()
|
||||||
|
res.result = 1
|
||||||
|
res.type = jackal_pb2.MessageType.LOAD_USER
|
||||||
|
access_code = request.load_user.access_code
|
||||||
|
user_id = self.data.card.get_user_id_from_card(access_code)
|
||||||
|
|
||||||
|
if user_id is None: # TODO: Toggle auto-register
|
||||||
|
user_id = self.data.user.create_user()
|
||||||
|
card_id = self.data.card.create_card(user_id, access_code)
|
||||||
|
|
||||||
|
self.logger.info(f"Register new card {access_code} (UserId {user_id}, CardId {card_id})")
|
||||||
|
|
||||||
|
# TODO: Check for user data. For now just treat ever card-in as a new user
|
||||||
|
|
||||||
|
load_usr = jackal_pb2.LoadUserResponseData()
|
||||||
|
load_usr.commidserv_result = 1
|
||||||
|
load_usr.load_hash = 1
|
||||||
|
load_usr.cardlock_status = False
|
||||||
|
load_usr.banapass_id = user_id
|
||||||
|
load_usr.access_code = access_code
|
||||||
|
load_usr.new_card_flag = True
|
||||||
|
load_usr.precedent_release_flag = 0xFFFFFFFF
|
||||||
|
load_usr.navi_newbie_flag = True
|
||||||
|
load_usr.navi_enable_flag = True
|
||||||
|
load_usr.pad_vibrate_flag = True
|
||||||
|
load_usr.home_region_code = 0
|
||||||
|
load_usr.home_loc_name = ""
|
||||||
|
load_usr.pref_code = 0
|
||||||
|
load_usr.trainer_name = "Newb" + str(random.randint(1111,999999))
|
||||||
|
load_usr.trainer_rank_point = 0
|
||||||
|
load_usr.wallet = 0
|
||||||
|
load_usr.fight_money = 0
|
||||||
|
load_usr.score_point = 0
|
||||||
|
load_usr.grade_max_num = 0
|
||||||
|
load_usr.total_play_days = 0
|
||||||
|
load_usr.play_date_time = 0
|
||||||
|
load_usr.lucky_box_fail_num = 0
|
||||||
|
load_usr.event_reward_get_flag = 0
|
||||||
|
load_usr.rank_pvp_all = 0
|
||||||
|
load_usr.rank_pvp_loc = 0
|
||||||
|
load_usr.rank_cpu_all = 0
|
||||||
|
load_usr.rank_cpu_loc = 0
|
||||||
|
load_usr.rank_event = 0
|
||||||
|
load_usr.awake_num = 0
|
||||||
|
load_usr.use_support_num = 0
|
||||||
|
load_usr.rankmatch_flag = 0
|
||||||
|
load_usr.title_text_id = 0
|
||||||
|
load_usr.title_plate_id = 0
|
||||||
|
load_usr.title_decoration_id = 0
|
||||||
|
load_usr.navi_trainer = 0
|
||||||
|
load_usr.navi_version_id = 0
|
||||||
|
load_usr.aid_skill = 0
|
||||||
|
load_usr.comment_text_id = 0
|
||||||
|
load_usr.comment_word_id = 0
|
||||||
|
load_usr.latest_use_pokemon = 0
|
||||||
|
load_usr.ex_ko_num = 0
|
||||||
|
load_usr.wko_num = 0
|
||||||
|
load_usr.timeup_win_num = 0
|
||||||
|
load_usr.cool_ko_num = 0
|
||||||
|
load_usr.perfect_ko_num = 0
|
||||||
|
load_usr.record_flag = 0
|
||||||
|
load_usr.site_register_status = 0
|
||||||
|
load_usr.continue_num = 0
|
||||||
|
load_usr.event_state = 0
|
||||||
|
load_usr.event_id = 0
|
||||||
|
load_usr.sp_bonus_category_id_1 = 0
|
||||||
|
load_usr.sp_bonus_key_value_1 = 0
|
||||||
|
load_usr.sp_bonus_category_id_2 = 0
|
||||||
|
load_usr.sp_bonus_key_value_2 = 0
|
||||||
|
|
||||||
|
res.load_user.CopyFrom(load_usr)
|
||||||
|
return res.SerializeToString()
|
||||||
|
|
||||||
|
def handle_set_bnpassid_lock(self, data: jackal_pb2.Request) -> bytes:
|
||||||
|
res = jackal_pb2.Response()
|
||||||
|
res.result = 1
|
||||||
|
res.type = jackal_pb2.MessageType.SET_BNPASSID_LOCK
|
||||||
|
return res.SerializeToString()
|
||||||
|
|
||||||
|
def handle_save_ingame_log(self, data: jackal_pb2.Request) -> bytes:
|
||||||
|
res = jackal_pb2.Response()
|
||||||
|
res.result = 1
|
||||||
|
res.type = jackal_pb2.MessageType.SET_BNPASSID_LOCK
|
||||||
|
return res.SerializeToString()
|
||||||
|
|
||||||
def handle_matching_noop(self, data: Dict = {}, client_ip: str = "127.0.0.1") -> Dict:
|
def handle_matching_noop(self, data: Dict = {}, client_ip: str = "127.0.0.1") -> Dict:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
@ -124,7 +124,6 @@ class PokkenServlet(resource.Resource):
|
|||||||
self.logger.debug(pokken_request)
|
self.logger.debug(pokken_request)
|
||||||
|
|
||||||
ret = handler(pokken_request)
|
ret = handler(pokken_request)
|
||||||
self.logger.debug(f"Response: {ret}")
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def handle_matching(self, request: Request) -> bytes:
|
def handle_matching(self, request: Request) -> bytes:
|
||||||
|
@ -635,14 +635,14 @@ class WaccaBase:
|
|||||||
new_tickets.append([ticket["id"], ticket["ticket_id"], 9999999999])
|
new_tickets.append([ticket["id"], ticket["ticket_id"], 9999999999])
|
||||||
|
|
||||||
for item in req.itemsUsed:
|
for item in req.itemsUsed:
|
||||||
if item.itemType == WaccaConstants.ITEM_TYPES["wp"]:
|
if item.itemType == WaccaConstants.ITEM_TYPES["wp"] and not self.game_config.mods.infinite_wp:
|
||||||
if current_wp >= item.quantity:
|
if current_wp >= item.quantity:
|
||||||
current_wp -= item.quantity
|
current_wp -= item.quantity
|
||||||
self.data.profile.spend_wp(req.profileId, item.quantity)
|
self.data.profile.spend_wp(req.profileId, item.quantity)
|
||||||
else:
|
else:
|
||||||
return BaseResponse().make()
|
return BaseResponse().make()
|
||||||
|
|
||||||
elif item.itemType == WaccaConstants.ITEM_TYPES["ticket"]:
|
elif item.itemType == WaccaConstants.ITEM_TYPES["ticket"] and not self.game_config.mods.infinite_tickets:
|
||||||
for x in range(len(new_tickets)):
|
for x in range(len(new_tickets)):
|
||||||
if new_tickets[x][1] == item.itemId:
|
if new_tickets[x][1] == item.itemId:
|
||||||
self.data.item.spend_ticket(new_tickets[x][0])
|
self.data.item.spend_ticket(new_tickets[x][0])
|
||||||
@ -836,7 +836,7 @@ class WaccaBase:
|
|||||||
resp.songDetail.grades = SongDetailGradeCountsV2(counts=grades)
|
resp.songDetail.grades = SongDetailGradeCountsV2(counts=grades)
|
||||||
else:
|
else:
|
||||||
resp.songDetail.grades = SongDetailGradeCountsV1(counts=grades)
|
resp.songDetail.grades = SongDetailGradeCountsV1(counts=grades)
|
||||||
|
resp.songDetail.lock_state = 1
|
||||||
return resp.make()
|
return resp.make()
|
||||||
|
|
||||||
# TODO: Coop and vs data
|
# TODO: Coop and vs data
|
||||||
@ -880,7 +880,7 @@ class WaccaBase:
|
|||||||
user_id = profile["user"]
|
user_id = profile["user"]
|
||||||
resp.currentWp = profile["wp"]
|
resp.currentWp = profile["wp"]
|
||||||
|
|
||||||
if req.purchaseType == PurchaseType.PurchaseTypeWP:
|
if req.purchaseType == PurchaseType.PurchaseTypeWP and not self.game_config.mods.infinite_wp:
|
||||||
resp.currentWp -= req.cost
|
resp.currentWp -= req.cost
|
||||||
self.data.profile.spend_wp(req.profileId, req.cost)
|
self.data.profile.spend_wp(req.profileId, req.cost)
|
||||||
|
|
||||||
@ -1070,19 +1070,12 @@ class WaccaBase:
|
|||||||
):
|
):
|
||||||
if item.quantity > WaccaConstants.Difficulty.HARD.value:
|
if item.quantity > WaccaConstants.Difficulty.HARD.value:
|
||||||
old_score = self.data.score.get_best_score(
|
old_score = self.data.score.get_best_score(
|
||||||
user_id, item.itemId, item.quantity
|
user_id, item.itemId, item.quantity
|
||||||
|
)
|
||||||
|
if not old_score:
|
||||||
|
self.data.score.put_best_score(
|
||||||
|
user_id, item.itemId, item.quantity, 0, [0] * 5, [0] * 13, 0, 0
|
||||||
)
|
)
|
||||||
if not old_score:
|
|
||||||
self.data.score.put_best_score(
|
|
||||||
user_id,
|
|
||||||
item.itemId,
|
|
||||||
item.quantity,
|
|
||||||
0,
|
|
||||||
[0] * 5,
|
|
||||||
[0] * 13,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
|
|
||||||
if item.quantity == 0:
|
if item.quantity == 0:
|
||||||
item.quantity = WaccaConstants.Difficulty.HARD.value
|
item.quantity = WaccaConstants.Difficulty.HARD.value
|
||||||
|
@ -577,7 +577,21 @@ class SongDetailGradeCountsV2(SongDetailGradeCountsV1):
|
|||||||
self.ssspCt = counts[12]
|
self.ssspCt = counts[12]
|
||||||
|
|
||||||
def make(self) -> List:
|
def make(self) -> List:
|
||||||
return super().make() + [self.spCt, self.sspCt, self.ssspCt]
|
return [
|
||||||
|
self.dCt,
|
||||||
|
self.cCt,
|
||||||
|
self.bCt,
|
||||||
|
self.aCt,
|
||||||
|
self.aaCt,
|
||||||
|
self.aaaCt,
|
||||||
|
self.sCt,
|
||||||
|
self.spCt,
|
||||||
|
self.ssCt,
|
||||||
|
self.sspCt,
|
||||||
|
self.sssCt,
|
||||||
|
self.ssspCt,
|
||||||
|
self.masterCt,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class BestScoreDetailV1:
|
class BestScoreDetailV1:
|
||||||
@ -928,7 +942,7 @@ class MusicUpdateDetailV1:
|
|||||||
self.score = 0
|
self.score = 0
|
||||||
self.lowestMissCount = 0
|
self.lowestMissCount = 0
|
||||||
self.maxSkillPts = 0
|
self.maxSkillPts = 0
|
||||||
self.locked = 0
|
self.lock_state = 0
|
||||||
|
|
||||||
def make(self) -> List:
|
def make(self) -> List:
|
||||||
return [
|
return [
|
||||||
@ -940,7 +954,7 @@ class MusicUpdateDetailV1:
|
|||||||
self.score,
|
self.score,
|
||||||
self.lowestMissCount,
|
self.lowestMissCount,
|
||||||
self.maxSkillPts,
|
self.maxSkillPts,
|
||||||
self.locked,
|
self.lock_state,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ class UserInfoUpdateRequest(BaseRequest):
|
|||||||
self.profileId = int(self.params[0])
|
self.profileId = int(self.params[0])
|
||||||
self.optsUpdated: List[UserOption] = []
|
self.optsUpdated: List[UserOption] = []
|
||||||
self.unknown2: List = self.params[2]
|
self.unknown2: List = self.params[2]
|
||||||
self.datesUpdated: List[DateUpdate] = []
|
self.datesUpdated: List[DateUpdate] = []
|
||||||
self.favoritesAdded: List[int] = self.params[4]
|
self.favoritesRemoved: List[int] = self.params[4]
|
||||||
self.favoritesRemoved: List[int] = self.params[5]
|
self.favoritesAdded: List[int] = self.params[5]
|
||||||
|
|
||||||
for x in self.params[1]:
|
for x in self.params[1]:
|
||||||
self.optsUpdated.append(UserOption(x[0], x[1]))
|
self.optsUpdated.append(UserOption(x[0], x[1]))
|
||||||
|
@ -102,7 +102,7 @@ class WaccaServlet:
|
|||||||
resp.message = "不正なリクエスト エラーです"
|
resp.message = "不正なリクエスト エラーです"
|
||||||
return end(resp.make())
|
return end(resp.make())
|
||||||
|
|
||||||
if "/api/" in url_path:
|
if "api/" in url_path:
|
||||||
func_to_find = (
|
func_to_find = (
|
||||||
"handle_" + url_path.partition("api/")[2].replace("/", "_") + "_request"
|
"handle_" + url_path.partition("api/")[2].replace("/", "_") + "_request"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user