2023-02-17 06:02:21 +00:00
|
|
|
import logging
|
|
|
|
import json
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
from time import strftime
|
|
|
|
|
|
|
|
import pytz
|
2023-07-05 14:47:43 +00:00
|
|
|
from typing import Dict, Any, List
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
from core.config import CoreConfig
|
|
|
|
from titles.chuni.const import ChuniConstants
|
|
|
|
from titles.chuni.database import ChuniData
|
|
|
|
from titles.chuni.config import ChuniConfig
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
|
|
|
|
class ChuniBase:
|
2023-02-17 06:02:21 +00:00
|
|
|
def __init__(self, core_cfg: CoreConfig, game_cfg: ChuniConfig) -> None:
|
|
|
|
self.core_cfg = core_cfg
|
|
|
|
self.game_cfg = game_cfg
|
|
|
|
self.data = ChuniData(core_cfg)
|
|
|
|
self.date_time_format = "%Y-%m-%d %H:%M:%S"
|
|
|
|
self.logger = logging.getLogger("chuni")
|
|
|
|
self.game = ChuniConstants.GAME_CODE
|
|
|
|
self.version = ChuniConstants.VER_CHUNITHM
|
2023-03-03 22:46:29 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
def handle_game_login_api_request(self, data: Dict) -> Dict:
|
2023-03-28 16:28:57 +00:00
|
|
|
"""
|
|
|
|
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(
|
2023-05-10 19:32:35 +00:00
|
|
|
user_id, self.version, preset["presetId"]
|
2023-03-28 16:28:57 +00:00
|
|
|
)
|
|
|
|
if user_login_bonus is None:
|
2023-05-10 19:32:35 +00:00
|
|
|
self.data.item.put_login_bonus(
|
|
|
|
user_id, self.version, preset["presetId"]
|
|
|
|
)
|
2023-03-28 16:28:57 +00:00
|
|
|
# yeah i'm lazy
|
|
|
|
user_login_bonus = self.data.item.get_login_bonus(
|
2023-05-10 19:32:35 +00:00
|
|
|
user_id, self.version, preset["presetId"]
|
2023-03-28 16:28:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# 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(
|
2023-05-10 19:32:35 +00:00
|
|
|
self.version, preset["presetId"]
|
2023-03-28 16:28:57 +00:00
|
|
|
)
|
|
|
|
|
2023-03-30 20:58:45 +00:00
|
|
|
# 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(
|
2023-05-10 19:32:35 +00:00
|
|
|
f"No bonus entries found for bonus preset {preset['presetId']}"
|
2023-03-30 20:58:45 +00:00
|
|
|
)
|
|
|
|
continue
|
|
|
|
|
2023-03-28 16:28:57 +00:00
|
|
|
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?
|
2023-05-10 19:32:35 +00:00
|
|
|
if preset["presetId"] < 3000:
|
2023-03-28 16:28:57 +00:00
|
|
|
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(
|
2023-05-10 19:32:35 +00:00
|
|
|
self.version, preset["presetId"], bonus_count
|
2023-03-28 16:28:57 +00:00
|
|
|
)
|
|
|
|
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,
|
2023-05-10 19:32:35 +00:00
|
|
|
preset["presetId"],
|
2023-03-28 16:28:57 +00:00
|
|
|
bonusCount=bonus_count,
|
|
|
|
lastUpdateDate=last_update_date,
|
|
|
|
isWatched=False,
|
|
|
|
isFinished=is_finished,
|
|
|
|
)
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": 1}
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
def handle_game_logout_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
# self.data.base.log_event("chuni", "logout", logging.INFO, {"version": self.version, "user": data["userId"]})
|
|
|
|
return {"returnCode": 1}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_game_charge_api_request(self, data: Dict) -> Dict:
|
|
|
|
game_charge_list = self.data.static.get_enabled_charges(self.version)
|
2023-03-24 17:10:10 +00:00
|
|
|
|
2023-03-17 06:16:49 +00:00
|
|
|
if game_charge_list is None or len(game_charge_list) == 0:
|
|
|
|
return {"length": 0, "gameChargeList": []}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
charges = []
|
2023-03-09 16:38:58 +00:00
|
|
|
for x in range(len(game_charge_list)):
|
|
|
|
charges.append(
|
|
|
|
{
|
|
|
|
"orderId": x,
|
|
|
|
"chargeId": game_charge_list[x]["chargeId"],
|
|
|
|
"price": 1,
|
|
|
|
"startDate": "2017-12-05 07:00:00.0",
|
|
|
|
"endDate": "2099-12-31 00:00:00.0",
|
|
|
|
"salePrice": 1,
|
|
|
|
"saleStartDate": "2017-12-05 07:00:00.0",
|
|
|
|
"saleEndDate": "2099-12-31 00:00:00.0",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
return {"length": len(charges), "gameChargeList": charges}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_game_event_api_request(self, data: Dict) -> Dict:
|
|
|
|
game_events = self.data.static.get_enabled_events(self.version)
|
|
|
|
|
2023-03-17 06:16:49 +00:00
|
|
|
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": [],
|
|
|
|
}
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
event_list = []
|
|
|
|
for evt_row in game_events:
|
2023-05-10 19:32:35 +00:00
|
|
|
event_list.append(
|
|
|
|
{
|
|
|
|
"id": evt_row["eventId"],
|
|
|
|
"type": evt_row["type"],
|
|
|
|
# actually use the startDate from the import so it
|
|
|
|
# properly shows all the events when new ones are imported
|
|
|
|
"startDate": datetime.strftime(
|
|
|
|
evt_row["startDate"], "%Y-%m-%d %H:%M:%S"
|
|
|
|
),
|
|
|
|
"endDate": "2099-12-31 00:00:00",
|
|
|
|
}
|
|
|
|
)
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"type": data["type"],
|
|
|
|
"length": len(event_list),
|
|
|
|
"gameEventList": event_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_game_idlist_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"type": data["type"], "length": 0, "gameIdlistList": []}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_game_message_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"type": data["type"], "length": "0", "gameMessageList": []}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_game_ranking_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"type": data["type"], "gameRankingList": []}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_game_sale_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"type": data["type"], "length": 0, "gameSaleList": []}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
reboot_start = datetime.strftime(
|
|
|
|
datetime.now() - timedelta(hours=4), self.date_time_format
|
|
|
|
)
|
|
|
|
reboot_end = datetime.strftime(
|
|
|
|
datetime.now() - timedelta(hours=3), self.date_time_format
|
|
|
|
)
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
|
|
|
"gameSetting": {
|
|
|
|
"dataVersion": "1.00.00",
|
|
|
|
"isMaintenance": "false",
|
|
|
|
"requestInterval": 10,
|
|
|
|
"rebootStartTime": reboot_start,
|
|
|
|
"rebootEndTime": reboot_end,
|
|
|
|
"isBackgroundDistribute": "false",
|
|
|
|
"maxCountCharacter": 300,
|
|
|
|
"maxCountItem": 300,
|
|
|
|
"maxCountMusic": 300,
|
|
|
|
},
|
2023-03-09 16:38:58 +00:00
|
|
|
"isDumpUpload": "false",
|
|
|
|
"isAou": "false",
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_activity_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
user_activity_list = self.data.profile.get_profile_activity(
|
|
|
|
data["userId"], data["kind"]
|
|
|
|
)
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
activity_list = []
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
for activity in user_activity_list:
|
|
|
|
tmp = activity._asdict()
|
|
|
|
tmp.pop("user")
|
|
|
|
tmp["id"] = tmp["activityId"]
|
|
|
|
tmp.pop("activityId")
|
|
|
|
activity_list.append(tmp)
|
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
|
|
|
"length": len(activity_list),
|
2023-03-24 17:10:10 +00:00
|
|
|
"kind": int(data["kind"]),
|
2023-03-09 16:38:58 +00:00
|
|
|
"userActivityList": activity_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_character_api_request(self, data: Dict) -> Dict:
|
|
|
|
characters = self.data.item.get_characters(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
if characters is None:
|
2023-05-10 19:32:35 +00:00
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
|
|
|
"length": 0,
|
|
|
|
"nextIndex": -1,
|
|
|
|
"userCharacterList": [],
|
|
|
|
}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
2023-05-10 19:32:35 +00:00
|
|
|
character_list = []
|
|
|
|
next_idx = int(data["nextIndex"])
|
|
|
|
max_ct = int(data["maxCount"])
|
|
|
|
|
|
|
|
for x in range(next_idx, len(characters)):
|
2023-02-17 06:02:21 +00:00
|
|
|
tmp = characters[x]._asdict()
|
|
|
|
tmp.pop("user")
|
|
|
|
tmp.pop("id")
|
2023-05-10 19:32:35 +00:00
|
|
|
character_list.append(tmp)
|
2023-02-17 06:02:21 +00:00
|
|
|
|
2023-05-10 19:32:35 +00:00
|
|
|
if len(character_list) >= max_ct:
|
2023-02-17 06:02:21 +00:00
|
|
|
break
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-05-10 19:32:35 +00:00
|
|
|
if len(characters) >= next_idx + max_ct:
|
|
|
|
next_idx += max_ct
|
|
|
|
else:
|
|
|
|
next_idx = -1
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-05-10 19:32:35 +00:00
|
|
|
"length": len(character_list),
|
2023-03-09 16:38:58 +00:00
|
|
|
"nextIndex": next_idx,
|
2023-05-10 19:32:35 +00:00
|
|
|
"userCharacterList": character_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_charge_api_request(self, data: Dict) -> Dict:
|
|
|
|
user_charge_list = self.data.profile.get_profile_charge(data["userId"])
|
|
|
|
|
|
|
|
charge_list = []
|
|
|
|
for charge in user_charge_list:
|
|
|
|
tmp = charge._asdict()
|
|
|
|
tmp.pop("id")
|
|
|
|
tmp.pop("user")
|
|
|
|
charge_list.append(tmp)
|
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"length": len(charge_list),
|
2023-03-09 16:38:58 +00:00
|
|
|
"userChargeList": charge_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_course_api_request(self, data: Dict) -> Dict:
|
|
|
|
user_course_list = self.data.score.get_courses(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
if user_course_list is None:
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"length": 0,
|
2023-03-09 16:38:58 +00:00
|
|
|
"nextIndex": -1,
|
|
|
|
"userCourseList": [],
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
course_list = []
|
|
|
|
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()
|
|
|
|
tmp.pop("user")
|
|
|
|
tmp.pop("id")
|
|
|
|
course_list.append(tmp)
|
|
|
|
|
|
|
|
if len(user_course_list) >= max_ct:
|
|
|
|
break
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-05-10 19:32:35 +00:00
|
|
|
if len(user_course_list) >= next_idx + max_ct:
|
|
|
|
next_idx += max_ct
|
2023-02-17 06:02:21 +00:00
|
|
|
else:
|
|
|
|
next_idx = -1
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"length": len(course_list),
|
2023-03-09 16:38:58 +00:00
|
|
|
"nextIndex": next_idx,
|
|
|
|
"userCourseList": course_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_data_api_request(self, data: Dict) -> Dict:
|
|
|
|
p = self.data.profile.get_profile_data(data["userId"], self.version)
|
2023-03-09 16:38:58 +00:00
|
|
|
if p is None:
|
|
|
|
return {}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
profile = p._asdict()
|
|
|
|
profile.pop("id")
|
|
|
|
profile.pop("user")
|
|
|
|
profile.pop("version")
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"userId": data["userId"], "userData": profile}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_user_data_ex_api_request(self, data: Dict) -> Dict:
|
|
|
|
p = self.data.profile.get_profile_data_ex(data["userId"], self.version)
|
2023-03-09 16:38:58 +00:00
|
|
|
if p is None:
|
|
|
|
return {}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
profile = p._asdict()
|
|
|
|
profile.pop("id")
|
|
|
|
profile.pop("user")
|
|
|
|
profile.pop("version")
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"userId": data["userId"], "userDataEx": profile}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_user_duel_api_request(self, data: Dict) -> Dict:
|
|
|
|
user_duel_list = self.data.item.get_duels(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
if user_duel_list is None:
|
|
|
|
return {}
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
duel_list = []
|
|
|
|
for duel in user_duel_list:
|
|
|
|
tmp = duel._asdict()
|
|
|
|
tmp.pop("id")
|
|
|
|
tmp.pop("user")
|
|
|
|
duel_list.append(tmp)
|
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"length": len(duel_list),
|
2023-03-09 16:38:58 +00:00
|
|
|
"userDuelList": duel_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_favorite_item_api_request(self, data: Dict) -> Dict:
|
2023-05-10 19:32:35 +00:00
|
|
|
user_fav_item_list = []
|
|
|
|
|
|
|
|
# still needs to be implemented on WebUI
|
|
|
|
# 1: Music, 3: Character
|
|
|
|
fav_list = self.data.item.get_all_favorites(
|
|
|
|
data["userId"], self.version, fav_kind=int(data["kind"])
|
|
|
|
)
|
|
|
|
if fav_list is not None:
|
|
|
|
for fav in fav_list:
|
|
|
|
user_fav_item_list.append({"id": fav["favId"]})
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-05-10 19:32:35 +00:00
|
|
|
"length": len(user_fav_item_list),
|
2023-03-09 16:38:58 +00:00
|
|
|
"kind": data["kind"],
|
|
|
|
"nextIndex": -1,
|
2023-05-10 19:32:35 +00:00
|
|
|
"userFavoriteItemList": user_fav_item_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_favorite_music_api_request(self, data: Dict) -> Dict:
|
|
|
|
"""
|
|
|
|
This is handled via the webui, which we don't have right now
|
|
|
|
"""
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"userId": data["userId"], "length": 0, "userFavoriteMusicList": []}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_user_item_api_request(self, data: Dict) -> Dict:
|
|
|
|
kind = int(int(data["nextIndex"]) / 10000000000)
|
|
|
|
next_idx = int(int(data["nextIndex"]) % 10000000000)
|
|
|
|
user_item_list = self.data.item.get_items(data["userId"], kind)
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
if user_item_list is None or len(user_item_list) == 0:
|
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
|
|
|
"nextIndex": -1,
|
|
|
|
"itemKind": kind,
|
|
|
|
"userItemList": [],
|
|
|
|
}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
2023-07-05 14:47:43 +00:00
|
|
|
items: List[Dict[str, Any]] = []
|
2023-03-09 16:38:58 +00:00
|
|
|
for i in range(next_idx, len(user_item_list)):
|
2023-02-17 06:02:21 +00:00
|
|
|
tmp = user_item_list[i]._asdict()
|
|
|
|
tmp.pop("user")
|
|
|
|
tmp.pop("id")
|
|
|
|
items.append(tmp)
|
|
|
|
if len(items) >= int(data["maxCount"]):
|
|
|
|
break
|
|
|
|
|
|
|
|
xout = kind * 10000000000 + next_idx + len(items)
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
if len(items) < int(data["maxCount"]):
|
2023-05-10 19:32:35 +00:00
|
|
|
next_idx = 0
|
2023-03-09 16:38:58 +00:00
|
|
|
else:
|
2023-05-10 19:32:35 +00:00
|
|
|
next_idx = xout
|
2023-02-17 06:02:21 +00:00
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
2023-05-10 19:32:35 +00:00
|
|
|
"nextIndex": next_idx,
|
2023-03-09 16:38:58 +00:00
|
|
|
"itemKind": kind,
|
|
|
|
"length": len(items),
|
|
|
|
"userItemList": items,
|
|
|
|
}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_user_login_bonus_api_request(self, data: Dict) -> Dict:
|
2023-03-28 16:28:57 +00:00
|
|
|
user_id = data["userId"]
|
|
|
|
user_login_bonus = self.data.item.get_all_login_bonus(user_id, self.version)
|
2023-03-28 16:54:27 +00:00
|
|
|
# ignore the loginBonus request if its disabled in config
|
|
|
|
if user_login_bonus is None or not self.game_cfg.mods.use_login_bonus:
|
2023-03-28 16:28:57 +00:00
|
|
|
return {"userId": user_id, "length": 0, "userLoginBonusList": []}
|
|
|
|
|
|
|
|
user_login_list = []
|
|
|
|
for bonus in user_login_bonus:
|
|
|
|
user_login_list.append(
|
2023-02-17 06:02:21 +00:00
|
|
|
{
|
2023-03-28 16:28:57 +00:00
|
|
|
"presetId": bonus["presetId"],
|
|
|
|
"bonusCount": bonus["bonusCount"],
|
|
|
|
"lastUpdateDate": datetime.strftime(
|
|
|
|
bonus["lastUpdateDate"], "%Y-%m-%d %H:%M:%S"
|
|
|
|
),
|
|
|
|
"isWatched": bonus["isWatched"],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
return {
|
|
|
|
"userId": user_id,
|
|
|
|
"length": len(user_login_list),
|
|
|
|
"userLoginBonusList": user_login_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_map_api_request(self, data: Dict) -> Dict:
|
|
|
|
user_map_list = self.data.item.get_maps(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
if user_map_list is None:
|
|
|
|
return {}
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
map_list = []
|
|
|
|
for map in user_map_list:
|
|
|
|
tmp = map._asdict()
|
|
|
|
tmp.pop("id")
|
|
|
|
tmp.pop("user")
|
|
|
|
map_list.append(tmp)
|
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"length": len(map_list),
|
2023-03-09 16:38:58 +00:00
|
|
|
"userMapList": map_list,
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_music_api_request(self, data: Dict) -> Dict:
|
|
|
|
music_detail = self.data.score.get_scores(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
if music_detail is None:
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
|
|
|
"length": 0,
|
2023-02-17 06:02:21 +00:00
|
|
|
"nextIndex": -1,
|
2023-03-09 16:38:58 +00:00
|
|
|
"userMusicList": [], # 240
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
2023-05-10 19:32:35 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
song_list = []
|
|
|
|
next_idx = int(data["nextIndex"])
|
|
|
|
max_ct = int(data["maxCount"])
|
|
|
|
|
|
|
|
for x in range(next_idx, len(music_detail)):
|
|
|
|
found = False
|
|
|
|
tmp = music_detail[x]._asdict()
|
|
|
|
tmp.pop("user")
|
|
|
|
tmp.pop("id")
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
for song in song_list:
|
|
|
|
if song["userMusicDetailList"][0]["musicId"] == tmp["musicId"]:
|
|
|
|
found = True
|
|
|
|
song["userMusicDetailList"].append(tmp)
|
|
|
|
song["length"] = len(song["userMusicDetailList"])
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if not found:
|
2023-03-09 16:38:58 +00:00
|
|
|
song_list.append({"length": 1, "userMusicDetailList": [tmp]})
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if len(song_list) >= max_ct:
|
|
|
|
break
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-05-10 19:32:35 +00:00
|
|
|
if len(song_list) >= next_idx + max_ct:
|
2023-02-17 06:02:21 +00:00
|
|
|
next_idx += max_ct
|
|
|
|
else:
|
2023-05-10 19:32:35 +00:00
|
|
|
next_idx = -1
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
|
|
|
"length": len(song_list),
|
2023-02-17 06:02:21 +00:00
|
|
|
"nextIndex": next_idx,
|
2023-03-09 16:38:58 +00:00
|
|
|
"userMusicList": song_list, # 240
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_option_api_request(self, data: Dict) -> Dict:
|
|
|
|
p = self.data.profile.get_profile_option(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
option = p._asdict()
|
|
|
|
option.pop("id")
|
|
|
|
option.pop("user")
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"userId": data["userId"], "userGameOption": option}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_get_user_option_ex_api_request(self, data: Dict) -> Dict:
|
|
|
|
p = self.data.profile.get_profile_option_ex(data["userId"])
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
option = p._asdict()
|
|
|
|
option.pop("id")
|
|
|
|
option.pop("user")
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"userId": data["userId"], "userGameOptionEx": option}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def read_wtf8(self, src):
|
|
|
|
return bytes([ord(c) for c in src]).decode("utf-8")
|
|
|
|
|
|
|
|
def handle_get_user_preview_api_request(self, data: Dict) -> Dict:
|
|
|
|
profile = self.data.profile.get_profile_preview(data["userId"], self.version)
|
2023-03-09 16:38:58 +00:00
|
|
|
if profile is None:
|
|
|
|
return None
|
|
|
|
profile_character = self.data.item.get_character(
|
|
|
|
data["userId"], profile["characterId"]
|
|
|
|
)
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if profile_character is None:
|
|
|
|
chara = {}
|
|
|
|
else:
|
|
|
|
chara = profile_character._asdict()
|
|
|
|
chara.pop("id")
|
|
|
|
chara.pop("user")
|
|
|
|
|
|
|
|
return {
|
2023-03-09 16:38:58 +00:00
|
|
|
"userId": data["userId"],
|
|
|
|
# Current Login State
|
2023-02-17 06:02:21 +00:00
|
|
|
"isLogin": False,
|
|
|
|
"lastLoginDate": profile["lastPlayDate"],
|
|
|
|
# User Profile
|
|
|
|
"userName": profile["userName"],
|
|
|
|
"reincarnationNum": profile["reincarnationNum"],
|
|
|
|
"level": profile["level"],
|
|
|
|
"exp": profile["exp"],
|
|
|
|
"playerRating": profile["playerRating"],
|
|
|
|
"lastGameId": profile["lastGameId"],
|
|
|
|
"lastRomVersion": profile["lastRomVersion"],
|
|
|
|
"lastDataVersion": profile["lastDataVersion"],
|
2023-03-09 16:38:58 +00:00
|
|
|
"lastPlayDate": profile["lastPlayDate"],
|
|
|
|
"trophyId": profile["trophyId"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"nameplateId": profile["nameplateId"],
|
|
|
|
# Current Selected Character
|
|
|
|
"userCharacter": chara,
|
|
|
|
# User Game Options
|
2023-03-09 16:38:58 +00:00
|
|
|
"playerLevel": profile["playerLevel"],
|
|
|
|
"rating": profile["rating"],
|
2023-02-17 06:02:21 +00:00
|
|
|
"headphone": profile["headphone"],
|
2023-03-24 17:10:10 +00:00
|
|
|
"chargeState": 1,
|
2023-02-17 06:02:21 +00:00
|
|
|
"userNameEx": profile["userName"],
|
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_recent_rating_api_request(self, data: Dict) -> Dict:
|
2023-03-24 17:10:10 +00:00
|
|
|
recent_rating_list = self.data.profile.get_profile_recent_rating(data["userId"])
|
|
|
|
if recent_rating_list is None:
|
2023-02-17 06:02:21 +00:00
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
|
|
|
"length": 0,
|
|
|
|
"userRecentRatingList": [],
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
2023-03-24 17:10:10 +00:00
|
|
|
"length": len(recent_rating_list["recentRating"]),
|
|
|
|
"userRecentRatingList": recent_rating_list["recentRating"],
|
2023-02-17 06:02:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_region_api_request(self, data: Dict) -> Dict:
|
|
|
|
# TODO: Region
|
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
|
|
|
"length": 0,
|
|
|
|
"userRegionList": [],
|
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_user_team_api_request(self, data: Dict) -> Dict:
|
2023-03-24 17:10:10 +00:00
|
|
|
# TODO: use the database "chuni_profile_team" with a GUI
|
|
|
|
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"],
|
|
|
|
},
|
|
|
|
}
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
def handle_get_team_course_setting_api_request(self, data: Dict) -> Dict:
|
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
|
|
|
"length": 0,
|
|
|
|
"nextIndex": 0,
|
|
|
|
"teamCourseSettingList": [],
|
|
|
|
}
|
|
|
|
|
|
|
|
def handle_get_team_course_rule_api_request(self, data: Dict) -> Dict:
|
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
|
|
|
"length": 0,
|
|
|
|
"nextIndex": 0,
|
|
|
|
"teamCourseRuleList": [],
|
|
|
|
}
|
|
|
|
|
|
|
|
def handle_upsert_user_all_api_request(self, data: Dict) -> Dict:
|
|
|
|
upsert = data["upsertUserAll"]
|
|
|
|
user_id = data["userId"]
|
|
|
|
|
|
|
|
if "userData" in upsert:
|
|
|
|
try:
|
2023-03-09 16:38:58 +00:00
|
|
|
upsert["userData"][0]["userName"] = self.read_wtf8(
|
|
|
|
upsert["userData"][0]["userName"]
|
|
|
|
)
|
2023-07-16 20:58:34 +00:00
|
|
|
except Exception:
|
2023-03-09 16:38:58 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
self.data.profile.put_profile_data(
|
|
|
|
user_id, self.version, upsert["userData"][0]
|
|
|
|
)
|
2023-05-10 19:32:35 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userDataEx" in upsert:
|
2023-03-09 16:38:58 +00:00
|
|
|
self.data.profile.put_profile_data_ex(
|
|
|
|
user_id, self.version, upsert["userDataEx"][0]
|
|
|
|
)
|
2023-05-10 19:32:35 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userGameOption" in upsert:
|
|
|
|
self.data.profile.put_profile_option(user_id, upsert["userGameOption"][0])
|
2023-05-10 19:32:35 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userGameOptionEx" in upsert:
|
2023-03-09 16:38:58 +00:00
|
|
|
self.data.profile.put_profile_option_ex(
|
|
|
|
user_id, upsert["userGameOptionEx"][0]
|
|
|
|
)
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userRecentRatingList" in upsert:
|
2023-03-09 16:38:58 +00:00
|
|
|
self.data.profile.put_profile_recent_rating(
|
|
|
|
user_id, upsert["userRecentRatingList"]
|
|
|
|
)
|
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userCharacterList" in upsert:
|
|
|
|
for character in upsert["userCharacterList"]:
|
|
|
|
self.data.item.put_character(user_id, character)
|
|
|
|
|
|
|
|
if "userMapList" in upsert:
|
|
|
|
for map in upsert["userMapList"]:
|
|
|
|
self.data.item.put_map(user_id, map)
|
|
|
|
|
|
|
|
if "userCourseList" in upsert:
|
|
|
|
for course in upsert["userCourseList"]:
|
|
|
|
self.data.score.put_course(user_id, course)
|
|
|
|
|
|
|
|
if "userDuelList" in upsert:
|
|
|
|
for duel in upsert["userDuelList"]:
|
|
|
|
self.data.item.put_duel(user_id, duel)
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userItemList" in upsert:
|
|
|
|
for item in upsert["userItemList"]:
|
|
|
|
self.data.item.put_item(user_id, item)
|
|
|
|
|
|
|
|
if "userActivityList" in upsert:
|
|
|
|
for activity in upsert["userActivityList"]:
|
|
|
|
self.data.profile.put_profile_activity(user_id, activity)
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userChargeList" in upsert:
|
|
|
|
for charge in upsert["userChargeList"]:
|
|
|
|
self.data.profile.put_profile_charge(user_id, charge)
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userMusicDetailList" in upsert:
|
|
|
|
for song in upsert["userMusicDetailList"]:
|
|
|
|
self.data.score.put_score(user_id, song)
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userPlaylogList" in upsert:
|
|
|
|
for playlog in upsert["userPlaylogList"]:
|
2023-05-10 19:32:35 +00:00
|
|
|
# convert the player names to utf-8
|
|
|
|
playlog["playedUserName1"] = self.read_wtf8(playlog["playedUserName1"])
|
|
|
|
playlog["playedUserName2"] = self.read_wtf8(playlog["playedUserName2"])
|
|
|
|
playlog["playedUserName3"] = self.read_wtf8(playlog["playedUserName3"])
|
2023-02-17 06:02:21 +00:00
|
|
|
self.data.score.put_playlog(user_id, playlog)
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userTeamPoint" in upsert:
|
|
|
|
# TODO: team stuff
|
|
|
|
pass
|
2023-03-09 16:38:58 +00:00
|
|
|
|
2023-02-17 06:02:21 +00:00
|
|
|
if "userMapAreaList" in upsert:
|
|
|
|
for map_area in upsert["userMapAreaList"]:
|
|
|
|
self.data.item.put_map_area(user_id, map_area)
|
|
|
|
|
|
|
|
if "userOverPowerList" in upsert:
|
|
|
|
for overpower in upsert["userOverPowerList"]:
|
|
|
|
self.data.profile.put_profile_overpower(user_id, overpower)
|
|
|
|
|
|
|
|
if "userEmoneyList" in upsert:
|
|
|
|
for emoney in upsert["userEmoneyList"]:
|
|
|
|
self.data.profile.put_profile_emoney(user_id, emoney)
|
|
|
|
|
2023-03-28 16:28:57 +00:00
|
|
|
if "userLoginBonusList" in upsert:
|
|
|
|
for login in upsert["userLoginBonusList"]:
|
|
|
|
self.data.item.put_login_bonus(
|
|
|
|
user_id, self.version, login["presetId"], isWatched=True
|
|
|
|
)
|
|
|
|
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_upsert_user_chargelog_api_request(self, data: Dict) -> Dict:
|
2023-03-24 17:10:10 +00:00
|
|
|
# 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"])
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_upsert_client_develop_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_upsert_client_error_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_upsert_client_setting_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-02-17 06:02:21 +00:00
|
|
|
|
|
|
|
def handle_upsert_client_testmode_api_request(self, data: Dict) -> Dict:
|
2023-03-09 16:38:58 +00:00
|
|
|
return {"returnCode": "1"}
|
2023-03-15 20:03:22 +00:00
|
|
|
|
|
|
|
def handle_get_user_net_battle_data_api_request(self, data: Dict) -> Dict:
|
|
|
|
return {
|
|
|
|
"userId": data["userId"],
|
2023-03-24 17:10:10 +00:00
|
|
|
"userNetBattleData": {"recentNBSelectMusicList": []},
|
|
|
|
}
|