Merge branch 'develop' into idac
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
from titles.chuni.index import ChuniServlet
|
||||
from titles.chuni.const import ChuniConstants
|
||||
from titles.chuni.database import ChuniData
|
||||
from titles.chuni.read import ChuniReader
|
||||
from .index import ChuniServlet
|
||||
from .const import ChuniConstants
|
||||
from .database import ChuniData
|
||||
from .read import ChuniReader
|
||||
from .frontend import ChuniFrontend
|
||||
|
||||
index = ChuniServlet
|
||||
database = ChuniData
|
||||
reader = ChuniReader
|
||||
frontend = ChuniFrontend
|
||||
game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW, ChuniConstants.GAME_CODE_INT]
|
||||
current_schema_version = 5
|
||||
+2
-2
@@ -11,7 +11,7 @@ class ChuniAir(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_AIR
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.10.00"
|
||||
return ret
|
||||
|
||||
@@ -11,7 +11,7 @@ class ChuniAirPlus(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_AIR_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.15.00"
|
||||
return ret
|
||||
|
||||
@@ -13,7 +13,7 @@ class ChuniAmazon(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_AMAZON
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.30.00"
|
||||
return ret
|
||||
|
||||
@@ -13,7 +13,7 @@ class ChuniAmazonPlus(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_AMAZON_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.35.00"
|
||||
return ret
|
||||
|
||||
+105
-107
@@ -22,7 +22,7 @@ class ChuniBase:
|
||||
self.game = ChuniConstants.GAME_CODE
|
||||
self.version = ChuniConstants.VER_CHUNITHM
|
||||
|
||||
def handle_game_login_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_game_login_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
Handles the login bonus logic, required for the game because
|
||||
getUserLoginBonus gets called after getUserItem and therefore the
|
||||
@@ -38,20 +38,20 @@ class ChuniBase:
|
||||
return {"returnCode": 1}
|
||||
|
||||
user_id = data["userId"]
|
||||
login_bonus_presets = self.data.static.get_login_bonus_presets(self.version)
|
||||
login_bonus_presets = await 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_login_bonus = await self.data.item.get_login_bonus(
|
||||
user_id, self.version, preset["presetId"]
|
||||
)
|
||||
if user_login_bonus is None:
|
||||
self.data.item.put_login_bonus(
|
||||
await self.data.item.put_login_bonus(
|
||||
user_id, self.version, preset["presetId"]
|
||||
)
|
||||
# yeah i'm lazy
|
||||
user_login_bonus = self.data.item.get_login_bonus(
|
||||
user_login_bonus = await self.data.item.get_login_bonus(
|
||||
user_id, self.version, preset["presetId"]
|
||||
)
|
||||
|
||||
@@ -67,7 +67,7 @@ class ChuniBase:
|
||||
bonus_count = user_login_bonus["bonusCount"] + 1
|
||||
last_update_date = datetime.now()
|
||||
|
||||
all_login_boni = self.data.static.get_login_bonus(
|
||||
all_login_boni = await self.data.static.get_login_bonus(
|
||||
self.version, preset["presetId"]
|
||||
)
|
||||
|
||||
@@ -91,13 +91,13 @@ class ChuniBase:
|
||||
is_finished = True
|
||||
|
||||
# grab the item for the corresponding day
|
||||
login_item = self.data.static.get_login_bonus_by_required_days(
|
||||
login_item = await self.data.static.get_login_bonus_by_required_days(
|
||||
self.version, preset["presetId"], 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(
|
||||
await self.data.item.put_item(
|
||||
user_id,
|
||||
{
|
||||
"itemId": login_item["presentId"],
|
||||
@@ -107,7 +107,7 @@ class ChuniBase:
|
||||
},
|
||||
)
|
||||
|
||||
self.data.item.put_login_bonus(
|
||||
await self.data.item.put_login_bonus(
|
||||
user_id,
|
||||
self.version,
|
||||
preset["presetId"],
|
||||
@@ -119,12 +119,12 @@ class ChuniBase:
|
||||
|
||||
return {"returnCode": 1}
|
||||
|
||||
def handle_game_logout_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_game_logout_api_request(self, data: Dict) -> Dict:
|
||||
# self.data.base.log_event("chuni", "logout", logging.INFO, {"version": self.version, "user": data["userId"]})
|
||||
return {"returnCode": 1}
|
||||
|
||||
def handle_get_game_charge_api_request(self, data: Dict) -> Dict:
|
||||
game_charge_list = self.data.static.get_enabled_charges(self.version)
|
||||
async def handle_get_game_charge_api_request(self, data: Dict) -> Dict:
|
||||
game_charge_list = await self.data.static.get_enabled_charges(self.version)
|
||||
|
||||
if game_charge_list is None or len(game_charge_list) == 0:
|
||||
return {"length": 0, "gameChargeList": []}
|
||||
@@ -145,8 +145,8 @@ class ChuniBase:
|
||||
)
|
||||
return {"length": len(charges), "gameChargeList": charges}
|
||||
|
||||
def handle_get_game_event_api_request(self, data: Dict) -> Dict:
|
||||
game_events = self.data.static.get_enabled_events(self.version)
|
||||
async def handle_get_game_event_api_request(self, data: Dict) -> Dict:
|
||||
game_events = await self.data.static.get_enabled_events(self.version)
|
||||
|
||||
if game_events is None or len(game_events) == 0:
|
||||
self.logger.warning("No enabled events, did you run the reader?")
|
||||
@@ -177,10 +177,10 @@ class ChuniBase:
|
||||
"gameEventList": event_list,
|
||||
}
|
||||
|
||||
def handle_get_game_idlist_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_idlist_api_request(self, data: Dict) -> Dict:
|
||||
return {"type": data["type"], "length": 0, "gameIdlistList": []}
|
||||
|
||||
def handle_get_game_message_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_message_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"type": data["type"],
|
||||
"length": 1,
|
||||
@@ -193,14 +193,14 @@ class ChuniBase:
|
||||
}]
|
||||
}
|
||||
|
||||
def handle_get_game_ranking_api_request(self, data: Dict) -> Dict:
|
||||
rankings = self.data.score.get_rankings(self.version)
|
||||
async def handle_get_game_ranking_api_request(self, data: Dict) -> Dict:
|
||||
rankings = await self.data.score.get_rankings(self.version)
|
||||
return {"type": data["type"], "gameRankingList": rankings}
|
||||
|
||||
def handle_get_game_sale_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_sale_api_request(self, data: Dict) -> Dict:
|
||||
return {"type": data["type"], "length": 0, "gameSaleList": []}
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
# if reboot start/end time is not defined use the default behavior of being a few hours ago
|
||||
if self.core_cfg.title.reboot_start_time == "" or self.core_cfg.title.reboot_end_time == "":
|
||||
reboot_start = datetime.strftime(
|
||||
@@ -240,8 +240,8 @@ class ChuniBase:
|
||||
"isDumpUpload": "false",
|
||||
"isAou": "false",
|
||||
}
|
||||
def handle_get_user_activity_api_request(self, data: Dict) -> Dict:
|
||||
user_activity_list = self.data.profile.get_profile_activity(
|
||||
async def handle_get_user_activity_api_request(self, data: Dict) -> Dict:
|
||||
user_activity_list = await self.data.profile.get_profile_activity(
|
||||
data["userId"], data["kind"]
|
||||
)
|
||||
|
||||
@@ -261,8 +261,8 @@ class ChuniBase:
|
||||
"userActivityList": activity_list,
|
||||
}
|
||||
|
||||
def handle_get_user_character_api_request(self, data: Dict) -> Dict:
|
||||
characters = self.data.item.get_characters(data["userId"])
|
||||
async def handle_get_user_character_api_request(self, data: Dict) -> Dict:
|
||||
characters = await self.data.item.get_characters(data["userId"])
|
||||
if characters is None:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
@@ -296,8 +296,8 @@ class ChuniBase:
|
||||
"userCharacterList": character_list,
|
||||
}
|
||||
|
||||
def handle_get_user_charge_api_request(self, data: Dict) -> Dict:
|
||||
user_charge_list = self.data.profile.get_profile_charge(data["userId"])
|
||||
async def handle_get_user_charge_api_request(self, data: Dict) -> Dict:
|
||||
user_charge_list = await self.data.profile.get_profile_charge(data["userId"])
|
||||
|
||||
charge_list = []
|
||||
for charge in user_charge_list:
|
||||
@@ -312,15 +312,15 @@ class ChuniBase:
|
||||
"userChargeList": charge_list,
|
||||
}
|
||||
|
||||
def handle_get_user_recent_player_api_request(self, data: Dict) -> Dict:
|
||||
async 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"])
|
||||
async def handle_get_user_course_api_request(self, data: Dict) -> Dict:
|
||||
user_course_list = await self.data.score.get_courses(data["userId"])
|
||||
if user_course_list is None:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
@@ -354,8 +354,8 @@ class ChuniBase:
|
||||
"userCourseList": course_list,
|
||||
}
|
||||
|
||||
def handle_get_user_data_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
async def handle_get_user_data_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
if p is None:
|
||||
return {}
|
||||
|
||||
@@ -366,8 +366,8 @@ class ChuniBase:
|
||||
|
||||
return {"userId": data["userId"], "userData": profile}
|
||||
|
||||
def handle_get_user_data_ex_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_data_ex(data["userId"], self.version)
|
||||
async def handle_get_user_data_ex_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_profile_data_ex(data["userId"], self.version)
|
||||
if p is None:
|
||||
return {}
|
||||
|
||||
@@ -378,8 +378,8 @@ class ChuniBase:
|
||||
|
||||
return {"userId": data["userId"], "userDataEx": profile}
|
||||
|
||||
def handle_get_user_duel_api_request(self, data: Dict) -> Dict:
|
||||
user_duel_list = self.data.item.get_duels(data["userId"])
|
||||
async def handle_get_user_duel_api_request(self, data: Dict) -> Dict:
|
||||
user_duel_list = await self.data.item.get_duels(data["userId"])
|
||||
if user_duel_list is None:
|
||||
return {}
|
||||
|
||||
@@ -396,8 +396,8 @@ class ChuniBase:
|
||||
"userDuelList": duel_list,
|
||||
}
|
||||
|
||||
def handle_get_user_rival_data_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_rival(data["rivalId"])
|
||||
async def handle_get_user_rival_data_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_rival(data["rivalId"])
|
||||
if p is None:
|
||||
return {}
|
||||
userRivalData = {
|
||||
@@ -409,14 +409,14 @@ class ChuniBase:
|
||||
"userRivalData": userRivalData
|
||||
}
|
||||
|
||||
def handle_get_user_rival_music_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_rival_music_api_request(self, data: Dict) -> Dict:
|
||||
rival_id = data["rivalId"]
|
||||
next_index = int(data["nextIndex"])
|
||||
max_count = int(data["maxCount"])
|
||||
user_rival_music_list = []
|
||||
|
||||
# Fetch all the rival music entries for the user
|
||||
all_entries = self.data.score.get_rival_music(rival_id)
|
||||
all_entries = await self.data.score.get_rival_music(rival_id)
|
||||
|
||||
# Process the entries based on max_count and nextIndex
|
||||
for music in all_entries:
|
||||
@@ -462,12 +462,12 @@ class ChuniBase:
|
||||
return result
|
||||
|
||||
|
||||
def handle_get_user_favorite_item_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_favorite_item_api_request(self, data: Dict) -> Dict:
|
||||
user_fav_item_list = []
|
||||
|
||||
# still needs to be implemented on WebUI
|
||||
# 1: Music, 2: User, 3: Character
|
||||
fav_list = self.data.item.get_all_favorites(
|
||||
fav_list = await self.data.item.get_all_favorites(
|
||||
data["userId"], self.version, fav_kind=int(data["kind"])
|
||||
)
|
||||
if fav_list is not None:
|
||||
@@ -482,17 +482,17 @@ class ChuniBase:
|
||||
"userFavoriteItemList": user_fav_item_list,
|
||||
}
|
||||
|
||||
def handle_get_user_favorite_music_api_request(self, data: Dict) -> Dict:
|
||||
async 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
|
||||
"""
|
||||
|
||||
return {"userId": data["userId"], "length": 0, "userFavoriteMusicList": []}
|
||||
|
||||
def handle_get_user_item_api_request(self, data: Dict) -> Dict:
|
||||
async 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)
|
||||
user_item_list = await self.data.item.get_items(data["userId"], kind)
|
||||
|
||||
if user_item_list is None or len(user_item_list) == 0:
|
||||
return {
|
||||
@@ -526,9 +526,9 @@ class ChuniBase:
|
||||
"userItemList": items,
|
||||
}
|
||||
|
||||
def handle_get_user_login_bonus_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_login_bonus_api_request(self, data: Dict) -> Dict:
|
||||
user_id = data["userId"]
|
||||
user_login_bonus = self.data.item.get_all_login_bonus(user_id, self.version)
|
||||
user_login_bonus = await 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": []}
|
||||
@@ -552,8 +552,8 @@ class ChuniBase:
|
||||
"userLoginBonusList": user_login_list,
|
||||
}
|
||||
|
||||
def handle_get_user_map_api_request(self, data: Dict) -> Dict:
|
||||
user_map_list = self.data.item.get_maps(data["userId"])
|
||||
async def handle_get_user_map_api_request(self, data: Dict) -> Dict:
|
||||
user_map_list = await self.data.item.get_maps(data["userId"])
|
||||
if user_map_list is None:
|
||||
return {}
|
||||
|
||||
@@ -570,8 +570,8 @@ class ChuniBase:
|
||||
"userMapList": map_list,
|
||||
}
|
||||
|
||||
def handle_get_user_music_api_request(self, data: Dict) -> Dict:
|
||||
music_detail = self.data.score.get_scores(data["userId"])
|
||||
async def handle_get_user_music_api_request(self, data: Dict) -> Dict:
|
||||
music_detail = await self.data.score.get_scores(data["userId"])
|
||||
if music_detail is None:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
@@ -608,16 +608,14 @@ class ChuniBase:
|
||||
if len(song_list) >= max_ct:
|
||||
break
|
||||
|
||||
try:
|
||||
while song_list[-1]["userMusicDetailList"][0]["musicId"] == music_detail[x + 1]["musicId"]:
|
||||
music = music_detail[x + 1]._asdict()
|
||||
music.pop("user")
|
||||
music.pop("id")
|
||||
song_list[-1]["userMusicDetailList"].append(music)
|
||||
song_list[-1]["length"] += 1
|
||||
x += 1
|
||||
except IndexError:
|
||||
pass
|
||||
for songIdx in range(len(song_list)):
|
||||
for recordIdx in range(x+1, len(music_detail)):
|
||||
if song_list[songIdx]["userMusicDetailList"][0]["musicId"] == music_detail[recordIdx]["musicId"]:
|
||||
music = music_detail[recordIdx]._asdict()
|
||||
music.pop("user")
|
||||
music.pop("id")
|
||||
song_list[songIdx]["userMusicDetailList"].append(music)
|
||||
song_list[songIdx]["length"] += 1
|
||||
|
||||
if len(song_list) >= max_ct:
|
||||
next_idx += len(song_list)
|
||||
@@ -631,8 +629,8 @@ class ChuniBase:
|
||||
"userMusicList": song_list, # 240
|
||||
}
|
||||
|
||||
def handle_get_user_option_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_option(data["userId"])
|
||||
async def handle_get_user_option_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_profile_option(data["userId"])
|
||||
|
||||
option = p._asdict()
|
||||
option.pop("id")
|
||||
@@ -640,8 +638,8 @@ class ChuniBase:
|
||||
|
||||
return {"userId": data["userId"], "userGameOption": option}
|
||||
|
||||
def handle_get_user_option_ex_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_option_ex(data["userId"])
|
||||
async def handle_get_user_option_ex_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_profile_option_ex(data["userId"])
|
||||
|
||||
option = p._asdict()
|
||||
option.pop("id")
|
||||
@@ -652,11 +650,11 @@ class ChuniBase:
|
||||
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)
|
||||
async def handle_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile_preview(data["userId"], self.version)
|
||||
if profile is None:
|
||||
return None
|
||||
profile_character = self.data.item.get_character(
|
||||
profile_character = await self.data.item.get_character(
|
||||
data["userId"], profile["characterId"]
|
||||
)
|
||||
|
||||
@@ -694,8 +692,8 @@ class ChuniBase:
|
||||
"userNameEx": profile["userName"],
|
||||
}
|
||||
|
||||
def handle_get_user_recent_rating_api_request(self, data: Dict) -> Dict:
|
||||
recent_rating_list = self.data.profile.get_profile_recent_rating(data["userId"])
|
||||
async def handle_get_user_recent_rating_api_request(self, data: Dict) -> Dict:
|
||||
recent_rating_list = await self.data.profile.get_profile_recent_rating(data["userId"])
|
||||
if recent_rating_list is None:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
@@ -709,7 +707,7 @@ class ChuniBase:
|
||||
"userRecentRatingList": recent_rating_list["recentRating"],
|
||||
}
|
||||
|
||||
def handle_get_user_region_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_region_api_request(self, data: Dict) -> Dict:
|
||||
# TODO: Region
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
@@ -717,22 +715,22 @@ class ChuniBase:
|
||||
"userRegionList": [],
|
||||
}
|
||||
|
||||
def handle_get_user_team_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_team_api_request(self, data: Dict) -> Dict:
|
||||
# Default values
|
||||
team_id = 65535
|
||||
team_name = self.game_cfg.team.team_name
|
||||
team_rank = 0
|
||||
|
||||
# Get user profile
|
||||
profile = self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
profile = await self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
if profile and profile["teamId"]:
|
||||
# Get team by id
|
||||
team = self.data.profile.get_team_by_id(profile["teamId"])
|
||||
team = await self.data.profile.get_team_by_id(profile["teamId"])
|
||||
|
||||
if team:
|
||||
team_id = team["id"]
|
||||
team_name = team["teamName"]
|
||||
team_rank = self.data.profile.get_team_rank(team["id"])
|
||||
team_rank = await self.data.profile.get_team_rank(team["id"])
|
||||
|
||||
# Don't return anything if no team name has been defined for defaults and there is no team set for the player
|
||||
if not profile["teamId"] and team_name == "":
|
||||
@@ -752,7 +750,7 @@ class ChuniBase:
|
||||
},
|
||||
}
|
||||
|
||||
def handle_get_team_course_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_team_course_setting_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 0,
|
||||
@@ -760,7 +758,7 @@ class ChuniBase:
|
||||
"teamCourseSettingList": [],
|
||||
}
|
||||
|
||||
def handle_get_team_course_setting_api_request_proto(self, data: Dict) -> Dict:
|
||||
async def handle_get_team_course_setting_api_request_proto(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 1,
|
||||
@@ -784,7 +782,7 @@ class ChuniBase:
|
||||
],
|
||||
}
|
||||
|
||||
def handle_get_team_course_rule_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_team_course_rule_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 0,
|
||||
@@ -792,7 +790,7 @@ class ChuniBase:
|
||||
"teamCourseRuleList": []
|
||||
}
|
||||
|
||||
def handle_get_team_course_rule_api_request_proto(self, data: Dict) -> Dict:
|
||||
async def handle_get_team_course_rule_api_request_proto(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 1,
|
||||
@@ -809,7 +807,7 @@ class ChuniBase:
|
||||
],
|
||||
}
|
||||
|
||||
def handle_upsert_user_all_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_user_all_api_request(self, data: Dict) -> Dict:
|
||||
upsert = data["upsertUserAll"]
|
||||
user_id = data["userId"]
|
||||
|
||||
@@ -821,58 +819,58 @@ class ChuniBase:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
self.data.profile.put_profile_data(
|
||||
await self.data.profile.put_profile_data(
|
||||
user_id, self.version, upsert["userData"][0]
|
||||
)
|
||||
|
||||
if "userDataEx" in upsert:
|
||||
self.data.profile.put_profile_data_ex(
|
||||
await self.data.profile.put_profile_data_ex(
|
||||
user_id, self.version, upsert["userDataEx"][0]
|
||||
)
|
||||
|
||||
if "userGameOption" in upsert:
|
||||
self.data.profile.put_profile_option(user_id, upsert["userGameOption"][0])
|
||||
await self.data.profile.put_profile_option(user_id, upsert["userGameOption"][0])
|
||||
|
||||
if "userGameOptionEx" in upsert:
|
||||
self.data.profile.put_profile_option_ex(
|
||||
await self.data.profile.put_profile_option_ex(
|
||||
user_id, upsert["userGameOptionEx"][0]
|
||||
)
|
||||
if "userRecentRatingList" in upsert:
|
||||
self.data.profile.put_profile_recent_rating(
|
||||
await self.data.profile.put_profile_recent_rating(
|
||||
user_id, upsert["userRecentRatingList"]
|
||||
)
|
||||
|
||||
if "userCharacterList" in upsert:
|
||||
for character in upsert["userCharacterList"]:
|
||||
self.data.item.put_character(user_id, character)
|
||||
await 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)
|
||||
await 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)
|
||||
await 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)
|
||||
await self.data.item.put_duel(user_id, duel)
|
||||
|
||||
if "userItemList" in upsert:
|
||||
for item in upsert["userItemList"]:
|
||||
self.data.item.put_item(user_id, item)
|
||||
await 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)
|
||||
await self.data.profile.put_profile_activity(user_id, activity)
|
||||
|
||||
if "userChargeList" in upsert:
|
||||
for charge in upsert["userChargeList"]:
|
||||
self.data.profile.put_profile_charge(user_id, charge)
|
||||
await self.data.profile.put_profile_charge(user_id, charge)
|
||||
|
||||
if "userMusicDetailList" in upsert:
|
||||
for song in upsert["userMusicDetailList"]:
|
||||
self.data.score.put_score(user_id, song)
|
||||
await self.data.score.put_score(user_id, song)
|
||||
|
||||
if "userPlaylogList" in upsert:
|
||||
for playlog in upsert["userPlaylogList"]:
|
||||
@@ -883,7 +881,7 @@ class ChuniBase:
|
||||
playlog["playedUserName2"] = self.read_wtf8(playlog["playedUserName2"])
|
||||
if playlog["playedUserName3"] is not None:
|
||||
playlog["playedUserName3"] = self.read_wtf8(playlog["playedUserName3"])
|
||||
self.data.score.put_playlog(user_id, playlog, self.version)
|
||||
await self.data.score.put_playlog(user_id, playlog, self.version)
|
||||
|
||||
if "userTeamPoint" in upsert:
|
||||
team_points = upsert["userTeamPoint"]
|
||||
@@ -891,7 +889,7 @@ class ChuniBase:
|
||||
for tp in team_points:
|
||||
if tp["teamId"] != '65535':
|
||||
# Fetch the current team data
|
||||
current_team = self.data.profile.get_team_by_id(tp["teamId"])
|
||||
current_team = await self.data.profile.get_team_by_id(tp["teamId"])
|
||||
|
||||
# Calculate the new teamPoint
|
||||
new_team_point = int(tp["teamPoint"]) + current_team["teamPoint"]
|
||||
@@ -902,24 +900,24 @@ class ChuniBase:
|
||||
}
|
||||
|
||||
# Update the team data
|
||||
self.data.profile.update_team(tp["teamId"], team_data)
|
||||
await self.data.profile.update_team(tp["teamId"], team_data)
|
||||
except:
|
||||
pass # Probably a better way to catch if the team is not set yet (new profiles), but let's just pass
|
||||
if "userMapAreaList" in upsert:
|
||||
for map_area in upsert["userMapAreaList"]:
|
||||
self.data.item.put_map_area(user_id, map_area)
|
||||
await 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)
|
||||
await 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)
|
||||
await self.data.profile.put_profile_emoney(user_id, emoney)
|
||||
|
||||
if "userLoginBonusList" in upsert:
|
||||
for login in upsert["userLoginBonusList"]:
|
||||
self.data.item.put_login_bonus(
|
||||
await self.data.item.put_login_bonus(
|
||||
user_id, self.version, login["presetId"], isWatched=True
|
||||
)
|
||||
|
||||
@@ -929,28 +927,28 @@ class ChuniBase:
|
||||
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_upsert_user_chargelog_api_request(self, data: Dict) -> Dict:
|
||||
async 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"])
|
||||
await self.data.profile.put_profile_charge(data["userId"], data["userCharge"])
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_upsert_client_develop_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_develop_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_upsert_client_error_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_error_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_upsert_client_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_setting_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_upsert_client_testmode_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_testmode_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_get_user_net_battle_data_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_net_battle_data_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"userNetBattleData": {"recentNBSelectMusicList": []},
|
||||
|
||||
@@ -89,6 +89,27 @@ class ChuniCryptoConfig:
|
||||
self.__config, "chuni", "crypto", "encrypted_only", default=False
|
||||
)
|
||||
|
||||
class ChuniMatchingConfig:
|
||||
def __init__(self, parent_config: "ChuniConfig") -> None:
|
||||
self.__config = parent_config
|
||||
|
||||
@property
|
||||
def enable(self) -> bool:
|
||||
return CoreConfig.get_config_field(
|
||||
self.__config, "chuni", "matching", "enable", default=False
|
||||
)
|
||||
|
||||
@property
|
||||
def match_time_limit(self) -> int:
|
||||
return CoreConfig.get_config_field(
|
||||
self.__config, "chuni", "matching", "match_time_limit", default=60
|
||||
)
|
||||
|
||||
@property
|
||||
def match_error_limit(self) -> int:
|
||||
return CoreConfig.get_config_field(
|
||||
self.__config, "chuni", "matching", "match_error_limit", default=9999
|
||||
)
|
||||
|
||||
class ChuniConfig(dict):
|
||||
def __init__(self) -> None:
|
||||
@@ -97,3 +118,4 @@ class ChuniConfig(dict):
|
||||
self.mods = ChuniModsConfig(self)
|
||||
self.version = ChuniVersionConfig(self)
|
||||
self.crypto = ChuniCryptoConfig(self)
|
||||
self.matching = ChuniMatchingConfig(self)
|
||||
|
||||
@@ -13,7 +13,7 @@ class ChuniCrystal(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_CRYSTAL
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.40.00"
|
||||
return ret
|
||||
|
||||
@@ -13,7 +13,7 @@ class ChuniCrystalPlus(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_CRYSTAL_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.45.00"
|
||||
return ret
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
from typing import List
|
||||
from starlette.routing import Route
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import Response, RedirectResponse
|
||||
from os import path
|
||||
import yaml
|
||||
import jinja2
|
||||
|
||||
from core.frontend import FE_Base, UserSession
|
||||
from core.config import CoreConfig
|
||||
from .database import ChuniData
|
||||
from .config import ChuniConfig
|
||||
from .const import ChuniConstants
|
||||
|
||||
|
||||
class ChuniFrontend(FE_Base):
|
||||
def __init__(
|
||||
self, cfg: CoreConfig, environment: jinja2.Environment, cfg_dir: str
|
||||
) -> None:
|
||||
super().__init__(cfg, environment)
|
||||
self.data = ChuniData(cfg)
|
||||
self.game_cfg = ChuniConfig()
|
||||
if path.exists(f"{cfg_dir}/{ChuniConstants.CONFIG_NAME}"):
|
||||
self.game_cfg.update(
|
||||
yaml.safe_load(open(f"{cfg_dir}/{ChuniConstants.CONFIG_NAME}"))
|
||||
)
|
||||
self.nav_name = "Chunithm"
|
||||
|
||||
def get_routes(self) -> List[Route]:
|
||||
return [
|
||||
Route("/", self.render_GET, methods=['GET']),
|
||||
Route("/update.name", self.update_name, methods=['POST']),
|
||||
]
|
||||
|
||||
async def render_GET(self, request: Request) -> bytes:
|
||||
template = self.environment.get_template(
|
||||
"titles/chuni/templates/chuni_index.jinja"
|
||||
)
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
usr_sesh = UserSession()
|
||||
|
||||
return Response(template.render(
|
||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||
game_list=self.environment.globals["game_list"],
|
||||
sesh=vars(usr_sesh)
|
||||
), media_type="text/html; charset=utf-8")
|
||||
|
||||
async def update_name(self, request: Request) -> bytes:
|
||||
usr_sesh = self.validate_session(request)
|
||||
if not usr_sesh:
|
||||
return RedirectResponse("/gate/", 303)
|
||||
|
||||
new_name: str = request.query_params.get('new_name', '')
|
||||
new_name_full = ""
|
||||
|
||||
if not new_name:
|
||||
return RedirectResponse("/gate/?e=4", 303)
|
||||
|
||||
if len(new_name) > 8:
|
||||
return RedirectResponse("/gate/?e=8", 303)
|
||||
|
||||
for x in new_name: # FIXME: This will let some invalid characters through atm
|
||||
o = ord(x)
|
||||
try:
|
||||
if o == 0x20:
|
||||
new_name_full += chr(0x3000)
|
||||
elif o < 0x7F and o > 0x20:
|
||||
new_name_full += chr(o + 0xFEE0)
|
||||
elif o <= 0x7F:
|
||||
self.logger.warn(f"Invalid ascii character {o:02X}")
|
||||
return RedirectResponse("/gate/?e=4", 303)
|
||||
else:
|
||||
new_name_full += x
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Something went wrong parsing character {o:04X} - {e}")
|
||||
return RedirectResponse("/gate/?e=4", 303)
|
||||
|
||||
if not await self.data.profile.update_name(usr_sesh, new_name_full):
|
||||
return RedirectResponse("/gate/?e=999", 303)
|
||||
|
||||
return RedirectResponse("/gate/?s=1", 303)
|
||||
+28
-30
@@ -1,4 +1,6 @@
|
||||
from twisted.web.http import Request
|
||||
from starlette.requests import Request
|
||||
from starlette.routing import Route
|
||||
from starlette.responses import Response
|
||||
import logging, coloredlogs
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
import zlib
|
||||
@@ -33,7 +35,6 @@ from .newplus import ChuniNewPlus
|
||||
from .sun import ChuniSun
|
||||
from .sunplus import ChuniSunPlus
|
||||
|
||||
|
||||
class ChuniServlet(BaseServlet):
|
||||
def __init__(self, core_cfg: CoreConfig, cfg_dir: str) -> None:
|
||||
super().__init__(core_cfg, cfg_dir)
|
||||
@@ -124,15 +125,6 @@ class ChuniServlet(BaseServlet):
|
||||
f"Hashed v{version} method {method_fixed} with {bytes.fromhex(keys[2])} to get {hash.hex()}"
|
||||
)
|
||||
|
||||
def get_endpoint_matchers(self) -> Tuple[List[Tuple[str, str, Dict]], List[Tuple[str, str, Dict]]]:
|
||||
return (
|
||||
[],
|
||||
[
|
||||
("render_POST", "/{game}/{version}/ChuniServlet/{endpoint}", {}),
|
||||
("render_POST", "/{game}/{version}/ChuniServlet/MatchingServer/{endpoint}", {})
|
||||
]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def is_game_enabled(
|
||||
cls, game_code: str, core_cfg: CoreConfig, cfg_dir: str
|
||||
@@ -150,19 +142,25 @@ 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_code}/{game_ver}/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.server.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_code}/{game_ver}/", self.core_cfg.server.hostname)
|
||||
|
||||
return (f"http://{self.core_cfg.title.hostname}/{game_code}/{game_ver}/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.server.hostname}/{game_code}/{game_ver}/", self.core_cfg.server.hostname)
|
||||
|
||||
def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
endpoint = matchers['endpoint']
|
||||
version = int(matchers['version'])
|
||||
game_code = matchers['game']
|
||||
def get_routes(self) -> List[Route]:
|
||||
return [
|
||||
Route("/{game:str}/{version:int}/ChuniServlet/{endpoint:str}", self.render_POST, methods=['POST']),
|
||||
Route("/{game:str}/{version:int}/ChuniServlet/MatchingServer/{endpoint:str}", self.render_POST, methods=['POST']),
|
||||
]
|
||||
|
||||
async def render_POST(self, request: Request) -> bytes:
|
||||
endpoint: str = request.path_params.get('endpoint')
|
||||
version: int = request.path_params.get('version')
|
||||
game_code: str = request.path_params.get('game')
|
||||
|
||||
if endpoint.lower() == "ping":
|
||||
return zlib.compress(b'{"returnCode": "1"}')
|
||||
return Response(zlib.compress(b'{"returnCode": "1"}'))
|
||||
|
||||
req_raw = request.content.getvalue()
|
||||
req_raw = await request.body()
|
||||
|
||||
encrtped = False
|
||||
internal_ver = 0
|
||||
@@ -201,7 +199,7 @@ class ChuniServlet(BaseServlet):
|
||||
internal_ver = ChuniConstants.VER_CHUNITHM_SUN_PLUS
|
||||
elif game_code == "SDGS": # Int
|
||||
if version < 110: # SUPERSTAR
|
||||
internal_ver = ChuniConstants.PARADISE
|
||||
internal_ver = ChuniConstants.VER_CHUNITHM_PARADISE # FIXME: Not sure what was intended to go here? was just "PARADISE"
|
||||
elif version >= 110 and version < 115: # NEW
|
||||
internal_ver = ChuniConstants.VER_CHUNITHM_NEW
|
||||
elif version >= 115 and version < 120: # NEW PLUS!!
|
||||
@@ -216,20 +214,20 @@ class ChuniServlet(BaseServlet):
|
||||
# doing encrypted. The likelyhood of false positives is low but
|
||||
# technically not 0
|
||||
if internal_ver < ChuniConstants.VER_CHUNITHM_NEW:
|
||||
endpoint = request.getHeader("User-Agent").split("#")[0]
|
||||
endpoint = request.headers.get("User-Agent").split("#")[0]
|
||||
|
||||
else:
|
||||
if internal_ver not in self.hash_table:
|
||||
self.logger.error(
|
||||
f"v{version} does not support encryption or no keys entered"
|
||||
)
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
elif endpoint.lower() not in self.hash_table[internal_ver]:
|
||||
self.logger.error(
|
||||
f"No hash found for v{version} endpoint {endpoint}"
|
||||
)
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
endpoint = self.hash_table[internal_ver][endpoint.lower()]
|
||||
|
||||
@@ -246,7 +244,7 @@ class ChuniServlet(BaseServlet):
|
||||
self.logger.error(
|
||||
f"Failed to decrypt v{version} request to {endpoint} -> {e}"
|
||||
)
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
encrtped = True
|
||||
|
||||
@@ -258,7 +256,7 @@ class ChuniServlet(BaseServlet):
|
||||
self.logger.error(
|
||||
f"Unencrypted v{version} {endpoint} request, but config is set to encrypted only: {req_raw}"
|
||||
)
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
try:
|
||||
unzip = zlib.decompress(req_raw)
|
||||
@@ -267,7 +265,7 @@ class ChuniServlet(BaseServlet):
|
||||
self.logger.error(
|
||||
f"Failed to decompress v{version} {endpoint} request -> {e}"
|
||||
)
|
||||
return b""
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
req_data = json.loads(unzip)
|
||||
|
||||
@@ -285,11 +283,11 @@ class ChuniServlet(BaseServlet):
|
||||
else:
|
||||
try:
|
||||
handler = getattr(handler_cls, func_to_find)
|
||||
resp = handler(req_data)
|
||||
resp = await handler(req_data)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error handling v{version} method {endpoint} - {e}")
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
if resp == None:
|
||||
resp = {"returnCode": 1}
|
||||
@@ -299,7 +297,7 @@ class ChuniServlet(BaseServlet):
|
||||
zipped = zlib.compress(json.dumps(resp, ensure_ascii=False).encode("utf-8"))
|
||||
|
||||
if not encrtped:
|
||||
return zipped
|
||||
return Response(zipped)
|
||||
|
||||
padded = pad(zipped, 16)
|
||||
|
||||
@@ -309,4 +307,4 @@ class ChuniServlet(BaseServlet):
|
||||
bytes.fromhex(self.game_cfg.crypto.keys[internal_ver][1]),
|
||||
)
|
||||
|
||||
return crypt.encrypt(padded)
|
||||
return Response(crypt.encrypt(padded))
|
||||
+87
-73
@@ -5,12 +5,12 @@ from typing import Dict
|
||||
|
||||
import pytz
|
||||
from core.config import CoreConfig
|
||||
from core.utils import Utils
|
||||
from titles.chuni.const import ChuniConstants
|
||||
from titles.chuni.database import ChuniData
|
||||
from titles.chuni.base import ChuniBase
|
||||
from titles.chuni.config import ChuniConfig
|
||||
|
||||
|
||||
class ChuniNew(ChuniBase):
|
||||
ITEM_TYPE = {"character": 20, "story": 21, "card": 22}
|
||||
|
||||
@@ -22,8 +22,18 @@ class ChuniNew(ChuniBase):
|
||||
self.logger = logging.getLogger("chuni")
|
||||
self.game = ChuniConstants.GAME_CODE
|
||||
self.version = ChuniConstants.VER_CHUNITHM_NEW
|
||||
|
||||
def _interal_ver_to_intver(self) -> str:
|
||||
if self.version == ChuniConstants.VER_CHUNITHM_NEW:
|
||||
return "200"
|
||||
if self.version == ChuniConstants.VER_CHUNITHM_NEW_PLUS:
|
||||
return "205"
|
||||
if self.version == ChuniConstants.VER_CHUNITHM_SUN:
|
||||
return "210"
|
||||
if self.version == ChuniConstants.VER_CHUNITHM_SUN_PLUS:
|
||||
return "215"
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
# use UTC time and convert it to JST time by adding +9
|
||||
# matching therefore starts one hour before and lasts for 8 hours
|
||||
match_start = datetime.strftime(
|
||||
@@ -55,6 +65,7 @@ class ChuniNew(ChuniBase):
|
||||
# create strings for use in gameSetting
|
||||
reboot_start = reboot_start_time.strftime(self.date_time_format)
|
||||
reboot_end = reboot_end_time.strftime(self.date_time_format)
|
||||
t_port = Utils.get_title_port(self.core_cfg)
|
||||
return {
|
||||
"gameSetting": {
|
||||
"isMaintenance": False,
|
||||
@@ -67,31 +78,31 @@ class ChuniNew(ChuniBase):
|
||||
"maxCountMusic": 300,
|
||||
"matchStartTime": match_start,
|
||||
"matchEndTime": match_end,
|
||||
"matchTimeLimit": 60,
|
||||
"matchErrorLimit": 9999,
|
||||
"matchTimeLimit": self.game_cfg.matching.match_time_limit,
|
||||
"matchErrorLimit": self.game_cfg.matching.match_error_limit,
|
||||
"romVersion": self.game_cfg.version.version(self.version)["rom"],
|
||||
"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/",
|
||||
"matchingUriX": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
||||
"matchingUri": f"http://{self.core_cfg.server.hostname}:{t_port}/SDHD/{self._interal_ver_to_intver()}/ChuniServlet/",
|
||||
"matchingUriX": f"http://{self.core_cfg.server.hostname}:{t_port}/SDHD/{self._interal_ver_to_intver()}/ChuniServlet/",
|
||||
# might be really important for online battle to connect the cabs via UDP port 50201
|
||||
"udpHolePunchUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
||||
"reflectorUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
|
||||
"udpHolePunchUri": f"http://{self.core_cfg.server.hostname}:{self.core_cfg.server.port}/SDHD/{self._interal_ver_to_intver()}/ChuniServlet/",
|
||||
"reflectorUri": f"http://{self.core_cfg.server.hostname}:{self.core_cfg.server.port}/SDHD/{self._interal_ver_to_intver()}/ChuniServlet/",
|
||||
},
|
||||
"isDumpUpload": False,
|
||||
"isAou": False,
|
||||
}
|
||||
|
||||
def handle_remove_token_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_remove_token_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_delete_token_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_delete_token_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_create_token_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_create_token_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_get_user_map_area_api_request(self, data: Dict) -> Dict:
|
||||
user_map_areas = self.data.item.get_map_areas(data["userId"])
|
||||
async def handle_get_user_map_area_api_request(self, data: Dict) -> Dict:
|
||||
user_map_areas = await self.data.item.get_map_areas(data["userId"])
|
||||
|
||||
map_areas = []
|
||||
for map_area in user_map_areas:
|
||||
@@ -102,14 +113,14 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
return {"userId": data["userId"], "userMapAreaList": map_areas}
|
||||
|
||||
def handle_get_user_symbol_chat_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_symbol_chat_setting_api_request(self, data: Dict) -> Dict:
|
||||
return {"userId": data["userId"], "symbolCharInfoList": []}
|
||||
|
||||
def handle_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile_preview(data["userId"], self.version)
|
||||
async def handle_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile_preview(data["userId"], self.version)
|
||||
if profile is None:
|
||||
return None
|
||||
profile_character = self.data.item.get_character(
|
||||
profile_character = await self.data.item.get_character(
|
||||
data["userId"], profile["characterId"]
|
||||
)
|
||||
|
||||
@@ -153,8 +164,8 @@ class ChuniNew(ChuniBase):
|
||||
}
|
||||
return data1
|
||||
|
||||
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
async def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
if p is None:
|
||||
return {}
|
||||
|
||||
@@ -166,17 +177,17 @@ class ChuniNew(ChuniBase):
|
||||
"isLogin": False,
|
||||
}
|
||||
|
||||
def handle_printer_login_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_printer_login_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": 1}
|
||||
|
||||
def handle_printer_logout_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_printer_logout_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": 1}
|
||||
|
||||
def handle_get_game_gacha_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_gacha_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
returns all current active banners (gachas)
|
||||
"""
|
||||
game_gachas = self.data.static.get_gachas(self.version)
|
||||
game_gachas = await self.data.static.get_gachas(self.version)
|
||||
|
||||
# clean the database rows
|
||||
game_gacha_list = []
|
||||
@@ -202,11 +213,11 @@ class ChuniNew(ChuniBase):
|
||||
"registIdList": [],
|
||||
}
|
||||
|
||||
def handle_get_game_gacha_card_by_id_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_gacha_card_by_id_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
returns all valid cards for a given gachaId
|
||||
"""
|
||||
game_gacha_cards = self.data.static.get_gacha_cards(data["gachaId"])
|
||||
game_gacha_cards = await self.data.static.get_gacha_cards(data["gachaId"])
|
||||
|
||||
game_gacha_card_list = []
|
||||
for gacha_card in game_gacha_cards:
|
||||
@@ -226,8 +237,8 @@ class ChuniNew(ChuniBase):
|
||||
"ssrBookCalcList": [],
|
||||
}
|
||||
|
||||
def handle_cm_get_user_data_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
async def handle_cm_get_user_data_api_request(self, data: Dict) -> Dict:
|
||||
p = await self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
if p is None:
|
||||
return {}
|
||||
|
||||
@@ -251,8 +262,8 @@ class ChuniNew(ChuniBase):
|
||||
],
|
||||
}
|
||||
|
||||
def handle_get_user_gacha_api_request(self, data: Dict) -> Dict:
|
||||
user_gachas = self.data.item.get_user_gachas(data["userId"])
|
||||
async def handle_get_user_gacha_api_request(self, data: Dict) -> Dict:
|
||||
user_gachas = await self.data.item.get_user_gachas(data["userId"])
|
||||
if user_gachas is None:
|
||||
return {"userId": data["userId"], "length": 0, "userGachaList": []}
|
||||
|
||||
@@ -270,8 +281,8 @@ class ChuniNew(ChuniBase):
|
||||
"userGachaList": user_gacha_list,
|
||||
}
|
||||
|
||||
def handle_get_user_printed_card_api_request(self, data: Dict) -> Dict:
|
||||
user_print_list = self.data.item.get_user_print_states(
|
||||
async def handle_get_user_printed_card_api_request(self, data: Dict) -> Dict:
|
||||
user_print_list = await self.data.item.get_user_print_states(
|
||||
data["userId"], has_completed=True
|
||||
)
|
||||
if user_print_list is None:
|
||||
@@ -305,10 +316,10 @@ class ChuniNew(ChuniBase):
|
||||
"userPrintedCardList": print_list,
|
||||
}
|
||||
|
||||
def handle_get_user_card_print_error_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_user_card_print_error_api_request(self, data: Dict) -> Dict:
|
||||
user_id = data["userId"]
|
||||
|
||||
user_print_states = self.data.item.get_user_print_states(
|
||||
user_print_states = await self.data.item.get_user_print_states(
|
||||
user_id, has_completed=False
|
||||
)
|
||||
|
||||
@@ -327,13 +338,13 @@ class ChuniNew(ChuniBase):
|
||||
"userCardPrintStateList": card_print_state_list,
|
||||
}
|
||||
|
||||
def handle_cm_get_user_character_api_request(self, data: Dict) -> Dict:
|
||||
return super().handle_get_user_character_api_request(data)
|
||||
async def handle_cm_get_user_character_api_request(self, data: Dict) -> Dict:
|
||||
return await super().handle_get_user_character_api_request(data)
|
||||
|
||||
def handle_cm_get_user_item_api_request(self, data: Dict) -> Dict:
|
||||
return super().handle_get_user_item_api_request(data)
|
||||
async def handle_cm_get_user_item_api_request(self, data: Dict) -> Dict:
|
||||
return await super().handle_get_user_item_api_request(data)
|
||||
|
||||
def handle_roll_gacha_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_roll_gacha_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
Handle a gacha roll API request, with:
|
||||
gachaId: the gachaId where the cards should be pulled from
|
||||
@@ -351,14 +362,14 @@ class ChuniNew(ChuniBase):
|
||||
# characterId should be returned
|
||||
if chara_id != -1:
|
||||
# get the
|
||||
card = self.data.static.get_gacha_card_by_character(gacha_id, chara_id)
|
||||
card = await self.data.static.get_gacha_card_by_character(gacha_id, chara_id)
|
||||
|
||||
tmp = card._asdict()
|
||||
tmp.pop("id")
|
||||
|
||||
rolled_cards.append(tmp)
|
||||
else:
|
||||
gacha_cards = self.data.static.get_gacha_cards(gacha_id)
|
||||
gacha_cards = await self.data.static.get_gacha_cards(gacha_id)
|
||||
|
||||
# get the card id for each roll
|
||||
for _ in range(num_rolls):
|
||||
@@ -375,7 +386,7 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
return {"length": len(rolled_cards), "gameGachaCardList": rolled_cards}
|
||||
|
||||
def handle_cm_upsert_user_gacha_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_cm_upsert_user_gacha_api_request(self, data: Dict) -> Dict:
|
||||
upsert = data["cmUpsertUserGacha"]
|
||||
user_id = data["userId"]
|
||||
place_id = data["placeId"]
|
||||
@@ -385,7 +396,7 @@ class ChuniNew(ChuniBase):
|
||||
user_data.pop("rankUpChallengeResults")
|
||||
user_data.pop("userEmoney")
|
||||
|
||||
self.data.profile.put_profile_data(user_id, self.version, user_data)
|
||||
await self.data.profile.put_profile_data(user_id, self.version, user_data)
|
||||
|
||||
# save the user gacha
|
||||
user_gacha = upsert["userGacha"]
|
||||
@@ -393,16 +404,16 @@ class ChuniNew(ChuniBase):
|
||||
user_gacha.pop("gachaId")
|
||||
user_gacha.pop("dailyGachaDate")
|
||||
|
||||
self.data.item.put_user_gacha(user_id, gacha_id, user_gacha)
|
||||
await self.data.item.put_user_gacha(user_id, gacha_id, user_gacha)
|
||||
|
||||
# save all user items
|
||||
if "userItemList" in upsert:
|
||||
for item in upsert["userItemList"]:
|
||||
self.data.item.put_item(user_id, item)
|
||||
await self.data.item.put_item(user_id, item)
|
||||
|
||||
# add every gamegachaCard to database
|
||||
for card in upsert["gameGachaCardList"]:
|
||||
self.data.item.put_user_print_state(
|
||||
await self.data.item.put_user_print_state(
|
||||
user_id,
|
||||
hasCompleted=False,
|
||||
placeId=place_id,
|
||||
@@ -412,7 +423,7 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
# retrieve every game gacha card which has been added in order to get
|
||||
# the orderId for the next request
|
||||
user_print_states = self.data.item.get_user_print_states_by_gacha(
|
||||
user_print_states = await self.data.item.get_user_print_states_by_gacha(
|
||||
user_id, gacha_id, has_completed=False
|
||||
)
|
||||
card_print_state_list = []
|
||||
@@ -430,7 +441,7 @@ class ChuniNew(ChuniBase):
|
||||
"userCardPrintStateList": card_print_state_list,
|
||||
}
|
||||
|
||||
def handle_cm_upsert_user_printlog_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_cm_upsert_user_printlog_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"returnCode": 1,
|
||||
"orderId": 0,
|
||||
@@ -438,7 +449,7 @@ class ChuniNew(ChuniBase):
|
||||
"apiName": "CMUpsertUserPrintlogApi",
|
||||
}
|
||||
|
||||
def handle_cm_upsert_user_print_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_cm_upsert_user_print_api_request(self, data: Dict) -> Dict:
|
||||
user_print_detail = data["userPrintDetail"]
|
||||
user_id = data["userId"]
|
||||
|
||||
@@ -454,7 +465,7 @@ class ChuniNew(ChuniBase):
|
||||
)
|
||||
|
||||
# add the entry to the user print table with the random serialId
|
||||
self.data.item.put_user_print_detail(user_id, serial_id, user_print_detail)
|
||||
await self.data.item.put_user_print_detail(user_id, serial_id, user_print_detail)
|
||||
|
||||
return {
|
||||
"returnCode": 1,
|
||||
@@ -463,7 +474,7 @@ class ChuniNew(ChuniBase):
|
||||
"apiName": "CMUpsertUserPrintApi",
|
||||
}
|
||||
|
||||
def handle_cm_upsert_user_print_subtract_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_cm_upsert_user_print_subtract_api_request(self, data: Dict) -> Dict:
|
||||
upsert = data["userCardPrintState"]
|
||||
user_id = data["userId"]
|
||||
place_id = data["placeId"]
|
||||
@@ -471,37 +482,37 @@ class ChuniNew(ChuniBase):
|
||||
# save all user items
|
||||
if "userItemList" in data:
|
||||
for item in data["userItemList"]:
|
||||
self.data.item.put_item(user_id, item)
|
||||
await self.data.item.put_item(user_id, item)
|
||||
|
||||
# set the card print state to success and use the orderId as the key
|
||||
self.data.item.put_user_print_state(
|
||||
await self.data.item.put_user_print_state(
|
||||
user_id, id=upsert["orderId"], hasCompleted=True
|
||||
)
|
||||
|
||||
return {"returnCode": "1", "apiName": "CMUpsertUserPrintSubtractApi"}
|
||||
|
||||
def handle_cm_upsert_user_print_cancel_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_cm_upsert_user_print_cancel_api_request(self, data: Dict) -> Dict:
|
||||
order_ids = data["orderIdList"]
|
||||
user_id = data["userId"]
|
||||
|
||||
# set the card print state to success and use the orderId as the key
|
||||
for order_id in order_ids:
|
||||
self.data.item.put_user_print_state(user_id, id=order_id, hasCompleted=True)
|
||||
await self.data.item.put_user_print_state(user_id, id=order_id, hasCompleted=True)
|
||||
|
||||
return {"returnCode": "1", "apiName": "CMUpsertUserPrintCancelApi"}
|
||||
|
||||
def handle_ping_request(self, data: Dict) -> Dict:
|
||||
async def handle_ping_request(self, data: Dict) -> Dict:
|
||||
# matchmaking ping request
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_begin_matching_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_begin_matching_api_request(self, data: Dict) -> Dict:
|
||||
room_id = 1
|
||||
# check if there is a free matching room
|
||||
matching_room = self.data.item.get_oldest_free_matching(self.version)
|
||||
matching_room = await self.data.item.get_oldest_free_matching(self.version)
|
||||
|
||||
if matching_room is None:
|
||||
# grab the latest roomId and add 1 for the new room
|
||||
newest_matching = self.data.item.get_newest_matching(self.version)
|
||||
newest_matching = await self.data.item.get_newest_matching(self.version)
|
||||
if newest_matching is not None:
|
||||
room_id = newest_matching["roomId"] + 1
|
||||
|
||||
@@ -511,12 +522,12 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
# create the new room with room_id and the current user id (host)
|
||||
# user id is required for the countdown later on
|
||||
self.data.item.put_matching(
|
||||
await self.data.item.put_matching(
|
||||
self.version, room_id, [new_member], user_id=new_member["userId"]
|
||||
)
|
||||
|
||||
# get the newly created matching room
|
||||
matching_room = self.data.item.get_matching(self.version, room_id)
|
||||
matching_room = await self.data.item.get_matching(self.version, room_id)
|
||||
else:
|
||||
# a room already exists, so just add the new member to it
|
||||
matching_member_list = matching_room["matchingMemberInfoList"]
|
||||
@@ -526,7 +537,7 @@ class ChuniNew(ChuniBase):
|
||||
matching_member_list.append(new_member)
|
||||
|
||||
# add the updated room to the database, make sure to set isFull correctly!
|
||||
self.data.item.put_matching(
|
||||
await self.data.item.put_matching(
|
||||
self.version,
|
||||
matching_room["roomId"],
|
||||
matching_member_list,
|
||||
@@ -543,8 +554,8 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
return {"roomId": 1, "matchingWaitState": matching_wait}
|
||||
|
||||
def handle_end_matching_api_request(self, data: Dict) -> Dict:
|
||||
matching_room = self.data.item.get_matching(self.version, data["roomId"])
|
||||
async def handle_end_matching_api_request(self, data: Dict) -> Dict:
|
||||
matching_room = await self.data.item.get_matching(self.version, data["roomId"])
|
||||
members = matching_room["matchingMemberInfoList"]
|
||||
|
||||
# only set the host user to role 1 every other to 0?
|
||||
@@ -553,7 +564,7 @@ class ChuniNew(ChuniBase):
|
||||
for m in members
|
||||
]
|
||||
|
||||
self.data.item.put_matching(
|
||||
await self.data.item.put_matching(
|
||||
self.version,
|
||||
matching_room["roomId"],
|
||||
members,
|
||||
@@ -568,13 +579,13 @@ class ChuniNew(ChuniBase):
|
||||
# no idea, maybe to differentiate between CPUs and real players?
|
||||
"matchingMemberRoleList": role_list,
|
||||
# TCP/UDP connection?
|
||||
"reflectorUri": f"{self.core_cfg.title.hostname}",
|
||||
"reflectorUri": f"{self.core_cfg.server.hostname}",
|
||||
}
|
||||
|
||||
def handle_remove_matching_member_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_remove_matching_member_api_request(self, data: Dict) -> Dict:
|
||||
# get all matching rooms, because Chuni only returns the userId
|
||||
# not the actual roomId
|
||||
matching_rooms = self.data.item.get_all_matchings(self.version)
|
||||
matching_rooms = await self.data.item.get_all_matchings(self.version)
|
||||
if matching_rooms is None:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
@@ -588,10 +599,10 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
# if the last user got removed, delete the matching room
|
||||
if len(new_members) <= 0:
|
||||
self.data.item.delete_matching(self.version, room["roomId"])
|
||||
await self.data.item.delete_matching(self.version, room["roomId"])
|
||||
else:
|
||||
# remove the user from the room
|
||||
self.data.item.put_matching(
|
||||
await self.data.item.put_matching(
|
||||
self.version,
|
||||
room["roomId"],
|
||||
new_members,
|
||||
@@ -601,10 +612,10 @@ class ChuniNew(ChuniBase):
|
||||
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_get_matching_state_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_matching_state_api_request(self, data: Dict) -> Dict:
|
||||
polling_interval = 1
|
||||
# get the current active room
|
||||
matching_room = self.data.item.get_matching(self.version, data["roomId"])
|
||||
matching_room = await self.data.item.get_matching(self.version, data["roomId"])
|
||||
members = matching_room["matchingMemberInfoList"]
|
||||
rest_sec = matching_room["restMSec"]
|
||||
|
||||
@@ -627,7 +638,7 @@ class ChuniNew(ChuniBase):
|
||||
current_member["userName"] = self.read_wtf8(current_member["userName"])
|
||||
members[i] = current_member
|
||||
|
||||
self.data.item.put_matching(
|
||||
await self.data.item.put_matching(
|
||||
self.version,
|
||||
data["roomId"],
|
||||
members,
|
||||
@@ -647,4 +658,7 @@ class ChuniNew(ChuniBase):
|
||||
"matchingMemberInfoList": [current_member] + diff_members,
|
||||
}
|
||||
|
||||
return {"matchingWaitState": matching_wait}
|
||||
return {
|
||||
"roomId": data["roomId"],
|
||||
"matchingWaitState": matching_wait
|
||||
}
|
||||
|
||||
+3
-25
@@ -1,40 +1,18 @@
|
||||
from typing import Dict, Any
|
||||
|
||||
from core.utils import Utils
|
||||
from core.config import CoreConfig
|
||||
from titles.chuni.new import ChuniNew
|
||||
from titles.chuni.const import ChuniConstants
|
||||
from titles.chuni.config import ChuniConfig
|
||||
|
||||
|
||||
class ChuniNewPlus(ChuniNew):
|
||||
def __init__(self, core_cfg: CoreConfig, game_cfg: ChuniConfig) -> None:
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_NEW_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["romVersion"] = self.game_cfg.version.version(self.version)[
|
||||
"rom"
|
||||
]
|
||||
ret["gameSetting"]["dataVersion"] = self.game_cfg.version.version(self.version)[
|
||||
"data"
|
||||
]
|
||||
ret["gameSetting"][
|
||||
"matchingUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"matchingUriX"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"udpHolePunchUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"reflectorUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
||||
return ret
|
||||
|
||||
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
user_data = super().handle_cm_get_user_preview_api_request(data)
|
||||
async def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
user_data = await super().handle_cm_get_user_preview_api_request(data)
|
||||
|
||||
# hardcode lastDataVersion for CardMaker 1.35 A028
|
||||
user_data["lastDataVersion"] = "2.05.00"
|
||||
|
||||
@@ -13,7 +13,7 @@ class ChuniParadise(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_PARADISE
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.50.00"
|
||||
return ret
|
||||
|
||||
@@ -11,7 +11,7 @@ class ChuniPlus(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.05.00"
|
||||
return ret
|
||||
|
||||
+17
-17
@@ -28,7 +28,7 @@ class ChuniReader(BaseReader):
|
||||
self.logger.error(f"Invalid chunithm version {version}")
|
||||
exit(1)
|
||||
|
||||
def read(self) -> None:
|
||||
async def read(self) -> None:
|
||||
data_dirs = []
|
||||
if self.bin_dir is not None:
|
||||
data_dirs += self.get_data_directories(self.bin_dir)
|
||||
@@ -38,13 +38,13 @@ class ChuniReader(BaseReader):
|
||||
|
||||
for dir in data_dirs:
|
||||
self.logger.info(f"Read from {dir}")
|
||||
self.read_events(f"{dir}/event")
|
||||
self.read_music(f"{dir}/music")
|
||||
self.read_charges(f"{dir}/chargeItem")
|
||||
self.read_avatar(f"{dir}/avatarAccessory")
|
||||
self.read_login_bonus(f"{dir}/")
|
||||
await self.read_events(f"{dir}/event")
|
||||
await self.read_music(f"{dir}/music")
|
||||
await self.read_charges(f"{dir}/chargeItem")
|
||||
await self.read_avatar(f"{dir}/avatarAccessory")
|
||||
await self.read_login_bonus(f"{dir}/")
|
||||
|
||||
def read_login_bonus(self, root_dir: str) -> None:
|
||||
async 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"):
|
||||
@@ -60,7 +60,7 @@ class ChuniReader(BaseReader):
|
||||
True if xml_root.find("disableFlag").text == "false" else False
|
||||
)
|
||||
|
||||
result = self.data.static.put_login_bonus_preset(
|
||||
result = await self.data.static.put_login_bonus_preset(
|
||||
self.version, id, name, is_enabled
|
||||
)
|
||||
|
||||
@@ -98,7 +98,7 @@ class ChuniReader(BaseReader):
|
||||
bonus_root.find("loginBonusCategoryType").text
|
||||
)
|
||||
|
||||
result = self.data.static.put_login_bonus(
|
||||
result = await self.data.static.put_login_bonus(
|
||||
self.version,
|
||||
id,
|
||||
bonus_id,
|
||||
@@ -117,7 +117,7 @@ class ChuniReader(BaseReader):
|
||||
f"Failed to insert login bonus {bonus_id}"
|
||||
)
|
||||
|
||||
def read_events(self, evt_dir: str) -> None:
|
||||
async def read_events(self, evt_dir: str) -> None:
|
||||
for root, dirs, files in walk(evt_dir):
|
||||
for dir in dirs:
|
||||
if path.exists(f"{root}/{dir}/Event.xml"):
|
||||
@@ -132,7 +132,7 @@ class ChuniReader(BaseReader):
|
||||
for substances in xml_root.findall("substances"):
|
||||
event_type = substances.find("type").text
|
||||
|
||||
result = self.data.static.put_event(
|
||||
result = await self.data.static.put_event(
|
||||
self.version, id, event_type, name
|
||||
)
|
||||
if result is not None:
|
||||
@@ -140,7 +140,7 @@ class ChuniReader(BaseReader):
|
||||
else:
|
||||
self.logger.warning(f"Failed to insert event {id}")
|
||||
|
||||
def read_music(self, music_dir: str) -> None:
|
||||
async def read_music(self, music_dir: str) -> None:
|
||||
for root, dirs, files in walk(music_dir):
|
||||
for dir in dirs:
|
||||
if path.exists(f"{root}/{dir}/Music.xml"):
|
||||
@@ -185,7 +185,7 @@ class ChuniReader(BaseReader):
|
||||
)
|
||||
we_chara = None
|
||||
|
||||
result = self.data.static.put_music(
|
||||
result = await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
chart_id,
|
||||
@@ -206,7 +206,7 @@ class ChuniReader(BaseReader):
|
||||
f"Failed to insert music {song_id} chart {chart_id}"
|
||||
)
|
||||
|
||||
def read_charges(self, charge_dir: str) -> None:
|
||||
async def read_charges(self, charge_dir: str) -> None:
|
||||
for root, dirs, files in walk(charge_dir):
|
||||
for dir in dirs:
|
||||
if path.exists(f"{root}/{dir}/ChargeItem.xml"):
|
||||
@@ -222,7 +222,7 @@ class ChuniReader(BaseReader):
|
||||
consumeType = xml_root.find("consumeType").text
|
||||
sellingAppeal = bool(xml_root.find("sellingAppeal").text)
|
||||
|
||||
result = self.data.static.put_charge(
|
||||
result = await self.data.static.put_charge(
|
||||
self.version,
|
||||
id,
|
||||
name,
|
||||
@@ -236,7 +236,7 @@ class ChuniReader(BaseReader):
|
||||
else:
|
||||
self.logger.warning(f"Failed to insert charge {id}")
|
||||
|
||||
def read_avatar(self, avatar_dir: str) -> None:
|
||||
async def read_avatar(self, avatar_dir: str) -> None:
|
||||
for root, dirs, files in walk(avatar_dir):
|
||||
for dir in dirs:
|
||||
if path.exists(f"{root}/{dir}/AvatarAccessory.xml"):
|
||||
@@ -254,7 +254,7 @@ class ChuniReader(BaseReader):
|
||||
for texture in xml_root.findall("texture"):
|
||||
texturePath = texture.find("path").text
|
||||
|
||||
result = self.data.static.put_avatar(
|
||||
result = await self.data.static.put_avatar(
|
||||
self.version, id, name, category, iconPath, texturePath
|
||||
)
|
||||
|
||||
|
||||
+54
-54
@@ -245,7 +245,7 @@ matching = Table(
|
||||
|
||||
|
||||
class ChuniItemData(BaseData):
|
||||
def get_oldest_free_matching(self, version: int) -> Optional[Row]:
|
||||
async def get_oldest_free_matching(self, version: int) -> Optional[Row]:
|
||||
sql = matching.select(
|
||||
and_(
|
||||
matching.c.version == version,
|
||||
@@ -253,46 +253,46 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
).order_by(matching.c.roomId.asc())
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_newest_matching(self, version: int) -> Optional[Row]:
|
||||
async def get_newest_matching(self, version: int) -> Optional[Row]:
|
||||
sql = matching.select(
|
||||
and_(
|
||||
matching.c.version == version
|
||||
)
|
||||
).order_by(matching.c.roomId.desc())
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_all_matchings(self, version: int) -> Optional[List[Row]]:
|
||||
async def get_all_matchings(self, version: int) -> Optional[List[Row]]:
|
||||
sql = matching.select(
|
||||
and_(
|
||||
matching.c.version == version
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_matching(self, version: int, room_id: int) -> Optional[Row]:
|
||||
async def get_matching(self, version: int, room_id: int) -> Optional[Row]:
|
||||
sql = matching.select(
|
||||
and_(matching.c.version == version, matching.c.roomId == room_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_matching(
|
||||
async def put_matching(
|
||||
self,
|
||||
version: int,
|
||||
room_id: int,
|
||||
@@ -314,22 +314,22 @@ class ChuniItemData(BaseData):
|
||||
restMSec=rest_sec, matchingMemberInfoList=matching_member_info_list
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def delete_matching(self, version: int, room_id: int):
|
||||
async def delete_matching(self, version: int, room_id: int):
|
||||
sql = delete(matching).where(
|
||||
and_(matching.c.roomId == room_id, matching.c.version == version)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_all_favorites(
|
||||
async def get_all_favorites(
|
||||
self, user_id: int, version: int, fav_kind: int = 1
|
||||
) -> Optional[List[Row]]:
|
||||
sql = favorite.select(
|
||||
@@ -340,12 +340,12 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_login_bonus(
|
||||
async def put_login_bonus(
|
||||
self, user_id: int, version: int, preset_id: int, **login_bonus_data
|
||||
) -> Optional[int]:
|
||||
sql = insert(login_bonus).values(
|
||||
@@ -354,12 +354,12 @@ class ChuniItemData(BaseData):
|
||||
|
||||
conflict = sql.on_duplicate_key_update(presetId=preset_id, **login_bonus_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_all_login_bonus(
|
||||
async def get_all_login_bonus(
|
||||
self, user_id: int, version: int, is_finished: bool = False
|
||||
) -> Optional[List[Row]]:
|
||||
sql = login_bonus.select(
|
||||
@@ -370,12 +370,12 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_login_bonus(
|
||||
async def get_login_bonus(
|
||||
self, user_id: int, version: int, preset_id: int
|
||||
) -> Optional[Row]:
|
||||
sql = login_bonus.select(
|
||||
@@ -386,12 +386,12 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_character(self, user_id: int, character_data: Dict) -> Optional[int]:
|
||||
async def put_character(self, user_id: int, character_data: Dict) -> Optional[int]:
|
||||
character_data["user"] = user_id
|
||||
|
||||
character_data = self.fix_bools(character_data)
|
||||
@@ -399,30 +399,30 @@ class ChuniItemData(BaseData):
|
||||
sql = insert(character).values(**character_data)
|
||||
conflict = sql.on_duplicate_key_update(**character_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_character(self, user_id: int, character_id: int) -> Optional[Dict]:
|
||||
async def get_character(self, user_id: int, character_id: int) -> Optional[Dict]:
|
||||
sql = select(character).where(
|
||||
and_(character.c.user == user_id, character.c.characterId == character_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_characters(self, user_id: int) -> Optional[List[Row]]:
|
||||
async def get_characters(self, user_id: int) -> Optional[List[Row]]:
|
||||
sql = select(character).where(character.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_item(self, user_id: int, item_data: Dict) -> Optional[int]:
|
||||
async def put_item(self, user_id: int, item_data: Dict) -> Optional[int]:
|
||||
item_data["user"] = user_id
|
||||
|
||||
item_data = self.fix_bools(item_data)
|
||||
@@ -430,12 +430,12 @@ class ChuniItemData(BaseData):
|
||||
sql = insert(item).values(**item_data)
|
||||
conflict = sql.on_duplicate_key_update(**item_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_items(self, user_id: int, kind: int = None) -> Optional[List[Row]]:
|
||||
async def get_items(self, user_id: int, kind: int = None) -> Optional[List[Row]]:
|
||||
if kind is None:
|
||||
sql = select(item).where(item.c.user == user_id)
|
||||
else:
|
||||
@@ -443,12 +443,12 @@ class ChuniItemData(BaseData):
|
||||
and_(item.c.user == user_id, item.c.itemKind == kind)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_duel(self, user_id: int, duel_data: Dict) -> Optional[int]:
|
||||
async def put_duel(self, user_id: int, duel_data: Dict) -> Optional[int]:
|
||||
duel_data["user"] = user_id
|
||||
|
||||
duel_data = self.fix_bools(duel_data)
|
||||
@@ -456,20 +456,20 @@ class ChuniItemData(BaseData):
|
||||
sql = insert(duel).values(**duel_data)
|
||||
conflict = sql.on_duplicate_key_update(**duel_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_duels(self, user_id: int) -> Optional[List[Row]]:
|
||||
async def get_duels(self, user_id: int) -> Optional[List[Row]]:
|
||||
sql = select(duel).where(duel.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_map(self, user_id: int, map_data: Dict) -> Optional[int]:
|
||||
async def put_map(self, user_id: int, map_data: Dict) -> Optional[int]:
|
||||
map_data["user"] = user_id
|
||||
|
||||
map_data = self.fix_bools(map_data)
|
||||
@@ -477,20 +477,20 @@ class ChuniItemData(BaseData):
|
||||
sql = insert(map).values(**map_data)
|
||||
conflict = sql.on_duplicate_key_update(**map_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_maps(self, user_id: int) -> Optional[List[Row]]:
|
||||
async def get_maps(self, user_id: int) -> Optional[List[Row]]:
|
||||
sql = select(map).where(map.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_map_area(self, user_id: int, map_area_data: Dict) -> Optional[int]:
|
||||
async def put_map_area(self, user_id: int, map_area_data: Dict) -> Optional[int]:
|
||||
map_area_data["user"] = user_id
|
||||
|
||||
map_area_data = self.fix_bools(map_area_data)
|
||||
@@ -498,28 +498,28 @@ class ChuniItemData(BaseData):
|
||||
sql = insert(map_area).values(**map_area_data)
|
||||
conflict = sql.on_duplicate_key_update(**map_area_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_map_areas(self, user_id: int) -> Optional[List[Row]]:
|
||||
async def get_map_areas(self, user_id: int) -> Optional[List[Row]]:
|
||||
sql = select(map_area).where(map_area.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_user_gachas(self, aime_id: int) -> Optional[List[Row]]:
|
||||
async def get_user_gachas(self, aime_id: int) -> Optional[List[Row]]:
|
||||
sql = gacha.select(gacha.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_user_gacha(
|
||||
async def put_user_gacha(
|
||||
self, aime_id: int, gacha_id: int, gacha_data: Dict
|
||||
) -> Optional[int]:
|
||||
sql = insert(gacha).values(user=aime_id, gachaId=gacha_id, **gacha_data)
|
||||
@@ -527,14 +527,14 @@ class ChuniItemData(BaseData):
|
||||
conflict = sql.on_duplicate_key_update(
|
||||
user=aime_id, gachaId=gacha_id, **gacha_data
|
||||
)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(f"put_user_gacha: Failed to insert! aime_id: {aime_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_user_print_states(
|
||||
async def get_user_print_states(
|
||||
self, aime_id: int, has_completed: bool = False
|
||||
) -> Optional[List[Row]]:
|
||||
sql = print_state.select(
|
||||
@@ -544,12 +544,12 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_user_print_states_by_gacha(
|
||||
async def get_user_print_states_by_gacha(
|
||||
self, aime_id: int, gacha_id: int, has_completed: bool = False
|
||||
) -> Optional[List[Row]]:
|
||||
sql = print_state.select(
|
||||
@@ -560,16 +560,16 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_user_print_state(self, aime_id: int, **print_data) -> Optional[int]:
|
||||
async def put_user_print_state(self, aime_id: int, **print_data) -> Optional[int]:
|
||||
sql = insert(print_state).values(user=aime_id, **print_data)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(user=aime_id, **print_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
@@ -578,7 +578,7 @@ class ChuniItemData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def put_user_print_detail(
|
||||
async def put_user_print_detail(
|
||||
self, aime_id: int, serial_id: str, user_print_data: Dict
|
||||
) -> Optional[int]:
|
||||
sql = insert(print_detail).values(
|
||||
@@ -586,7 +586,7 @@ class ChuniItemData(BaseData):
|
||||
)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(user=aime_id, **user_print_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
|
||||
@@ -395,7 +395,18 @@ team = Table(
|
||||
|
||||
|
||||
class ChuniProfileData(BaseData):
|
||||
def put_profile_data(
|
||||
async def update_name(self, user_id: int, new_name: str) -> bool:
|
||||
sql = profile.update(profile.c.user == user_id).values(
|
||||
userName=new_name
|
||||
)
|
||||
result = await self.execute(sql)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(f"Failed to set user {user_id} name to {new_name}")
|
||||
return False
|
||||
return True
|
||||
|
||||
async def put_profile_data(
|
||||
self, aime_id: int, version: int, profile_data: Dict
|
||||
) -> Optional[int]:
|
||||
profile_data["user"] = aime_id
|
||||
@@ -407,26 +418,26 @@ class ChuniProfileData(BaseData):
|
||||
|
||||
sql = insert(profile).values(**profile_data)
|
||||
conflict = sql.on_duplicate_key_update(**profile_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(f"put_profile_data: Failed to update! aime_id: {aime_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_preview(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
async def get_profile_preview(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
sql = (
|
||||
select([profile, option])
|
||||
.join(option, profile.c.user == option.c.user)
|
||||
.filter(and_(profile.c.user == aime_id, profile.c.version <= version))
|
||||
).order_by(profile.c.version.desc())
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_profile_data(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
async def get_profile_data(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
sql = select(profile).where(
|
||||
and_(
|
||||
profile.c.user == aime_id,
|
||||
@@ -434,12 +445,12 @@ class ChuniProfileData(BaseData):
|
||||
)
|
||||
).order_by(profile.c.version.desc())
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_profile_data_ex(
|
||||
async def put_profile_data_ex(
|
||||
self, aime_id: int, version: int, profile_ex_data: Dict
|
||||
) -> Optional[int]:
|
||||
profile_ex_data["user"] = aime_id
|
||||
@@ -449,7 +460,7 @@ class ChuniProfileData(BaseData):
|
||||
|
||||
sql = insert(profile_ex).values(**profile_ex_data)
|
||||
conflict = sql.on_duplicate_key_update(**profile_ex_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
@@ -458,7 +469,7 @@ class ChuniProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_data_ex(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
async def get_profile_data_ex(self, aime_id: int, version: int) -> Optional[Row]:
|
||||
sql = select(profile_ex).where(
|
||||
and_(
|
||||
profile_ex.c.user == aime_id,
|
||||
@@ -466,17 +477,17 @@ class ChuniProfileData(BaseData):
|
||||
)
|
||||
).order_by(profile_ex.c.version.desc())
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_profile_option(self, aime_id: int, option_data: Dict) -> Optional[int]:
|
||||
async def put_profile_option(self, aime_id: int, option_data: Dict) -> Optional[int]:
|
||||
option_data["user"] = aime_id
|
||||
|
||||
sql = insert(option).values(**option_data)
|
||||
conflict = sql.on_duplicate_key_update(**option_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
@@ -485,22 +496,22 @@ class ChuniProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_option(self, aime_id: int) -> Optional[Row]:
|
||||
async def get_profile_option(self, aime_id: int) -> Optional[Row]:
|
||||
sql = select(option).where(option.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_profile_option_ex(
|
||||
async def put_profile_option_ex(
|
||||
self, aime_id: int, option_ex_data: Dict
|
||||
) -> Optional[int]:
|
||||
option_ex_data["user"] = aime_id
|
||||
|
||||
sql = insert(option_ex).values(**option_ex_data)
|
||||
conflict = sql.on_duplicate_key_update(**option_ex_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
@@ -509,15 +520,15 @@ class ChuniProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_option_ex(self, aime_id: int) -> Optional[Row]:
|
||||
async def get_profile_option_ex(self, aime_id: int) -> Optional[Row]:
|
||||
sql = select(option_ex).where(option_ex.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_profile_recent_rating(
|
||||
async def put_profile_recent_rating(
|
||||
self, aime_id: int, recent_rating_data: List[Dict]
|
||||
) -> Optional[int]:
|
||||
sql = insert(recent_rating).values(
|
||||
@@ -525,7 +536,7 @@ class ChuniProfileData(BaseData):
|
||||
)
|
||||
conflict = sql.on_duplicate_key_update(recentRating=recent_rating_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
f"put_profile_recent_rating: Failed to update! aime_id: {aime_id}"
|
||||
@@ -533,15 +544,15 @@ class ChuniProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_recent_rating(self, aime_id: int) -> Optional[Row]:
|
||||
async def get_profile_recent_rating(self, aime_id: int) -> Optional[Row]:
|
||||
sql = select(recent_rating).where(recent_rating.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_profile_activity(self, aime_id: int, activity_data: Dict) -> Optional[int]:
|
||||
async def put_profile_activity(self, aime_id: int, activity_data: Dict) -> Optional[int]:
|
||||
# The game just uses "id" but we need to distinguish that from the db column "id"
|
||||
activity_data["user"] = aime_id
|
||||
activity_data["activityId"] = activity_data["id"]
|
||||
@@ -549,7 +560,7 @@ class ChuniProfileData(BaseData):
|
||||
|
||||
sql = insert(activity).values(**activity_data)
|
||||
conflict = sql.on_duplicate_key_update(**activity_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
@@ -558,24 +569,24 @@ class ChuniProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_activity(self, aime_id: int, kind: int) -> Optional[List[Row]]:
|
||||
async def get_profile_activity(self, aime_id: int, kind: int) -> Optional[List[Row]]:
|
||||
sql = (
|
||||
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 = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_profile_charge(self, aime_id: int, charge_data: Dict) -> Optional[int]:
|
||||
async def put_profile_charge(self, aime_id: int, charge_data: Dict) -> Optional[int]:
|
||||
charge_data["user"] = aime_id
|
||||
|
||||
sql = insert(charge).values(**charge_data)
|
||||
conflict = sql.on_duplicate_key_update(**charge_data)
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
@@ -584,40 +595,40 @@ class ChuniProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_charge(self, aime_id: int) -> Optional[List[Row]]:
|
||||
async def get_profile_charge(self, aime_id: int) -> Optional[List[Row]]:
|
||||
sql = select(charge).where(charge.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def add_profile_region(self, aime_id: int, region_id: int) -> Optional[int]:
|
||||
async def add_profile_region(self, aime_id: int, region_id: int) -> Optional[int]:
|
||||
pass
|
||||
|
||||
def get_profile_regions(self, aime_id: int) -> Optional[List[Row]]:
|
||||
async def get_profile_regions(self, aime_id: int) -> Optional[List[Row]]:
|
||||
pass
|
||||
|
||||
def put_profile_emoney(self, aime_id: int, emoney_data: Dict) -> Optional[int]:
|
||||
async def put_profile_emoney(self, aime_id: int, emoney_data: Dict) -> Optional[int]:
|
||||
emoney_data["user"] = aime_id
|
||||
|
||||
sql = insert(emoney).values(**emoney_data)
|
||||
conflict = sql.on_duplicate_key_update(**emoney_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_emoney(self, aime_id: int) -> Optional[List[Row]]:
|
||||
async def get_profile_emoney(self, aime_id: int) -> Optional[List[Row]]:
|
||||
sql = select(emoney).where(emoney.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_profile_overpower(
|
||||
async def put_profile_overpower(
|
||||
self, aime_id: int, overpower_data: Dict
|
||||
) -> Optional[int]:
|
||||
overpower_data["user"] = aime_id
|
||||
@@ -625,31 +636,31 @@ class ChuniProfileData(BaseData):
|
||||
sql = insert(overpower).values(**overpower_data)
|
||||
conflict = sql.on_duplicate_key_update(**overpower_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile_overpower(self, aime_id: int) -> Optional[List[Row]]:
|
||||
async def get_profile_overpower(self, aime_id: int) -> Optional[List[Row]]:
|
||||
sql = select(overpower).where(overpower.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_team_by_id(self, team_id: int) -> Optional[Row]:
|
||||
async def get_team_by_id(self, team_id: int) -> Optional[Row]:
|
||||
sql = select(team).where(team.c.id == team_id)
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_team_rank(self, team_id: int) -> int:
|
||||
async def get_team_rank(self, team_id: int) -> int:
|
||||
# Normal ranking system, likely the one used in the real servers
|
||||
# Query all teams sorted by 'teamPoint'
|
||||
result = self.execute(
|
||||
result = await self.execute(
|
||||
select(team.c.id).order_by(team.c.teamPoint.desc())
|
||||
)
|
||||
|
||||
@@ -666,13 +677,13 @@ class ChuniProfileData(BaseData):
|
||||
# RIP scaled team ranking. Gone, but forgotten
|
||||
# def get_team_rank_scaled(self, team_id: int) -> int:
|
||||
|
||||
def update_team(self, team_id: int, team_data: Dict) -> bool:
|
||||
async def update_team(self, team_id: int, team_data: Dict) -> bool:
|
||||
team_data["id"] = team_id
|
||||
|
||||
sql = insert(team).values(**team_data)
|
||||
conflict = sql.on_duplicate_key_update(**team_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warn(
|
||||
@@ -680,16 +691,16 @@ class ChuniProfileData(BaseData):
|
||||
)
|
||||
return False
|
||||
return True
|
||||
def get_rival(self, rival_id: int) -> Optional[Row]:
|
||||
async def get_rival(self, rival_id: int) -> Optional[Row]:
|
||||
sql = select(profile).where(profile.c.user == rival_id)
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
def get_overview(self) -> Dict:
|
||||
async def get_overview(self) -> Dict:
|
||||
# Fetch and add up all the playcounts
|
||||
playcount_sql = self.execute(select(profile.c.playCount))
|
||||
playcount_sql = await self.execute(select(profile.c.playCount))
|
||||
|
||||
if playcount_sql is None:
|
||||
self.logger.warn(
|
||||
@@ -697,7 +708,7 @@ class ChuniProfileData(BaseData):
|
||||
)
|
||||
return 0
|
||||
|
||||
total_play_count = 0;
|
||||
total_play_count = 0
|
||||
for row in playcount_sql:
|
||||
total_play_count += row[0]
|
||||
return {
|
||||
|
||||
@@ -142,55 +142,55 @@ playlog = Table(
|
||||
|
||||
|
||||
class ChuniScoreData(BaseData):
|
||||
def get_courses(self, aime_id: int) -> Optional[Row]:
|
||||
async def get_courses(self, aime_id: int) -> Optional[Row]:
|
||||
sql = select(course).where(course.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_course(self, aime_id: int, course_data: Dict) -> Optional[int]:
|
||||
async def put_course(self, aime_id: int, course_data: Dict) -> Optional[int]:
|
||||
course_data["user"] = aime_id
|
||||
course_data = self.fix_bools(course_data)
|
||||
|
||||
sql = insert(course).values(**course_data)
|
||||
conflict = sql.on_duplicate_key_update(**course_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_scores(self, aime_id: int) -> Optional[Row]:
|
||||
async def get_scores(self, aime_id: int) -> Optional[Row]:
|
||||
sql = select(best_score).where(best_score.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_score(self, aime_id: int, score_data: Dict) -> Optional[int]:
|
||||
async def put_score(self, aime_id: int, score_data: Dict) -> Optional[int]:
|
||||
score_data["user"] = aime_id
|
||||
score_data = self.fix_bools(score_data)
|
||||
|
||||
sql = insert(best_score).values(**score_data)
|
||||
conflict = sql.on_duplicate_key_update(**score_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_playlogs(self, aime_id: int) -> Optional[Row]:
|
||||
async def get_playlogs(self, aime_id: int) -> Optional[Row]:
|
||||
sql = select(playlog).where(playlog.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_playlog(self, aime_id: int, playlog_data: Dict, version: int) -> Optional[int]:
|
||||
async def put_playlog(self, aime_id: int, playlog_data: Dict, version: int) -> Optional[int]:
|
||||
# Calculate the ROM version that should be inserted into the DB, based on the version of the ggame being inserted
|
||||
# We only need from Version 10 (Plost) and back, as newer versions include romVersion in their upsert
|
||||
# This matters both for gameRankings, as well as a future DB update to keep version data separate
|
||||
@@ -216,12 +216,12 @@ class ChuniScoreData(BaseData):
|
||||
sql = insert(playlog).values(**playlog_data)
|
||||
conflict = sql.on_duplicate_key_update(**playlog_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_rankings(self, version: int) -> Optional[List[Dict]]:
|
||||
async def get_rankings(self, version: int) -> Optional[List[Dict]]:
|
||||
# Calculates the ROM version that should be fetched for rankings, based on the game version being retrieved
|
||||
# This prevents tracks that are not accessible in your version from counting towards the 10 results
|
||||
romVer = {
|
||||
@@ -241,7 +241,7 @@ class ChuniScoreData(BaseData):
|
||||
0: "1.00%"
|
||||
}
|
||||
sql = select([playlog.c.musicId.label('id'), func.count(playlog.c.musicId).label('point')]).where((playlog.c.level != 4) & (playlog.c.romVersion.like(romVer.get(version, "%")))).group_by(playlog.c.musicId).order_by(func.count(playlog.c.musicId).desc()).limit(10)
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
|
||||
if result is None:
|
||||
return None
|
||||
@@ -249,10 +249,10 @@ class ChuniScoreData(BaseData):
|
||||
rows = result.fetchall()
|
||||
return [dict(row) for row in rows]
|
||||
|
||||
def get_rival_music(self, rival_id: int) -> Optional[List[Dict]]:
|
||||
async def get_rival_music(self, rival_id: int) -> Optional[List[Dict]]:
|
||||
sql = select(best_score).where(best_score.c.user == rival_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
@@ -175,7 +175,7 @@ login_bonus = Table(
|
||||
|
||||
|
||||
class ChuniStaticData(BaseData):
|
||||
def put_login_bonus(
|
||||
async def put_login_bonus(
|
||||
self,
|
||||
version: int,
|
||||
preset_id: int,
|
||||
@@ -207,12 +207,12 @@ class ChuniStaticData(BaseData):
|
||||
loginBonusCategoryType=login_bonus_category_type,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_login_bonus(
|
||||
async def get_login_bonus(
|
||||
self,
|
||||
version: int,
|
||||
preset_id: int,
|
||||
@@ -224,12 +224,12 @@ class ChuniStaticData(BaseData):
|
||||
)
|
||||
).order_by(login_bonus.c.needLoginDayCount.desc())
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_login_bonus_by_required_days(
|
||||
async def get_login_bonus_by_required_days(
|
||||
self, version: int, preset_id: int, need_login_day_count: int
|
||||
) -> Optional[Row]:
|
||||
sql = login_bonus.select(
|
||||
@@ -240,12 +240,12 @@ class ChuniStaticData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_login_bonus_preset(
|
||||
async 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(
|
||||
@@ -259,12 +259,12 @@ class ChuniStaticData(BaseData):
|
||||
presetName=preset_name, isEnabled=is_enabled
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_login_bonus_presets(
|
||||
async def get_login_bonus_presets(
|
||||
self, version: int, is_enabled: bool = True
|
||||
) -> Optional[List[Row]]:
|
||||
sql = login_bonus_preset.select(
|
||||
@@ -274,12 +274,12 @@ class ChuniStaticData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_event(
|
||||
async def put_event(
|
||||
self, version: int, event_id: int, type: int, name: str
|
||||
) -> Optional[int]:
|
||||
sql = insert(events).values(
|
||||
@@ -288,19 +288,19 @@ class ChuniStaticData(BaseData):
|
||||
|
||||
conflict = sql.on_duplicate_key_update(name=name)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def update_event(
|
||||
async def update_event(
|
||||
self, version: int, event_id: int, enabled: bool
|
||||
) -> Optional[bool]:
|
||||
sql = events.update(
|
||||
and_(events.c.version == version, events.c.eventId == event_id)
|
||||
).values(enabled=enabled)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.warning(
|
||||
f"update_event: failed to update event! version: {version}, event_id: {event_id}, enabled: {enabled}"
|
||||
@@ -315,35 +315,35 @@ class ChuniStaticData(BaseData):
|
||||
return None
|
||||
return event["enabled"]
|
||||
|
||||
def get_event(self, version: int, event_id: int) -> Optional[Row]:
|
||||
async def get_event(self, version: int, event_id: int) -> Optional[Row]:
|
||||
sql = select(events).where(
|
||||
and_(events.c.version == version, events.c.eventId == event_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_enabled_events(self, version: int) -> Optional[List[Row]]:
|
||||
async def get_enabled_events(self, version: int) -> Optional[List[Row]]:
|
||||
sql = select(events).where(
|
||||
and_(events.c.version == version, events.c.enabled == True)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_events(self, version: int) -> Optional[List[Row]]:
|
||||
async def get_events(self, version: int) -> Optional[List[Row]]:
|
||||
sql = select(events).where(events.c.version == version)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_music(
|
||||
async def put_music(
|
||||
self,
|
||||
version: int,
|
||||
song_id: int,
|
||||
@@ -376,12 +376,12 @@ class ChuniStaticData(BaseData):
|
||||
worldsEndTag=we_tag,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def put_charge(
|
||||
async def put_charge(
|
||||
self,
|
||||
version: int,
|
||||
charge_id: int,
|
||||
@@ -406,38 +406,38 @@ class ChuniStaticData(BaseData):
|
||||
sellingAppeal=selling_appeal,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_enabled_charges(self, version: int) -> Optional[List[Row]]:
|
||||
async def get_enabled_charges(self, version: int) -> Optional[List[Row]]:
|
||||
sql = select(charge).where(
|
||||
and_(charge.c.version == version, charge.c.enabled == True)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_charges(self, version: int) -> Optional[List[Row]]:
|
||||
async def get_charges(self, version: int) -> Optional[List[Row]]:
|
||||
sql = select(charge).where(charge.c.version == version)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_music(self, version: int) -> Optional[List[Row]]:
|
||||
async def get_music(self, version: int) -> Optional[List[Row]]:
|
||||
sql = music.select(music.c.version <= version)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_music_chart(
|
||||
async def get_music_chart(
|
||||
self, version: int, song_id: int, chart_id: int
|
||||
) -> Optional[List[Row]]:
|
||||
sql = select(music).where(
|
||||
@@ -448,21 +448,21 @@ class ChuniStaticData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_song(self, music_id: int) -> Optional[Row]:
|
||||
async def get_song(self, music_id: int) -> Optional[Row]:
|
||||
sql = music.select(music.c.id == music_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
|
||||
def put_avatar(
|
||||
async def put_avatar(
|
||||
self,
|
||||
version: int,
|
||||
avatarAccessoryId: int,
|
||||
@@ -487,12 +487,12 @@ class ChuniStaticData(BaseData):
|
||||
texturePath=texturePath,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def put_gacha(
|
||||
async def put_gacha(
|
||||
self,
|
||||
version: int,
|
||||
gacha_id: int,
|
||||
@@ -513,33 +513,33 @@ class ChuniStaticData(BaseData):
|
||||
**gacha_data,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warning(f"Failed to insert gacha! gacha_id {gacha_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_gachas(self, version: int) -> Optional[List[Dict]]:
|
||||
async def get_gachas(self, version: int) -> Optional[List[Dict]]:
|
||||
sql = gachas.select(gachas.c.version <= version).order_by(
|
||||
gachas.c.gachaId.asc()
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_gacha(self, version: int, gacha_id: int) -> Optional[Dict]:
|
||||
async def get_gacha(self, version: int, gacha_id: int) -> Optional[Dict]:
|
||||
sql = gachas.select(
|
||||
and_(gachas.c.version <= version, gachas.c.gachaId == gacha_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_gacha_card(
|
||||
async def put_gacha_card(
|
||||
self, gacha_id: int, card_id: int, **gacha_card
|
||||
) -> Optional[int]:
|
||||
sql = insert(gacha_cards).values(gachaId=gacha_id, cardId=card_id, **gacha_card)
|
||||
@@ -548,21 +548,21 @@ class ChuniStaticData(BaseData):
|
||||
gachaId=gacha_id, cardId=card_id, **gacha_card
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warning(f"Failed to insert gacha card! gacha_id {gacha_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_gacha_cards(self, gacha_id: int) -> Optional[List[Dict]]:
|
||||
async def get_gacha_cards(self, gacha_id: int) -> Optional[List[Dict]]:
|
||||
sql = gacha_cards.select(gacha_cards.c.gachaId == gacha_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_gacha_card_by_character(
|
||||
async def get_gacha_card_by_character(
|
||||
self, gacha_id: int, chara_id: int
|
||||
) -> Optional[Dict]:
|
||||
sql_sub = (
|
||||
@@ -574,26 +574,26 @@ class ChuniStaticData(BaseData):
|
||||
and_(gacha_cards.c.gachaId == gacha_id, gacha_cards.c.cardId == sql_sub)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_card(self, version: int, card_id: int, **card_data) -> Optional[int]:
|
||||
async def put_card(self, version: int, card_id: int, **card_data) -> Optional[int]:
|
||||
sql = insert(cards).values(version=version, cardId=card_id, **card_data)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(**card_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warning(f"Failed to insert card! card_id {card_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_card(self, version: int, card_id: int) -> Optional[Dict]:
|
||||
async def get_card(self, version: int, card_id: int) -> Optional[Dict]:
|
||||
sql = cards.select(and_(cards.c.version <= version, cards.c.cardId == card_id))
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
@@ -11,7 +11,7 @@ class ChuniStar(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_STAR
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.20.00"
|
||||
return ret
|
||||
|
||||
@@ -11,7 +11,7 @@ class ChuniStarPlus(ChuniBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_STAR_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.25.00"
|
||||
return ret
|
||||
|
||||
+2
-20
@@ -11,26 +11,8 @@ class ChuniSun(ChuniNewPlus):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_SUN
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["romVersion"] = self.game_cfg.version.version(self.version)["rom"]
|
||||
ret["gameSetting"]["dataVersion"] = self.game_cfg.version.version(self.version)["data"]
|
||||
ret["gameSetting"][
|
||||
"matchingUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"matchingUriX"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"udpHolePunchUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"reflectorUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
|
||||
return ret
|
||||
|
||||
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
user_data = super().handle_cm_get_user_preview_api_request(data)
|
||||
async def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
user_data = await super().handle_cm_get_user_preview_api_request(data)
|
||||
|
||||
# hardcode lastDataVersion for CardMaker 1.35 A032
|
||||
user_data["lastDataVersion"] = "2.10.00"
|
||||
|
||||
+2
-20
@@ -11,26 +11,8 @@ class ChuniSunPlus(ChuniSun):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = ChuniConstants.VER_CHUNITHM_SUN_PLUS
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["romVersion"] = self.game_cfg.version.version(self.version)["rom"]
|
||||
ret["gameSetting"]["dataVersion"] = self.game_cfg.version.version(self.version)["data"]
|
||||
ret["gameSetting"][
|
||||
"matchingUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/215/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"matchingUriX"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/215/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"udpHolePunchUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/215/ChuniServlet/"
|
||||
ret["gameSetting"][
|
||||
"reflectorUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/215/ChuniServlet/"
|
||||
return ret
|
||||
|
||||
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
user_data = super().handle_cm_get_user_preview_api_request(data)
|
||||
async def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
user_data = await super().handle_cm_get_user_preview_api_request(data)
|
||||
|
||||
# I don't know if lastDataVersion is going to matter, I don't think CardMaker 1.35 works this far up
|
||||
user_data["lastDataVersion"] = "2.15.00"
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
{% extends "core/templates/index.jinja" %}
|
||||
{% block content %}
|
||||
<h1>Chunithm</h1>
|
||||
{% if profile is defined and profile is not none and profile.id > 0 %}
|
||||
<script type="text/javascript">
|
||||
function toggle_new_name_form() {
|
||||
let frm = document.getElementById("new_name_form");
|
||||
let btn = document.getElementById("btn_toggle_form");
|
||||
|
||||
if (frm.style['display'] != "") {
|
||||
frm.style['display'] = "";
|
||||
frm.style['max-height'] = "";
|
||||
btn.innerText = "Cancel";
|
||||
} else {
|
||||
frm.style['display'] = "none";
|
||||
frm.style['max-height'] = "0px";
|
||||
btn.innerText = "Edit";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<h3>Profile for {{ profile.userName }} <button onclick="toggle_new_name_form()" class="btn btn-secondary" id="btn_toggle_form">Edit</button></h3>
|
||||
{% if error is defined %}
|
||||
{% include "core/templates/widgets/err_banner.jinja" %}
|
||||
{% endif %}
|
||||
{% if success is defined and success == 1 %}
|
||||
<div style="background-color: #00AA00; padding: 20px; margin-bottom: 10px; width: 15%;">
|
||||
Update successful
|
||||
</div>
|
||||
{% endif %}
|
||||
<form style="max-width: 33%; display: none; max-height: 0px;" action="/game/chuni/update.name" method="post" id="new_name_form">
|
||||
<div class="mb-3">
|
||||
<label for="new_name" class="form-label">New Trainer Name</label>
|
||||
<input type="text" class="form-control" id="new_name" name="new_name" aria-describedby="new_name_help" maxlength="14">
|
||||
<div id="new_name_help" class="form-text">Must be 14 characters or less</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
{% elif sesh is defined and sesh is not none and sesh.user_id > 0 %}
|
||||
No profile information found for this account.
|
||||
{% else %}
|
||||
Login to view profile information.
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
@@ -6,7 +6,4 @@ from titles.cm.database import CardMakerData
|
||||
index = CardMakerServlet
|
||||
reader = CardMakerReader
|
||||
database = CardMakerData
|
||||
|
||||
game_codes = [CardMakerConstants.GAME_CODE]
|
||||
|
||||
current_schema_version = 1
|
||||
|
||||
+7
-7
@@ -29,11 +29,11 @@ class CardMakerBase:
|
||||
def _parse_int_ver(version: str) -> str:
|
||||
return version.replace(".", "")[:3]
|
||||
|
||||
def handle_get_game_connect_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_connect_api_request(self, data: Dict) -> Dict:
|
||||
if not self.core_cfg.server.is_using_proxy and Utils.get_title_port(self.core_cfg) != 80:
|
||||
uri = f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}"
|
||||
uri = f"http://{self.core_cfg.server.hostname}:{Utils.get_title_port(self.core_cfg)}"
|
||||
else:
|
||||
uri = f"http://{self.core_cfg.title.hostname}"
|
||||
uri = f"http://{self.core_cfg.server.hostname}"
|
||||
|
||||
# grab the dict with all games version numbers from user config
|
||||
games_ver = self.game_cfg.version.version(self.version)
|
||||
@@ -62,7 +62,7 @@ class CardMakerBase:
|
||||
],
|
||||
}
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
# if reboot start/end time is not defined use the default behavior of being a few hours ago
|
||||
if self.core_cfg.title.reboot_start_time == "" or self.core_cfg.title.reboot_end_time == "":
|
||||
reboot_start = datetime.strftime(
|
||||
@@ -110,11 +110,11 @@ class CardMakerBase:
|
||||
"isAou": False,
|
||||
}
|
||||
|
||||
def handle_get_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||
return {"placeId": data["placeId"], "length": 0, "clientBookkeepingList": []}
|
||||
|
||||
def handle_upsert_client_setting_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_setting_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": 1, "apiName": "UpsertClientSettingApi"}
|
||||
|
||||
def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||
async def handle_upsert_client_bookkeeping_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": 1, "apiName": "UpsertClientBookkeepingApi"}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ class CardMaker135(CardMakerBase):
|
||||
super().__init__(core_cfg, game_cfg)
|
||||
self.version = CardMakerConstants.VER_CARD_MAKER_135
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = super().handle_get_game_setting_api_request(data)
|
||||
async def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
|
||||
ret = await super().handle_get_game_setting_api_request(data)
|
||||
ret["gameSetting"]["dataVersion"] = "1.35.00"
|
||||
return ret
|
||||
|
||||
+18
-19
@@ -5,10 +5,11 @@ import string
|
||||
import logging
|
||||
import coloredlogs
|
||||
import zlib
|
||||
|
||||
from starlette.routing import Route
|
||||
from starlette.responses import Response
|
||||
from starlette.requests import Request
|
||||
from os import path
|
||||
from typing import Tuple, List, Dict
|
||||
from twisted.web.http import Request
|
||||
from typing import List
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
|
||||
from core.config import CoreConfig
|
||||
@@ -19,7 +20,6 @@ from .const import CardMakerConstants
|
||||
from .base import CardMakerBase
|
||||
from .cm135 import CardMaker135
|
||||
|
||||
|
||||
class CardMakerServlet(BaseServlet):
|
||||
def __init__(self, core_cfg: CoreConfig, cfg_dir: str) -> None:
|
||||
super().__init__(core_cfg, cfg_dir)
|
||||
@@ -72,16 +72,15 @@ class CardMakerServlet(BaseServlet):
|
||||
|
||||
return True
|
||||
|
||||
def get_endpoint_matchers(self) -> Tuple[List[Tuple[str, str, Dict]], List[Tuple[str, str, Dict]]]:
|
||||
return (
|
||||
[],
|
||||
[("render_POST", "/SDED/{version}/{endpoint}", {})]
|
||||
)
|
||||
|
||||
def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
version = int(matchers['version'])
|
||||
endpoint = matchers['endpoint']
|
||||
req_raw = request.content.getvalue()
|
||||
def get_routes(self) -> List[Route]:
|
||||
return [
|
||||
Route("/SDED/{version:int}/{endpoint:str}", self.render_POST, methods=['POST'])
|
||||
]
|
||||
|
||||
async def render_POST(self, request: Request) -> bytes:
|
||||
version: int = request.path_params.get('version')
|
||||
endpoint: str = request.path_params.get('endpoint')
|
||||
req_raw = await request.body()
|
||||
internal_ver = 0
|
||||
client_ip = Utils.get_ip_addr(request)
|
||||
|
||||
@@ -103,7 +102,7 @@ class CardMakerServlet(BaseServlet):
|
||||
self.logger.error(
|
||||
f"Failed to decompress v{version} {endpoint} request -> {e}"
|
||||
)
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
req_data = json.loads(unzip)
|
||||
|
||||
@@ -114,20 +113,20 @@ class CardMakerServlet(BaseServlet):
|
||||
|
||||
if not hasattr(self.versions[internal_ver], func_to_find):
|
||||
self.logger.warning(f"Unhandled v{version} request {endpoint}")
|
||||
return zlib.compress(b'{"returnCode": 1}')
|
||||
return Response(zlib.compress(b'{"returnCode": 1}'))
|
||||
|
||||
try:
|
||||
handler = getattr(self.versions[internal_ver], func_to_find)
|
||||
resp = handler(req_data)
|
||||
resp = await handler(req_data)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error handling v{version} method {endpoint} - {e}")
|
||||
raise
|
||||
return zlib.compress(b'{"stat": "0"}')
|
||||
return Response(zlib.compress(b'{"stat": "0"}'))
|
||||
|
||||
if resp is None:
|
||||
resp = {"returnCode": 1}
|
||||
|
||||
self.logger.debug(f"Response {resp}")
|
||||
|
||||
return zlib.compress(json.dumps(resp, ensure_ascii=False).encode("utf-8"))
|
||||
return Response(zlib.compress(json.dumps(resp, ensure_ascii=False).encode("utf-8")))
|
||||
|
||||
+23
-23
@@ -50,7 +50,7 @@ class CardMakerReader(BaseReader):
|
||||
):
|
||||
return f"{root}/{dir}"
|
||||
|
||||
def read(self) -> None:
|
||||
async def read(self) -> None:
|
||||
static_datas = {
|
||||
"static_gachas.csv": "read_ongeki_gacha_csv",
|
||||
"static_gacha_cards.csv": "read_ongeki_gacha_card_csv",
|
||||
@@ -59,14 +59,14 @@ class CardMakerReader(BaseReader):
|
||||
if self.bin_dir is not None:
|
||||
data_dir = self._get_card_maker_directory(self.bin_dir)
|
||||
|
||||
self.read_chuni_card(f"{data_dir}/CHU/Data/A000/card")
|
||||
self.read_chuni_gacha(f"{data_dir}/CHU/Data/A000/gacha")
|
||||
await self.read_chuni_card(f"{data_dir}/CHU/Data/A000/card")
|
||||
await self.read_chuni_gacha(f"{data_dir}/CHU/Data/A000/gacha")
|
||||
|
||||
self.read_mai2_card(f"{data_dir}/MAI/Data/A000/card")
|
||||
await self.read_mai2_card(f"{data_dir}/MAI/Data/A000/card")
|
||||
for file, func in static_datas.items():
|
||||
if os.path.exists(f"{self.bin_dir}/MU3/{file}"):
|
||||
read_csv = getattr(CardMakerReader, func)
|
||||
read_csv(self, f"{self.bin_dir}/MU3/{file}")
|
||||
await read_csv(self, f"{self.bin_dir}/MU3/{file}")
|
||||
else:
|
||||
self.logger.warning(
|
||||
f"Couldn't find {file} file in {self.bin_dir}, skipping"
|
||||
@@ -78,12 +78,12 @@ class CardMakerReader(BaseReader):
|
||||
# ONGEKI (MU3) cnnot easily access the bin data(A000.pac)
|
||||
# so only opt_dir will work for now
|
||||
for dir in data_dirs:
|
||||
self.read_chuni_card(f"{dir}/CHU/card")
|
||||
self.read_chuni_gacha(f"{dir}/CHU/gacha")
|
||||
self.read_mai2_card(f"{dir}/MAI/card")
|
||||
self.read_ongeki_gacha(f"{dir}/MU3/gacha")
|
||||
await self.read_chuni_card(f"{dir}/CHU/card")
|
||||
await self.read_chuni_gacha(f"{dir}/CHU/gacha")
|
||||
await self.read_mai2_card(f"{dir}/MAI/card")
|
||||
await self.read_ongeki_gacha(f"{dir}/MU3/gacha")
|
||||
|
||||
def read_chuni_card(self, base_dir: str) -> None:
|
||||
async def read_chuni_card(self, base_dir: str) -> None:
|
||||
self.logger.info(f"Reading cards from {base_dir}...")
|
||||
|
||||
version_ids = {
|
||||
@@ -114,7 +114,7 @@ class CardMakerReader(BaseReader):
|
||||
chain = int(troot.find("chain").text)
|
||||
skill_name = troot.find("skillName").text
|
||||
|
||||
self.chuni_data.static.put_card(
|
||||
await self.chuni_data.static.put_card(
|
||||
version,
|
||||
card_id,
|
||||
charaName=chara_name,
|
||||
@@ -131,7 +131,7 @@ class CardMakerReader(BaseReader):
|
||||
|
||||
self.logger.info(f"Added chuni card {card_id}")
|
||||
|
||||
def read_chuni_gacha(self, base_dir: str) -> None:
|
||||
async def read_chuni_gacha(self, base_dir: str) -> None:
|
||||
self.logger.info(f"Reading gachas from {base_dir}...")
|
||||
|
||||
version_ids = {
|
||||
@@ -158,7 +158,7 @@ class CardMakerReader(BaseReader):
|
||||
True if troot.find("ceilingType").text == "1" else False
|
||||
)
|
||||
|
||||
self.chuni_data.static.put_gacha(
|
||||
await self.chuni_data.static.put_gacha(
|
||||
version,
|
||||
gacha_id,
|
||||
name,
|
||||
@@ -181,7 +181,7 @@ class CardMakerReader(BaseReader):
|
||||
True if gacha_card.find("pickup").text == "1" else False
|
||||
)
|
||||
|
||||
self.chuni_data.static.put_gacha_card(
|
||||
await self.chuni_data.static.put_gacha_card(
|
||||
gacha_id,
|
||||
card_id,
|
||||
weight=weight,
|
||||
@@ -193,7 +193,7 @@ class CardMakerReader(BaseReader):
|
||||
f"Added chuni card {card_id} to gacha {gacha_id}"
|
||||
)
|
||||
|
||||
def read_mai2_card(self, base_dir: str) -> None:
|
||||
async def read_mai2_card(self, base_dir: str) -> None:
|
||||
self.logger.info(f"Reading cards from {base_dir}...")
|
||||
|
||||
version_ids = {
|
||||
@@ -231,18 +231,18 @@ class CardMakerReader(BaseReader):
|
||||
False if re.search(r"\d{2}/\d{2}/\d{2}", name) else enabled
|
||||
)
|
||||
|
||||
self.mai2_data.static.put_card(
|
||||
await self.mai2_data.static.put_card(
|
||||
version, card_id, name, enabled=enabled
|
||||
)
|
||||
self.logger.info(f"Added mai2 card {card_id}")
|
||||
|
||||
def read_ongeki_gacha_csv(self, file_path: str) -> None:
|
||||
async def read_ongeki_gacha_csv(self, file_path: str) -> None:
|
||||
self.logger.info(f"Reading gachas from {file_path}...")
|
||||
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
self.ongeki_data.static.put_gacha(
|
||||
await self.ongeki_data.static.put_gacha(
|
||||
row["version"],
|
||||
row["gachaId"],
|
||||
row["gachaName"],
|
||||
@@ -254,13 +254,13 @@ class CardMakerReader(BaseReader):
|
||||
|
||||
self.logger.info(f"Added ongeki gacha {row['gachaId']}")
|
||||
|
||||
def read_ongeki_gacha_card_csv(self, file_path: str) -> None:
|
||||
async def read_ongeki_gacha_card_csv(self, file_path: str) -> None:
|
||||
self.logger.info(f"Reading gacha cards from {file_path}...")
|
||||
|
||||
with open(file_path, encoding="utf-8") as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
self.ongeki_data.static.put_gacha_card(
|
||||
await self.ongeki_data.static.put_gacha_card(
|
||||
row["gachaId"],
|
||||
row["cardId"],
|
||||
rarity=row["rarity"],
|
||||
@@ -271,7 +271,7 @@ class CardMakerReader(BaseReader):
|
||||
|
||||
self.logger.info(f"Added ongeki card {row['cardId']} to gacha")
|
||||
|
||||
def read_ongeki_gacha(self, base_dir: str) -> None:
|
||||
async def read_ongeki_gacha(self, base_dir: str) -> None:
|
||||
self.logger.info(f"Reading gachas from {base_dir}...")
|
||||
|
||||
# assuming some GachaKinds based on the GachaType
|
||||
@@ -294,7 +294,7 @@ class CardMakerReader(BaseReader):
|
||||
|
||||
# skip already existing gachas
|
||||
if (
|
||||
self.ongeki_data.static.get_gacha(
|
||||
await self.ongeki_data.static.get_gacha(
|
||||
OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY, gacha_id
|
||||
)
|
||||
is not None
|
||||
@@ -320,7 +320,7 @@ class CardMakerReader(BaseReader):
|
||||
is_ceiling = 1
|
||||
max_select_point = 33
|
||||
|
||||
self.ongeki_data.static.put_gacha(
|
||||
await self.ongeki_data.static.put_gacha(
|
||||
version,
|
||||
gacha_id,
|
||||
name,
|
||||
|
||||
@@ -7,4 +7,3 @@ index = CxbServlet
|
||||
database = CxbData
|
||||
reader = CxbReader
|
||||
game_codes = [CxbConstants.GAME_CODE]
|
||||
current_schema_version = 1
|
||||
|
||||
+38
-38
@@ -28,14 +28,14 @@ class CxbBase:
|
||||
|
||||
return []
|
||||
|
||||
def handle_action_rpreq_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_rpreq_request(self, data: Dict) -> Dict:
|
||||
return {}
|
||||
|
||||
def handle_action_hitreq_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_hitreq_request(self, data: Dict) -> Dict:
|
||||
return {"data": []}
|
||||
|
||||
def handle_auth_usercheck_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile_index(
|
||||
async def handle_auth_usercheck_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile_index(
|
||||
0, data["usercheck"]["authid"], self.version
|
||||
)
|
||||
if profile is not None:
|
||||
@@ -45,12 +45,12 @@ class CxbBase:
|
||||
self.logger.info(f"No profile for aime id {data['usercheck']['authid']}")
|
||||
return {"exist": "false", "logout": "true"}
|
||||
|
||||
def handle_auth_entry_request(self, data: Dict) -> Dict:
|
||||
async def handle_auth_entry_request(self, data: Dict) -> Dict:
|
||||
self.logger.info(f"New profile for {data['entry']['authid']}")
|
||||
return {"token": data["entry"]["authid"], "uid": data["entry"]["authid"]}
|
||||
|
||||
def handle_auth_login_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile_index(
|
||||
async def handle_auth_login_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile_index(
|
||||
0, data["login"]["authid"], self.version
|
||||
)
|
||||
|
||||
@@ -198,14 +198,14 @@ class CxbBase:
|
||||
).decode("utf-8")
|
||||
)
|
||||
|
||||
def handle_action_loadrange_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_loadrange_request(self, data: Dict) -> Dict:
|
||||
range_start = data["loadrange"]["range"][0]
|
||||
range_end = data["loadrange"]["range"][1]
|
||||
uid = data["loadrange"]["uid"]
|
||||
|
||||
self.logger.info(f"Load data for {uid}")
|
||||
profile = self.data.profile.get_profile(uid, self.version)
|
||||
songs = self.data.score.get_best_scores(uid)
|
||||
profile = await self.data.profile.get_profile(uid, self.version)
|
||||
songs = await self.data.score.get_best_scores(uid)
|
||||
|
||||
data1 = []
|
||||
index = []
|
||||
@@ -271,7 +271,7 @@ class CxbBase:
|
||||
thread_ScoreData = Thread(target=CxbBase.task_generateScoreData(song, index, data1))
|
||||
thread_ScoreData.start()
|
||||
|
||||
v_profile = self.data.profile.get_profile_index(0, uid, self.version)
|
||||
v_profile = await self.data.profile.get_profile_index(0, uid, self.version)
|
||||
v_profile_data = v_profile["data"]
|
||||
|
||||
for _, data in enumerate(profile):
|
||||
@@ -282,7 +282,7 @@ class CxbBase:
|
||||
|
||||
return {"index": index, "data": data1, "version": versionindex}
|
||||
|
||||
def handle_action_saveindex_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_saveindex_request(self, data: Dict) -> Dict:
|
||||
save_data = data["saveindex"]
|
||||
|
||||
try:
|
||||
@@ -300,11 +300,11 @@ class CxbBase:
|
||||
|
||||
for value in data["saveindex"]["data"]:
|
||||
if "playedUserId" in value[1]:
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
data["saveindex"]["uid"], self.version, value[0], value[1]
|
||||
)
|
||||
if "mcode" not in value[1]:
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
data["saveindex"]["uid"], self.version, value[0], value[1]
|
||||
)
|
||||
if "shopId" in value:
|
||||
@@ -335,7 +335,7 @@ class CxbBase:
|
||||
"index": value[0],
|
||||
}
|
||||
)
|
||||
self.data.score.put_best_score(
|
||||
await self.data.score.put_best_score(
|
||||
data["saveindex"]["uid"],
|
||||
song_json["mcode"],
|
||||
self.version,
|
||||
@@ -360,32 +360,32 @@ class CxbBase:
|
||||
|
||||
for index, value in enumerate(data["saveindex"]["data"]):
|
||||
if int(data["saveindex"]["index"][index]) == 101:
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
aimeId, self.version, data["saveindex"]["index"][index], value
|
||||
)
|
||||
if (
|
||||
int(data["saveindex"]["index"][index]) >= 700000
|
||||
and int(data["saveindex"]["index"][index]) <= 701000
|
||||
):
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
aimeId, self.version, data["saveindex"]["index"][index], value
|
||||
)
|
||||
if (
|
||||
int(data["saveindex"]["index"][index]) >= 500
|
||||
and int(data["saveindex"]["index"][index]) <= 510
|
||||
):
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
aimeId, self.version, data["saveindex"]["index"][index], value
|
||||
)
|
||||
if "playedUserId" in value:
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
aimeId,
|
||||
self.version,
|
||||
data["saveindex"]["index"][index],
|
||||
json.loads(value),
|
||||
)
|
||||
if "mcode" not in value and "normalCR" not in value:
|
||||
self.data.profile.put_profile(
|
||||
await self.data.profile.put_profile(
|
||||
aimeId,
|
||||
self.version,
|
||||
data["saveindex"]["index"][index],
|
||||
@@ -437,16 +437,16 @@ class CxbBase:
|
||||
}
|
||||
)
|
||||
|
||||
self.data.score.put_best_score(
|
||||
await self.data.score.put_best_score(
|
||||
aimeId, data1["mcode"], self.version, indexSongList[i], songCode[0]
|
||||
)
|
||||
i += 1
|
||||
return {}
|
||||
|
||||
def handle_action_sprankreq_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_sprankreq_request(self, data: Dict) -> Dict:
|
||||
uid = data["sprankreq"]["uid"]
|
||||
self.logger.info(f"Get best rankings for {uid}")
|
||||
p = self.data.score.get_best_rankings(uid)
|
||||
p = await self.data.score.get_best_rankings(uid)
|
||||
|
||||
rankList: List[Dict[str, Any]] = []
|
||||
|
||||
@@ -475,16 +475,16 @@ class CxbBase:
|
||||
"rankx": [1, 1, 1],
|
||||
}
|
||||
|
||||
def handle_action_getadv_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_getadv_request(self, data: Dict) -> Dict:
|
||||
return {"data": [{"r": "1", "i": "100300", "c": "20"}]}
|
||||
|
||||
def handle_action_getmsg_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_getmsg_request(self, data: Dict) -> Dict:
|
||||
return {"msgs": []}
|
||||
|
||||
def handle_auth_logout_request(self, data: Dict) -> Dict:
|
||||
async def handle_auth_logout_request(self, data: Dict) -> Dict:
|
||||
return {"auth": True}
|
||||
|
||||
def handle_action_rankreg_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_rankreg_request(self, data: Dict) -> Dict:
|
||||
uid = data["rankreg"]["uid"]
|
||||
self.logger.info(f"Put {len(data['rankreg']['data'])} rankings for {uid}")
|
||||
|
||||
@@ -492,7 +492,7 @@ class CxbBase:
|
||||
# REV S2
|
||||
if "clear" in rid:
|
||||
try:
|
||||
self.data.score.put_ranking(
|
||||
await self.data.score.put_ranking(
|
||||
user_id=uid,
|
||||
rev_id=int(rid["rid"]),
|
||||
song_id=int(rid["sc"][1]),
|
||||
@@ -500,7 +500,7 @@ class CxbBase:
|
||||
clear=rid["clear"],
|
||||
)
|
||||
except Exception:
|
||||
self.data.score.put_ranking(
|
||||
await self.data.score.put_ranking(
|
||||
user_id=uid,
|
||||
rev_id=int(rid["rid"]),
|
||||
song_id=0,
|
||||
@@ -510,7 +510,7 @@ class CxbBase:
|
||||
# REV
|
||||
else:
|
||||
try:
|
||||
self.data.score.put_ranking(
|
||||
await self.data.score.put_ranking(
|
||||
user_id=uid,
|
||||
rev_id=int(rid["rid"]),
|
||||
song_id=int(rid["sc"][1]),
|
||||
@@ -518,7 +518,7 @@ class CxbBase:
|
||||
clear=0,
|
||||
)
|
||||
except Exception:
|
||||
self.data.score.put_ranking(
|
||||
await self.data.score.put_ranking(
|
||||
user_id=uid,
|
||||
rev_id=int(rid["rid"]),
|
||||
song_id=0,
|
||||
@@ -527,15 +527,15 @@ class CxbBase:
|
||||
)
|
||||
return {}
|
||||
|
||||
def handle_action_addenergy_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_addenergy_request(self, data: Dict) -> Dict:
|
||||
uid = data["addenergy"]["uid"]
|
||||
self.logger.info(f"Add energy to user {uid}")
|
||||
profile = self.data.profile.get_profile_index(0, uid, self.version)
|
||||
profile = await self.data.profile.get_profile_index(0, uid, self.version)
|
||||
data1 = profile["data"]
|
||||
p = self.data.item.get_energy(uid)
|
||||
p = await self.data.item.get_energy(uid)
|
||||
|
||||
if not p:
|
||||
self.data.item.put_energy(uid, 5)
|
||||
await self.data.item.put_energy(uid, 5)
|
||||
|
||||
return {
|
||||
"class": data1["myClass"],
|
||||
@@ -548,7 +548,7 @@ class CxbBase:
|
||||
energy = p["energy"]
|
||||
|
||||
newenergy = int(energy) + 5
|
||||
self.data.item.put_energy(uid, newenergy)
|
||||
await self.data.item.put_energy(uid, newenergy)
|
||||
|
||||
if int(energy) <= 995:
|
||||
array.append(
|
||||
@@ -570,10 +570,10 @@ class CxbBase:
|
||||
)
|
||||
return array[0]
|
||||
|
||||
def handle_action_eventreq_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_eventreq_request(self, data: Dict) -> Dict:
|
||||
self.logger.info(data)
|
||||
return {"eventreq": ""}
|
||||
|
||||
def handle_action_stampreq_request(self, data: Dict) -> Dict:
|
||||
async def handle_action_stampreq_request(self, data: Dict) -> Dict:
|
||||
self.logger.info(data)
|
||||
return {"stampreq": ""}
|
||||
@@ -18,6 +18,12 @@ class CxbServerConfig:
|
||||
self.__config, "cxb", "server", "loglevel", default="info"
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def use_https(self) -> bool:
|
||||
return CoreConfig.get_config_field(
|
||||
self.__config, "cxb", "server", "use_https", default=True
|
||||
)
|
||||
|
||||
|
||||
class CxbConfig(dict):
|
||||
|
||||
+40
-43
@@ -1,4 +1,6 @@
|
||||
from twisted.web.http import Request
|
||||
from starlette.requests import Request
|
||||
from starlette.routing import Route
|
||||
from starlette.responses import Response, JSONResponse
|
||||
import traceback
|
||||
import sys
|
||||
import yaml
|
||||
@@ -11,7 +13,7 @@ from typing import Dict, Tuple, List
|
||||
from os import path
|
||||
|
||||
from core.config import CoreConfig
|
||||
from core.title import BaseServlet
|
||||
from core.title import BaseServlet, JSONResponseNoASCII
|
||||
from core.utils import Utils
|
||||
from .config import CxbConfig
|
||||
from .const import CxbConstants
|
||||
@@ -62,6 +64,14 @@ class CxbServlet(BaseServlet):
|
||||
CxbRevSunriseS2(core_cfg, self.game_cfg),
|
||||
]
|
||||
|
||||
def get_routes(self) -> List[Route]:
|
||||
return [
|
||||
Route("/data", self.handle_data, methods=['POST']),
|
||||
Route("/action", self.handle_action, methods=['POST']),
|
||||
Route("/v2/action", self.handle_action, methods=['POST']),
|
||||
Route("/auth", self.handle_auth, methods=['POST']),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def is_game_enabled(cls, game_code: str, core_cfg: CoreConfig, cfg_dir: str) -> bool:
|
||||
game_cfg = CxbConfig()
|
||||
@@ -79,35 +89,22 @@ class CxbServlet(BaseServlet):
|
||||
title_port_int = Utils.get_title_port(self.core_cfg)
|
||||
title_port_ssl_int = Utils.get_title_port_ssl(self.core_cfg)
|
||||
|
||||
proto = "https" if title_port_ssl_int != 443 else "http"
|
||||
proto = "https" if self.game_cfg.server.use_https else "http"
|
||||
|
||||
if proto == "https":
|
||||
t_port = f":{title_port_ssl_int}" if title_port_ssl_int and not self.core_cfg.server.is_using_proxy else ""
|
||||
t_port = f":{title_port_ssl_int}" if title_port_ssl_int != 443 else ""
|
||||
|
||||
else:
|
||||
t_port = f":{title_port_int}" if title_port_int and not self.core_cfg.server.is_using_proxy else ""
|
||||
t_port = f":{title_port_int}" if title_port_int != 80 else ""
|
||||
|
||||
return (
|
||||
f"{proto}://{self.core_cfg.title.hostname}{t_port}",
|
||||
f"{proto}://{self.core_cfg.server.hostname}{t_port}",
|
||||
"",
|
||||
)
|
||||
|
||||
def get_endpoint_matchers(self) -> Tuple[List[Tuple[str, str, Dict]], List[Tuple[str, str, Dict]]]:
|
||||
return (
|
||||
[],
|
||||
[
|
||||
("handle_data", "/data", {}),
|
||||
("handle_action", "/action", {}),
|
||||
("handle_action", "/v2/action", {}),
|
||||
("handle_auth", "/auth", {}),
|
||||
]
|
||||
)
|
||||
|
||||
def preprocess(self, req: Request) -> Dict:
|
||||
try:
|
||||
req_bytes = req.content.getvalue()
|
||||
except:
|
||||
req_bytes = req.content.read() # Can we just use this one?
|
||||
|
||||
async def preprocess(self, req: Request) -> Dict:
|
||||
req_bytes = await req.body()
|
||||
|
||||
try:
|
||||
req_json: Dict = json.loads(req_bytes)
|
||||
@@ -126,8 +123,8 @@ class CxbServlet(BaseServlet):
|
||||
|
||||
return req_json
|
||||
|
||||
def handle_data(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
req_json = self.preprocess(request)
|
||||
async def handle_data(self, request: Request) -> bytes:
|
||||
req_json = await self.preprocess(request)
|
||||
func_to_find = "handle_data_"
|
||||
version_string = "Base"
|
||||
internal_ver = 0
|
||||
@@ -135,7 +132,7 @@ class CxbServlet(BaseServlet):
|
||||
|
||||
if req_json == {}:
|
||||
self.logger.warning(f"Empty json request to /data")
|
||||
return b""
|
||||
return Response()
|
||||
|
||||
subcmd = list(req_json.keys())[0]
|
||||
if subcmd == "dldate":
|
||||
@@ -145,14 +142,14 @@ class CxbServlet(BaseServlet):
|
||||
or "filetype" not in req_json["dldate"]
|
||||
):
|
||||
self.logger.warning(f"Malformed dldate request: {req_json}")
|
||||
return b""
|
||||
return Response()
|
||||
|
||||
filetype = req_json["dldate"]["filetype"]
|
||||
filetype_split = filetype.split("/")
|
||||
|
||||
if len(filetype_split) < 2 or not filetype_split[0].isnumeric():
|
||||
self.logger.warning(f"Malformed dldate request: {req_json}")
|
||||
return b""
|
||||
return Response()
|
||||
|
||||
version = int(filetype_split[0])
|
||||
filename = filetype_split[len(filetype_split) - 1]
|
||||
@@ -184,7 +181,7 @@ class CxbServlet(BaseServlet):
|
||||
|
||||
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":""})
|
||||
return JSONResponse({"data":""})
|
||||
|
||||
self.logger.info(f"{version_string} request for filetype {filetype}")
|
||||
self.logger.debug(req_json)
|
||||
@@ -192,7 +189,7 @@ class CxbServlet(BaseServlet):
|
||||
handler = getattr(self.versions[internal_ver], func_to_find)
|
||||
|
||||
try:
|
||||
resp = handler(req_json)
|
||||
resp = await handler(req_json)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error handling request for file {filetype} - {e}")
|
||||
@@ -201,19 +198,19 @@ class CxbServlet(BaseServlet):
|
||||
traceback.print_exception(tp, val, tb, limit=1)
|
||||
with open("{0}/{1}.log".format(self.core_cfg.server.log_dir, "cxb"), "a") as f:
|
||||
traceback.print_exception(tp, val, tb, limit=1, file=f)
|
||||
return ""
|
||||
return Response()
|
||||
|
||||
self.logger.debug(f"{version_string} Response {resp}")
|
||||
return json.dumps(resp, ensure_ascii=False).encode("utf-8")
|
||||
return JSONResponseNoASCII(resp)
|
||||
|
||||
def handle_action(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
req_json = self.preprocess(request)
|
||||
async def handle_action(self, request: Request) -> bytes:
|
||||
req_json = await self.preprocess(request)
|
||||
subcmd = list(req_json.keys())[0]
|
||||
func_to_find = f"handle_action_{subcmd}_request"
|
||||
|
||||
if not hasattr(self.versions[0], func_to_find):
|
||||
self.logger.warn(f"No handler for action {subcmd} request")
|
||||
return ""
|
||||
return Response()
|
||||
|
||||
self.logger.info(f"Action {subcmd} Request")
|
||||
self.logger.debug(req_json)
|
||||
@@ -221,7 +218,7 @@ class CxbServlet(BaseServlet):
|
||||
handler = getattr(self.versions[0], func_to_find)
|
||||
|
||||
try:
|
||||
resp = handler(req_json)
|
||||
resp = await handler(req_json)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error handling action {subcmd} request - {e}")
|
||||
@@ -230,19 +227,19 @@ class CxbServlet(BaseServlet):
|
||||
traceback.print_exception(tp, val, tb, limit=1)
|
||||
with open("{0}/{1}.log".format(self.core_cfg.server.log_dir, "cxb"), "a") as f:
|
||||
traceback.print_exception(tp, val, tb, limit=1, file=f)
|
||||
return ""
|
||||
return Response()
|
||||
|
||||
self.logger.debug(f"Response {resp}")
|
||||
return json.dumps(resp, ensure_ascii=False).encode("utf-8")
|
||||
return JSONResponseNoASCII(resp)
|
||||
|
||||
def handle_auth(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
req_json = self.preprocess(request)
|
||||
async def handle_auth(self, request: Request) -> bytes:
|
||||
req_json = await self.preprocess(request)
|
||||
subcmd = list(req_json.keys())[0]
|
||||
func_to_find = f"handle_auth_{subcmd}_request"
|
||||
|
||||
if not hasattr(self.versions[0], func_to_find):
|
||||
self.logger.warn(f"No handler for auth {subcmd} request")
|
||||
return ""
|
||||
return Response()
|
||||
|
||||
self.logger.info(f"Action {subcmd} Request")
|
||||
self.logger.debug(req_json)
|
||||
@@ -250,7 +247,7 @@ class CxbServlet(BaseServlet):
|
||||
handler = getattr(self.versions[0], func_to_find)
|
||||
|
||||
try:
|
||||
resp = handler(req_json)
|
||||
resp = await handler(req_json)
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error handling auth {subcmd} request - {e}")
|
||||
@@ -259,7 +256,7 @@ class CxbServlet(BaseServlet):
|
||||
traceback.print_exception(tp, val, tb, limit=1)
|
||||
with open("{0}/{1}.log".format(self.core_cfg.server.log_dir, "cxb"), "a") as f:
|
||||
traceback.print_exception(tp, val, tb, limit=1, file=f)
|
||||
return ""
|
||||
return Response()
|
||||
|
||||
self.logger.debug(f"Response {resp}")
|
||||
return json.dumps(resp, ensure_ascii=False).encode("utf-8")
|
||||
return JSONResponseNoASCII(resp)
|
||||
|
||||
+14
-19
@@ -1,6 +1,5 @@
|
||||
from typing import Optional, Dict, List
|
||||
from os import walk, path
|
||||
import urllib
|
||||
from typing import Optional
|
||||
from os import path
|
||||
import csv
|
||||
|
||||
from read import BaseReader
|
||||
@@ -8,7 +7,6 @@ from core.config import CoreConfig
|
||||
from titles.cxb.database import CxbData
|
||||
from titles.cxb.const import CxbConstants
|
||||
|
||||
|
||||
class CxbReader(BaseReader):
|
||||
def __init__(
|
||||
self,
|
||||
@@ -29,17 +27,14 @@ class CxbReader(BaseReader):
|
||||
self.logger.error(f"Invalid project cxb version {version}")
|
||||
exit(1)
|
||||
|
||||
def read(self) -> None:
|
||||
pull_bin_ram = True
|
||||
async def read(self) -> None:
|
||||
if path.exists(self.bin_dir):
|
||||
await self.read_csv(self.bin_dir)
|
||||
|
||||
else:
|
||||
self.logger.warn(f"{self.bin_dir} does not exist, nothing to import")
|
||||
|
||||
if not path.exists(f"{self.bin_dir}"):
|
||||
self.logger.warning(f"Couldn't find csv file in {self.bin_dir}, skipping")
|
||||
pull_bin_ram = False
|
||||
|
||||
if pull_bin_ram:
|
||||
self.read_csv(f"{self.bin_dir}")
|
||||
|
||||
def read_csv(self, bin_dir: str) -> None:
|
||||
async def read_csv(self, bin_dir: str) -> None:
|
||||
self.logger.info(f"Read csv from {bin_dir}")
|
||||
|
||||
try:
|
||||
@@ -55,7 +50,7 @@ class CxbReader(BaseReader):
|
||||
|
||||
if not "N/A" in row["standard"]:
|
||||
self.logger.info(f"Added song {song_id} chart 0")
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
index,
|
||||
@@ -71,7 +66,7 @@ class CxbReader(BaseReader):
|
||||
)
|
||||
if not "N/A" in row["hard"]:
|
||||
self.logger.info(f"Added song {song_id} chart 1")
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
index,
|
||||
@@ -83,7 +78,7 @@ class CxbReader(BaseReader):
|
||||
)
|
||||
if not "N/A" in row["master"]:
|
||||
self.logger.info(f"Added song {song_id} chart 2")
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
index,
|
||||
@@ -97,7 +92,7 @@ class CxbReader(BaseReader):
|
||||
)
|
||||
if not "N/A" in row["unlimited"]:
|
||||
self.logger.info(f"Added song {song_id} chart 3")
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
index,
|
||||
@@ -113,7 +108,7 @@ class CxbReader(BaseReader):
|
||||
)
|
||||
if not "N/A" in row["easy"]:
|
||||
self.logger.info(f"Added song {song_id} chart 4")
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
index,
|
||||
|
||||
+65
-60
@@ -17,15 +17,15 @@ class CxbRev(CxbBase):
|
||||
super().__init__(cfg, game_cfg)
|
||||
self.version = CxbConstants.VER_CROSSBEATS_REV
|
||||
|
||||
def handle_data_path_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_path_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_putlog_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_putlog_request(self, data: Dict) -> Dict:
|
||||
if data["putlog"]["type"] == "ResultLog":
|
||||
score_data = json.loads(data["putlog"]["data"])
|
||||
userid = score_data["usid"]
|
||||
|
||||
self.data.score.put_playlog(
|
||||
await self.data.score.put_playlog(
|
||||
userid,
|
||||
score_data["mcode"],
|
||||
score_data["difficulty"],
|
||||
@@ -45,9 +45,9 @@ class CxbRev(CxbBase):
|
||||
return {"data": True}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss/MusicArchiveList.csv") as music:
|
||||
with open(r"titles/cxb/data/rev/MusicArchiveList.csv") as music:
|
||||
lines = music.readlines()
|
||||
for line in lines:
|
||||
line_split = line.split(",")
|
||||
@@ -56,10 +56,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_icon_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_icon_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ItemListIcon\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Item/ItemArchiveList_Icon.csv", encoding="utf-8"
|
||||
r"titles/cxb/data/rev/Item/ItemArchiveList_Icon.csv", encoding="shift-jis"
|
||||
) as item:
|
||||
lines = item.readlines()
|
||||
for line in lines:
|
||||
@@ -67,10 +67,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_skin_notes_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_skin_notes_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ItemListSkinNotes\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Item/ItemArchiveList_SkinNotes.csv", encoding="utf-8"
|
||||
r"titles/cxb/data/rev/Item/ItemArchiveList_SkinNotes.csv", encoding="utf-8"
|
||||
) as item:
|
||||
lines = item.readlines()
|
||||
for line in lines:
|
||||
@@ -78,10 +78,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_skin_effect_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_skin_effect_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ItemListSkinEffect\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Item/ItemArchiveList_SkinEffect.csv", encoding="utf-8"
|
||||
r"titles/cxb/data/rev/Item/ItemArchiveList_SkinEffect.csv", encoding="utf-8"
|
||||
) as item:
|
||||
lines = item.readlines()
|
||||
for line in lines:
|
||||
@@ -89,10 +89,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_skin_bg_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_skin_bg_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ItemListSkinBg\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Item/ItemArchiveList_SkinBg.csv", encoding="utf-8"
|
||||
r"titles/cxb/data/rev/Item/ItemArchiveList_SkinBg.csv", encoding="utf-8"
|
||||
) as item:
|
||||
lines = item.readlines()
|
||||
for line in lines:
|
||||
@@ -100,10 +100,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_title_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_title_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ItemListTitle\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Item/ItemList_Title.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Item/ItemList_Title.csv", encoding="shift-jis"
|
||||
) as item:
|
||||
lines = item.readlines()
|
||||
for line in lines:
|
||||
@@ -111,10 +111,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_shop_list_music_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_music_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ShopListMusic\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Shop/ShopList_Music.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Shop/ShopList_Music.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
@@ -122,10 +122,10 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_shop_list_icon_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_icon_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ShopListIcon\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Shop/ShopList_Icon.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Shop/ShopList_Icon.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
@@ -133,83 +133,88 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_shop_list_title_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_title_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ShopListTitle\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Shop/ShopList_Title.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Shop/ShopList_Title.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_shop_list_skin_hud_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_skin_hud_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_shop_list_skin_arrow_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_skin_arrow_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_shop_list_skin_hit_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_skin_hit_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_shop_list_sale_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_sale_request(self, data: Dict) -> Dict:
|
||||
ret_str = "\r\n#ShopListSale\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Shop/ShopList_Sale.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Shop/ShopList_Sale.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
async def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rev/ExtraStageList.csv", encoding="shift-jis") as stage:
|
||||
lines = stage.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
extra_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = ""
|
||||
with open(
|
||||
rf"titles/cxb/data/rss/Ex000{extra_num}.csv", encoding="shift-jis"
|
||||
rf"titles/cxb/data/rev/Ex000{extra_num}.csv", encoding="shift-jis"
|
||||
) as stage:
|
||||
lines = stage.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss/NewsList.csv", encoding="UTF-8") as news:
|
||||
with open(r"titles/cxb/data/rev/NewsList.csv", encoding="UTF-8") as news:
|
||||
lines = news.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_tips_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_tips_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_license_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_license_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss/License_Offline.csv", encoding="UTF-8") as lic:
|
||||
with open(r"titles/cxb/data/rev/License_Offline.csv", encoding="UTF-8") as lic:
|
||||
lines = lic.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_course_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_course_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Course/CourseList.csv", encoding="UTF-8"
|
||||
r"titles/cxb/data/rev/Course/CourseList.csv", encoding="UTF-8"
|
||||
) as course:
|
||||
lines = course.readlines()
|
||||
for line in lines:
|
||||
@@ -217,12 +222,12 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_csxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_csxxxx_request(self, data: Dict) -> Dict:
|
||||
# Removed the CSVs since the format isnt quite right
|
||||
extra_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = ""
|
||||
with open(
|
||||
rf"titles/cxb/data/rss/Course/Cs000{extra_num}.csv", encoding="shift-jis"
|
||||
rf"titles/cxb/data/rev/Course/Cs000{extra_num}.csv", encoding="shift-jis"
|
||||
) as course:
|
||||
lines = course.readlines()
|
||||
for line in lines:
|
||||
@@ -230,77 +235,77 @@ class CxbRev(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_mission_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_mission_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(
|
||||
r"titles/cxb/data/rss/MissionList.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/MissionList.csv", encoding="shift-jis"
|
||||
) as mission:
|
||||
lines = mission.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_mission_bonus_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_mission_bonus_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_unlimited_mission_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_unlimited_mission_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_event_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Event/EventArchiveList.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Event/EventArchiveList.csv", encoding="shift-jis"
|
||||
) as mission:
|
||||
lines = mission.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_event_music_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_music_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_mission_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_mission_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_achievement_single_high_score_list_request(
|
||||
async def handle_data_event_achievement_single_high_score_list_request(
|
||||
self, data: Dict
|
||||
) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_achievement_single_accumulation_request(
|
||||
async def handle_data_event_achievement_single_accumulation_request(
|
||||
self, data: Dict
|
||||
) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_ranking_high_score_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_ranking_high_score_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_ranking_accumulation_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_ranking_accumulation_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_ranking_stamp_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_ranking_stamp_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_ranking_store_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_ranking_store_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_ranking_area_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_ranking_area_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_event_stamp_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_stamp_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(
|
||||
r"titles/cxb/data/rss/Event/EventStampList.csv", encoding="shift-jis"
|
||||
r"titles/cxb/data/rev/Event/EventStampList.csv", encoding="shift-jis"
|
||||
) as event:
|
||||
lines = event.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_event_stamp_map_list_csxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_stamp_map_list_csxxxx_request(self, data: Dict) -> Dict:
|
||||
return {"data": "1,2,1,1,2,3,9,5,6,7,8,9,10,\r\n"}
|
||||
|
||||
def handle_data_server_state_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_server_state_request(self, data: Dict) -> Dict:
|
||||
return {"data": True}
|
||||
|
||||
+31
-31
@@ -17,11 +17,11 @@ class CxbRevSunriseS1(CxbBase):
|
||||
super().__init__(cfg, game_cfg)
|
||||
self.version = CxbConstants.VER_CROSSBEATS_REV_SUNRISE_S1
|
||||
|
||||
def handle_data_path_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_path_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss1/MusicArchiveList.csv") as music:
|
||||
lines = music.readlines()
|
||||
@@ -32,7 +32,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_detail_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_detail_request(self, data: Dict) -> Dict:
|
||||
# ItemListIcon load
|
||||
ret_str = "#ItemListIcon\r\n"
|
||||
with open(
|
||||
@@ -54,7 +54,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_shop_list_detail_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_detail_request(self, data: Dict) -> Dict:
|
||||
# ShopListIcon load
|
||||
ret_str = "#ShopListIcon\r\n"
|
||||
with open(
|
||||
@@ -119,26 +119,26 @@ class CxbRevSunriseS1(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_one_more_extra_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_one_more_extra_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_oexxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_oexxxx_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss1/NewsList.csv", encoding="UTF-8") as news:
|
||||
lines = news.readlines()
|
||||
@@ -146,14 +146,14 @@ class CxbRevSunriseS1(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_tips_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_tips_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_release_info_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_release_info_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_random_music_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_random_music_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss1/MusicArchiveList.csv") as music:
|
||||
lines = music.readlines()
|
||||
@@ -167,7 +167,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_license_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_license_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss1/License.csv", encoding="UTF-8") as licenses:
|
||||
lines = licenses.readlines()
|
||||
@@ -176,7 +176,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_course_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_course_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(
|
||||
r"titles/cxb/data/rss1/Course/CourseList.csv", encoding="UTF-8"
|
||||
@@ -187,7 +187,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_csxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_csxxxx_request(self, data: Dict) -> Dict:
|
||||
extra_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = ""
|
||||
with open(
|
||||
@@ -198,16 +198,16 @@ class CxbRevSunriseS1(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_mission_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_mission_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_mission_bonus_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_mission_bonus_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_unlimited_mission_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_unlimited_mission_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_partner_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_partner_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
# Lord forgive me for the sins I am about to commit
|
||||
for i in range(0, 10):
|
||||
@@ -226,7 +226,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_partnerxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_partnerxxxx_request(self, data: Dict) -> Dict:
|
||||
partner_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = f"{partner_num},,{partner_num},1,10000,\r\n"
|
||||
with open(r"titles/cxb/data/rss1/Partner0000.csv") as partner:
|
||||
@@ -235,13 +235,13 @@ class CxbRevSunriseS1(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_server_state_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_server_state_request(self, data: Dict) -> Dict:
|
||||
return {"data": True}
|
||||
|
||||
def handle_data_settings_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_settings_request(self, data: Dict) -> Dict:
|
||||
return {"data": "2,\r\n"}
|
||||
|
||||
def handle_data_story_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_story_list_request(self, data: Dict) -> Dict:
|
||||
# story id, story name, game version, start time, end time, course arc, unlock flag, song mcode for menu
|
||||
ret_str = "\r\n"
|
||||
ret_str += (
|
||||
@@ -253,23 +253,23 @@ class CxbRevSunriseS1(CxbBase):
|
||||
ret_str += f"st0002,REMNANT,10104,1502127790,4096483201,Cs1000,-1,overcl,\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_stxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_stxxxx_request(self, data: Dict) -> Dict:
|
||||
story_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = ""
|
||||
for i in range(1, 11):
|
||||
ret_str += f"{i},st000{story_num}_{i-1},,,,,,,,,,,,,,,,1,,-1,1,\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_event_stamp_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_stamp_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": "Cs1032,1,1,1,1,1,1,1,1,1,1,\r\n"}
|
||||
|
||||
def handle_data_premium_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_premium_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": "1,,,,10,,,,,99,,,,,,,,,100,,\r\n"}
|
||||
|
||||
def handle_data_event_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_detail_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_detail_list_request(self, data: Dict) -> Dict:
|
||||
event_id = data["dldate"]["filetype"].split("/")[2]
|
||||
if "EventStampMapListCs1002" in event_id:
|
||||
return {"data": "1,2,1,1,2,3,9,5,6,7,8,9,10,\r\n"}
|
||||
@@ -278,7 +278,7 @@ class CxbRevSunriseS1(CxbBase):
|
||||
else:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_stamp_map_list_csxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_stamp_map_list_csxxxx_request(self, data: Dict) -> Dict:
|
||||
event_id = data["dldate"]["filetype"].split("/")[2]
|
||||
if "EventStampMapListCs1002" in event_id:
|
||||
return {"data": "1,2,1,1,2,3,9,5,6,7,8,9,10,\r\n"}
|
||||
|
||||
+31
-31
@@ -17,11 +17,11 @@ class CxbRevSunriseS2(CxbBase):
|
||||
super().__init__(cfg, game_cfg)
|
||||
self.version = CxbConstants.VER_CROSSBEATS_REV_SUNRISE_S2_OMNI
|
||||
|
||||
def handle_data_path_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_path_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_music_list_request(self, data: Dict) -> Dict:
|
||||
version = data["dldate"]["filetype"].split("/")[0]
|
||||
ret_str = ""
|
||||
|
||||
@@ -41,7 +41,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_item_list_detail_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_item_list_detail_request(self, data: Dict) -> Dict:
|
||||
# ItemListIcon load
|
||||
ret_str = "#ItemListIcon\r\n"
|
||||
with open(
|
||||
@@ -63,7 +63,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_shop_list_detail_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_shop_list_detail_request(self, data: Dict) -> Dict:
|
||||
# ShopListIcon load
|
||||
ret_str = "#ShopListIcon\r\n"
|
||||
with open(
|
||||
@@ -128,7 +128,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_extra_stage_list_request(self, data: Dict) -> Dict:
|
||||
async 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()
|
||||
@@ -136,19 +136,19 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return({"data":ret_str})
|
||||
|
||||
def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_exxxxx_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_one_more_extra_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_one_more_extra_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_bonus_list10100_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_oexxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_oexxxx_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_free_coupon_request(self, data: Dict) -> Dict:
|
||||
async 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()
|
||||
@@ -157,7 +157,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return({"data":ret_str})
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_news_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss2/NewsList.csv", encoding="UTF-8") as news:
|
||||
lines = news.readlines()
|
||||
@@ -165,14 +165,14 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_tips_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_tips_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_release_info_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_release_info_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_random_music_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_random_music_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss2/MusicArchiveList.csv") as music:
|
||||
lines = music.readlines()
|
||||
@@ -186,7 +186,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_license_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_license_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(r"titles/cxb/data/rss2/License.csv", encoding="UTF-8") as licenses:
|
||||
lines = licenses.readlines()
|
||||
@@ -195,7 +195,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_course_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_course_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
with open(
|
||||
r"titles/cxb/data/rss2/Course/CourseList.csv", encoding="UTF-8"
|
||||
@@ -206,7 +206,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_csxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_csxxxx_request(self, data: Dict) -> Dict:
|
||||
extra_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = ""
|
||||
with open(
|
||||
@@ -217,16 +217,16 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_mission_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_mission_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_mission_bonus_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_mission_bonus_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_unlimited_mission_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_unlimited_mission_request(self, data: Dict) -> Dict:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_partner_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_partner_list_request(self, data: Dict) -> Dict:
|
||||
ret_str = ""
|
||||
# Lord forgive me for the sins I am about to commit
|
||||
for i in range(0, 10):
|
||||
@@ -245,7 +245,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
return {"data": ret_str}
|
||||
|
||||
@cached(lifetime=86400)
|
||||
def handle_data_partnerxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_partnerxxxx_request(self, data: Dict) -> Dict:
|
||||
partner_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = f"{partner_num},,{partner_num},1,10000,\r\n"
|
||||
with open(r"titles/cxb/data/rss2/Partner0000.csv") as partner:
|
||||
@@ -254,13 +254,13 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_server_state_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_server_state_request(self, data: Dict) -> Dict:
|
||||
return {"data": True}
|
||||
|
||||
def handle_data_settings_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_settings_request(self, data: Dict) -> Dict:
|
||||
return {"data": "2,\r\n"}
|
||||
|
||||
def handle_data_story_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_story_list_request(self, data: Dict) -> Dict:
|
||||
# story id, story name, game version, start time, end time, course arc, unlock flag, song mcode for menu
|
||||
ret_str = "\r\n"
|
||||
ret_str += (
|
||||
@@ -272,7 +272,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"st0002,REMNANT,10104,1502127790,4096483201,Cs1000,-1,overcl,\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_stxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_stxxxx_request(self, data: Dict) -> Dict:
|
||||
story_num = int(data["dldate"]["filetype"][-4:])
|
||||
ret_str = ""
|
||||
# Each stories appears to have 10 pieces based on the wiki but as on how they are set.... no clue
|
||||
@@ -280,18 +280,18 @@ class CxbRevSunriseS2(CxbBase):
|
||||
ret_str += f"{i},st000{story_num}_{i-1},,,,,,,,,,,,,,,,1,,-1,1,\r\n"
|
||||
return {"data": ret_str}
|
||||
|
||||
def handle_data_event_stamp_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_stamp_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": "Cs1002,1,1,1,1,1,1,1,1,1,1,\r\n"}
|
||||
|
||||
def handle_data_premium_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_premium_list_request(self, data: Dict) -> Dict:
|
||||
return {"data": "1,,,,10,,,,,99,,,,,,,,,100,,\r\n"}
|
||||
|
||||
def handle_data_event_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_list_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"data": "Cs4001,0,10000,1601510400,1604188799,1,nv2006,1,\r\nCs4005,0,10000,1609459200,1615766399,1,nv2006,1,\r\n"
|
||||
}
|
||||
|
||||
def handle_data_event_detail_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_detail_list_request(self, data: Dict) -> Dict:
|
||||
event_id = data["dldate"]["filetype"].split("/")[2]
|
||||
if "Cs4001" in event_id:
|
||||
return {
|
||||
@@ -308,7 +308,7 @@ class CxbRevSunriseS2(CxbBase):
|
||||
else:
|
||||
return {"data": ""}
|
||||
|
||||
def handle_data_event_stamp_map_list_csxxxx_request(self, data: Dict) -> Dict:
|
||||
async def handle_data_event_stamp_map_list_csxxxx_request(self, data: Dict) -> Dict:
|
||||
event_id = data["dldate"]["filetype"].split("/")[2]
|
||||
if "EventStampMapListCs1002" in event_id:
|
||||
return {"data": "1,2,1,1,2,3,9,5,6,7,8,9,10,\r\n"}
|
||||
|
||||
@@ -19,12 +19,12 @@ energy = Table(
|
||||
|
||||
|
||||
class CxbItemData(BaseData):
|
||||
def put_energy(self, user_id: int, rev_energy: int) -> Optional[int]:
|
||||
async def put_energy(self, user_id: int, rev_energy: int) -> Optional[int]:
|
||||
sql = insert(energy).values(user=user_id, energy=rev_energy)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(energy=rev_energy)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to insert item! user: {user_id}, energy: {rev_energy}"
|
||||
@@ -33,10 +33,10 @@ class CxbItemData(BaseData):
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
def get_energy(self, user_id: int) -> Optional[Dict]:
|
||||
async def get_energy(self, user_id: int) -> Optional[Dict]:
|
||||
sql = energy.select(and_(energy.c.user == user_id))
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
@@ -21,7 +21,7 @@ profile = Table(
|
||||
|
||||
|
||||
class CxbProfileData(BaseData):
|
||||
def put_profile(
|
||||
async def put_profile(
|
||||
self, user_id: int, version: int, index: int, data: JSON
|
||||
) -> Optional[int]:
|
||||
sql = insert(profile).values(
|
||||
@@ -30,7 +30,7 @@ class CxbProfileData(BaseData):
|
||||
|
||||
conflict = sql.on_duplicate_key_update(index=index, data=data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to update! user: {user_id}, index: {index}, data: {data}"
|
||||
@@ -39,7 +39,7 @@ class CxbProfileData(BaseData):
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
def get_profile(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
async def get_profile(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
"""
|
||||
Given a game version and either a profile or aime id, return the profile
|
||||
"""
|
||||
@@ -47,12 +47,12 @@ class CxbProfileData(BaseData):
|
||||
and_(profile.c.version == version, profile.c.user == aime_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_profile_index(
|
||||
async def get_profile_index(
|
||||
self, index: int, aime_id: int = None, version: int = None
|
||||
) -> Optional[Dict]:
|
||||
"""
|
||||
@@ -72,7 +72,7 @@ class CxbProfileData(BaseData):
|
||||
)
|
||||
return None
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
+12
-12
@@ -58,7 +58,7 @@ ranking = Table(
|
||||
|
||||
|
||||
class CxbScoreData(BaseData):
|
||||
def put_best_score(
|
||||
async def put_best_score(
|
||||
self,
|
||||
user_id: int,
|
||||
song_mcode: str,
|
||||
@@ -79,7 +79,7 @@ class CxbScoreData(BaseData):
|
||||
|
||||
conflict = sql.on_duplicate_key_update(data=sql.inserted.data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to insert best score! profile: {user_id}, song: {song_mcode}, data: {data}"
|
||||
@@ -88,7 +88,7 @@ class CxbScoreData(BaseData):
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
def put_playlog(
|
||||
async def put_playlog(
|
||||
self,
|
||||
user_id: int,
|
||||
song_mcode: str,
|
||||
@@ -125,7 +125,7 @@ class CxbScoreData(BaseData):
|
||||
combo=combo,
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to insert playlog! profile: {user_id}, song: {song_mcode}, chart: {chart_id}"
|
||||
@@ -134,7 +134,7 @@ class CxbScoreData(BaseData):
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
def put_ranking(
|
||||
async def put_ranking(
|
||||
self, user_id: int, rev_id: int, song_id: int, score: int, clear: int
|
||||
) -> Optional[int]:
|
||||
"""
|
||||
@@ -151,7 +151,7 @@ class CxbScoreData(BaseData):
|
||||
|
||||
conflict = sql.on_duplicate_key_update(score=score)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} failed to insert ranking log! profile: {user_id}, score: {score}, clear: {clear}"
|
||||
@@ -160,28 +160,28 @@ class CxbScoreData(BaseData):
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
def get_best_score(self, user_id: int, song_mcode: int) -> Optional[Dict]:
|
||||
async def get_best_score(self, user_id: int, song_mcode: int) -> Optional[Dict]:
|
||||
sql = score.select(
|
||||
and_(score.c.user == user_id, score.c.song_mcode == song_mcode)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_best_scores(self, user_id: int) -> Optional[Dict]:
|
||||
async def get_best_scores(self, user_id: int) -> Optional[Dict]:
|
||||
sql = score.select(score.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_best_rankings(self, user_id: int) -> Optional[List[Dict]]:
|
||||
async def get_best_rankings(self, user_id: int) -> Optional[List[Dict]]:
|
||||
sql = ranking.select(ranking.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
@@ -29,7 +29,7 @@ music = Table(
|
||||
|
||||
|
||||
class CxbStaticData(BaseData):
|
||||
def put_music(
|
||||
async def put_music(
|
||||
self,
|
||||
version: int,
|
||||
mcode: str,
|
||||
@@ -55,12 +55,12 @@ class CxbStaticData(BaseData):
|
||||
title=title, artist=artist, category=category, level=level
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_music(
|
||||
async def get_music(
|
||||
self, version: int, song_id: Optional[int] = None
|
||||
) -> Optional[List[Row]]:
|
||||
if song_id is None:
|
||||
@@ -73,12 +73,12 @@ class CxbStaticData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_music_chart(
|
||||
async def get_music_chart(
|
||||
self, version: int, song_id: int, chart_id: int
|
||||
) -> Optional[List[Row]]:
|
||||
sql = select(music).where(
|
||||
@@ -89,7 +89,7 @@ class CxbStaticData(BaseData):
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
@@ -7,4 +7,3 @@ index = DivaServlet
|
||||
database = DivaData
|
||||
reader = DivaReader
|
||||
game_codes = [DivaConstants.GAME_CODE]
|
||||
current_schema_version = 6
|
||||
|
||||
+87
-88
@@ -1,8 +1,7 @@
|
||||
import datetime
|
||||
from typing import Any, List, Dict
|
||||
from typing import Dict
|
||||
import logging
|
||||
import json
|
||||
import urllib
|
||||
import urllib.parse
|
||||
from threading import Thread
|
||||
|
||||
from core.config import CoreConfig
|
||||
@@ -24,13 +23,13 @@ class DivaBase:
|
||||
dt = datetime.datetime.now()
|
||||
self.time_lut = urllib.parse.quote(dt.strftime("%Y-%m-%d %H:%M:%S:16.0"))
|
||||
|
||||
def handle_test_request(self, data: Dict) -> Dict:
|
||||
async def handle_test_request(self, data: Dict) -> Dict:
|
||||
return ""
|
||||
|
||||
def handle_game_init_request(self, data: Dict) -> Dict:
|
||||
async def handle_game_init_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_attend_request(self, data: Dict) -> Dict:
|
||||
async def handle_attend_request(self, data: Dict) -> Dict:
|
||||
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",
|
||||
@@ -44,7 +43,7 @@ class DivaBase:
|
||||
|
||||
return encoded
|
||||
|
||||
def handle_ping_request(self, data: Dict) -> Dict:
|
||||
async def handle_ping_request(self, data: Dict) -> Dict:
|
||||
encoded = "&"
|
||||
params = {
|
||||
"ping_b_msg": f"Welcome to {self.core_cfg.server.name} network!",
|
||||
@@ -89,7 +88,7 @@ class DivaBase:
|
||||
|
||||
return encoded
|
||||
|
||||
def handle_pv_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_pv_list_request(self, data: Dict) -> Dict:
|
||||
pvlist = ""
|
||||
with open(r"titles/diva/data/PvList0.dat", encoding="utf-8") as shop:
|
||||
lines = shop.readlines()
|
||||
@@ -126,10 +125,10 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_shop_catalog_request(self, data: Dict) -> Dict:
|
||||
async def handle_shop_catalog_request(self, data: Dict) -> Dict:
|
||||
catalog = ""
|
||||
|
||||
shopList = self.data.static.get_enabled_shops(self.version)
|
||||
shopList = await self.data.static.get_enabled_shops(self.version)
|
||||
if not shopList:
|
||||
with open(r"titles/diva/data/ShopCatalog.dat", encoding="utf-8") as shop:
|
||||
lines = shop.readlines()
|
||||
@@ -164,9 +163,9 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_buy_module_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
module = self.data.static.get_enabled_shop(self.version, int(data["mdl_id"]))
|
||||
async def handle_buy_module_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
module = await self.data.static.get_enabled_shop(self.version, int(data["mdl_id"]))
|
||||
|
||||
# make sure module is available to purchase
|
||||
if not module:
|
||||
@@ -178,11 +177,11 @@ class DivaBase:
|
||||
|
||||
new_vcld_pts = profile["vcld_pts"] - int(data["mdl_price"])
|
||||
|
||||
self.data.profile.update_profile(profile["user"], vcld_pts=new_vcld_pts)
|
||||
self.data.module.put_module(data["pd_id"], self.version, data["mdl_id"])
|
||||
await self.data.profile.update_profile(profile["user"], vcld_pts=new_vcld_pts)
|
||||
await self.data.module.put_module(data["pd_id"], self.version, data["mdl_id"])
|
||||
|
||||
# generate the mdl_have string
|
||||
mdl_have = self.data.module.get_modules_have_string(data["pd_id"], self.version)
|
||||
mdl_have = await self.data.module.get_modules_have_string(data["pd_id"], self.version)
|
||||
|
||||
response = "&shp_rslt=1"
|
||||
response += f"&mdl_id={data['mdl_id']}"
|
||||
@@ -191,10 +190,10 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_cstmz_itm_ctlg_request(self, data: Dict) -> Dict:
|
||||
async def handle_cstmz_itm_ctlg_request(self, data: Dict) -> Dict:
|
||||
catalog = ""
|
||||
|
||||
itemList = self.data.static.get_enabled_items(self.version)
|
||||
itemList = await self.data.static.get_enabled_items(self.version)
|
||||
if not itemList:
|
||||
with open(r"titles/diva/data/ItemCatalog.dat", encoding="utf-8") as item:
|
||||
lines = item.readlines()
|
||||
@@ -229,9 +228,9 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_buy_cstmz_itm_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
item = self.data.static.get_enabled_item(
|
||||
async def handle_buy_cstmz_itm_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
item = await self.data.static.get_enabled_item(
|
||||
self.version, int(data["cstmz_itm_id"])
|
||||
)
|
||||
|
||||
@@ -246,14 +245,14 @@ class DivaBase:
|
||||
new_vcld_pts = profile["vcld_pts"] - int(data["cstmz_itm_price"])
|
||||
|
||||
# save new Vocaloid Points balance
|
||||
self.data.profile.update_profile(profile["user"], vcld_pts=new_vcld_pts)
|
||||
await self.data.profile.update_profile(profile["user"], vcld_pts=new_vcld_pts)
|
||||
|
||||
self.data.customize.put_customize_item(
|
||||
await self.data.customize.put_customize_item(
|
||||
data["pd_id"], self.version, data["cstmz_itm_id"]
|
||||
)
|
||||
|
||||
# generate the cstmz_itm_have string
|
||||
cstmz_itm_have = self.data.customize.get_customize_items_have_string(
|
||||
cstmz_itm_have = await self.data.customize.get_customize_items_have_string(
|
||||
data["pd_id"], self.version
|
||||
)
|
||||
|
||||
@@ -264,7 +263,7 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_festa_info_request(self, data: Dict) -> Dict:
|
||||
async def handle_festa_info_request(self, data: Dict) -> Dict:
|
||||
encoded = "&"
|
||||
params = {
|
||||
"fi_id": "1,2",
|
||||
@@ -287,7 +286,7 @@ class DivaBase:
|
||||
|
||||
return encoded
|
||||
|
||||
def handle_contest_info_request(self, data: Dict) -> Dict:
|
||||
async def handle_contest_info_request(self, data: Dict) -> Dict:
|
||||
response = ""
|
||||
|
||||
response += f"&ci_lut={self.time_lut}"
|
||||
@@ -295,10 +294,10 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_qst_inf_request(self, data: Dict) -> Dict:
|
||||
async def handle_qst_inf_request(self, data: Dict) -> Dict:
|
||||
quest = ""
|
||||
|
||||
questList = self.data.static.get_enabled_quests(self.version)
|
||||
questList = await self.data.static.get_enabled_quests(self.version)
|
||||
if not questList:
|
||||
with open(r"titles/diva/data/QuestInfo.dat", encoding="utf-8") as shop:
|
||||
lines = shop.readlines()
|
||||
@@ -345,45 +344,45 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_nv_ranking_request(self, data: Dict) -> Dict:
|
||||
async def handle_nv_ranking_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_ps_ranking_request(self, data: Dict) -> Dict:
|
||||
async def handle_ps_ranking_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_ng_word_request(self, data: Dict) -> Dict:
|
||||
async def handle_ng_word_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_rmt_wp_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_rmt_wp_list_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_pv_def_chr_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_pv_def_chr_list_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_pv_ng_mdl_list_request(self, data: Dict) -> Dict:
|
||||
async def handle_pv_ng_mdl_list_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_cstmz_itm_ng_mdl_lst_request(self, data: Dict) -> Dict:
|
||||
async def handle_cstmz_itm_ng_mdl_lst_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_banner_info_request(self, data: Dict) -> Dict:
|
||||
async def handle_banner_info_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_banner_data_request(self, data: Dict) -> Dict:
|
||||
async def handle_banner_data_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_cm_ply_info_request(self, data: Dict) -> Dict:
|
||||
async def handle_cm_ply_info_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_pstd_h_ctrl_request(self, data: Dict) -> Dict:
|
||||
async def handle_pstd_h_ctrl_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_pstd_item_ng_lst_request(self, data: Dict) -> Dict:
|
||||
async def handle_pstd_item_ng_lst_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
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)
|
||||
async def handle_pre_start_request(self, data: Dict) -> str:
|
||||
profile = await self.data.profile.get_profile(data["aime_id"], self.version)
|
||||
profile_shop = await self.data.item.get_shop(data["aime_id"], self.version)
|
||||
|
||||
if profile is None:
|
||||
return f"&ps_result=-3"
|
||||
@@ -422,29 +421,29 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_registration_request(self, data: Dict) -> Dict:
|
||||
self.data.profile.create_profile(
|
||||
async def handle_registration_request(self, data: Dict) -> Dict:
|
||||
await self.data.profile.create_profile(
|
||||
self.version, data["aime_id"], data["player_name"]
|
||||
)
|
||||
return f"&cd_adm_result=1&pd_id={data['aime_id']}"
|
||||
|
||||
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)
|
||||
async def handle_start_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
profile_shop = await self.data.item.get_shop(data["pd_id"], self.version)
|
||||
if profile is None:
|
||||
return
|
||||
|
||||
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(
|
||||
mdl_have = await self.data.module.get_modules_have_string(
|
||||
data["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(
|
||||
cstmz_itm_have = await self.data.customize.get_customize_items_have_string(
|
||||
data["pd_id"], self.version
|
||||
)
|
||||
|
||||
@@ -525,7 +524,7 @@ class DivaBase:
|
||||
}
|
||||
|
||||
# get clear status from user scores
|
||||
pv_records = self.data.score.get_best_scores(data["pd_id"])
|
||||
pv_records = await self.data.score.get_best_scores(data["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:
|
||||
@@ -583,11 +582,11 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_pd_unlock_request(self, data: Dict) -> Dict:
|
||||
async 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)
|
||||
async def handle_spend_credit_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
if profile is None:
|
||||
return
|
||||
|
||||
@@ -664,30 +663,30 @@ class DivaBase:
|
||||
|
||||
return pv_result
|
||||
|
||||
def task_generateScoreData(self, data: Dict, pd_by_pv_id, song):
|
||||
async def task_generateScoreData(self, data: Dict, pd_by_pv_id, song):
|
||||
|
||||
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(
|
||||
pd_db_song_0 = await self.data.score.get_best_user_score(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=0
|
||||
)
|
||||
pd_db_song_1 = self.data.score.get_best_user_score(
|
||||
pd_db_song_1 = await self.data.score.get_best_user_score(
|
||||
data["pd_id"], int(song), data["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(
|
||||
pd_db_ranking_0 = await self.data.score.get_global_ranking(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=0
|
||||
)
|
||||
|
||||
if pd_db_song_1:
|
||||
pd_db_ranking_1 = self.data.score.get_global_ranking(
|
||||
pd_db_ranking_1 = await self.data.score.get_global_ranking(
|
||||
data["pd_id"], int(song), data["difficulty"], edition=1
|
||||
)
|
||||
|
||||
pd_db_customize = self.data.pv_customize.get_pv_customize(
|
||||
pd_db_customize = await self.data.pv_customize.get_pv_customize(
|
||||
data["pd_id"], int(song)
|
||||
)
|
||||
|
||||
@@ -705,7 +704,7 @@ class DivaBase:
|
||||
pd_by_pv_id.append(urllib.parse.quote(f"{song}***"))
|
||||
pd_by_pv_id.append(",")
|
||||
|
||||
def handle_get_pv_pd_request(self, data: Dict) -> Dict:
|
||||
async def handle_get_pv_pd_request(self, data: Dict) -> Dict:
|
||||
song_id = data["pd_pv_id_lst"].split(",")
|
||||
pv = ""
|
||||
|
||||
@@ -713,7 +712,7 @@ class DivaBase:
|
||||
pd_by_pv_id = []
|
||||
|
||||
for song in song_id:
|
||||
thread_ScoreData = Thread(target=self.task_generateScoreData(data, pd_by_pv_id, song))
|
||||
thread_ScoreData = Thread(target=await self.task_generateScoreData(data, pd_by_pv_id, song))
|
||||
threads.append(thread_ScoreData)
|
||||
|
||||
for x in threads:
|
||||
@@ -732,11 +731,11 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_stage_start_request(self, data: Dict) -> Dict:
|
||||
async def handle_stage_start_request(self, data: Dict) -> Dict:
|
||||
return f""
|
||||
|
||||
def handle_stage_result_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
async def handle_stage_result_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
|
||||
pd_song_list = data["stg_ply_pv_id"].split(",")
|
||||
pd_song_difficulty = data["stg_difficulty"].split(",")
|
||||
@@ -754,14 +753,14 @@ class DivaBase:
|
||||
|
||||
for index, value in enumerate(pd_song_list):
|
||||
if "-1" not in pd_song_list[index]:
|
||||
profile_pd_db_song = self.data.score.get_best_user_score(
|
||||
profile_pd_db_song = await self.data.score.get_best_user_score(
|
||||
data["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(
|
||||
await self.data.score.put_best_score(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
pd_song_list[index],
|
||||
@@ -778,7 +777,7 @@ class DivaBase:
|
||||
pd_song_worst_cnt[index],
|
||||
pd_song_max_combo[index],
|
||||
)
|
||||
self.data.score.put_playlog(
|
||||
await self.data.score.put_playlog(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
pd_song_list[index],
|
||||
@@ -796,7 +795,7 @@ class DivaBase:
|
||||
pd_song_max_combo[index],
|
||||
)
|
||||
elif int(pd_song_max_score[index]) >= int(profile_pd_db_song["score"]):
|
||||
self.data.score.put_best_score(
|
||||
await self.data.score.put_best_score(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
pd_song_list[index],
|
||||
@@ -813,7 +812,7 @@ class DivaBase:
|
||||
pd_song_worst_cnt[index],
|
||||
pd_song_max_combo[index],
|
||||
)
|
||||
self.data.score.put_playlog(
|
||||
await self.data.score.put_playlog(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
pd_song_list[index],
|
||||
@@ -831,7 +830,7 @@ class DivaBase:
|
||||
pd_song_max_combo[index],
|
||||
)
|
||||
elif int(pd_song_max_score[index]) != int(profile_pd_db_song["score"]):
|
||||
self.data.score.put_playlog(
|
||||
await self.data.score.put_playlog(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
pd_song_list[index],
|
||||
@@ -852,7 +851,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 = await self.data.score.get_best_scores(data["pd_id"])
|
||||
|
||||
total_atn_pnt = 0
|
||||
for best_score in best_scores:
|
||||
@@ -866,7 +865,7 @@ class DivaBase:
|
||||
response += f"&lv_pnt_old={int(profile['lv_pnt'])}"
|
||||
|
||||
# update the profile and commit changes to the db
|
||||
self.data.profile.update_profile(
|
||||
await self.data.profile.update_profile(
|
||||
profile["user"],
|
||||
lv_num=new_level,
|
||||
lv_pnt=new_level_pnt,
|
||||
@@ -914,16 +913,16 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_end_request(self, data: Dict) -> Dict:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
async def handle_end_request(self, data: Dict) -> Dict:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
|
||||
self.data.profile.update_profile(
|
||||
await self.data.profile.update_profile(
|
||||
profile["user"], my_qst_id=data["my_qst_id"], my_qst_sts=data["my_qst_sts"]
|
||||
)
|
||||
return f""
|
||||
|
||||
def handle_shop_exit_request(self, data: Dict) -> Dict:
|
||||
self.data.item.put_shop(
|
||||
async def handle_shop_exit_request(self, data: Dict) -> Dict:
|
||||
await self.data.item.put_shop(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
data["mdl_eqp_cmn_ary"],
|
||||
@@ -931,7 +930,7 @@ class DivaBase:
|
||||
data["ms_itm_flg_cmn_ary"],
|
||||
)
|
||||
if int(data["use_pv_mdl_eqp"]) == 1:
|
||||
self.data.pv_customize.put_pv_customize(
|
||||
await self.data.pv_customize.put_pv_customize(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
data["ply_pv_id"],
|
||||
@@ -940,7 +939,7 @@ class DivaBase:
|
||||
data["ms_itm_flg_pv_ary"],
|
||||
)
|
||||
else:
|
||||
self.data.pv_customize.put_pv_customize(
|
||||
await self.data.pv_customize.put_pv_customize(
|
||||
data["pd_id"],
|
||||
self.version,
|
||||
data["ply_pv_id"],
|
||||
@@ -952,8 +951,8 @@ class DivaBase:
|
||||
response = "&shp_rslt=1"
|
||||
return response
|
||||
|
||||
def handle_card_procedure_request(self, data: Dict) -> str:
|
||||
profile = self.data.profile.get_profile(data["aime_id"], self.version)
|
||||
async def handle_card_procedure_request(self, data: Dict) -> str:
|
||||
profile = await self.data.profile.get_profile(data["aime_id"], self.version)
|
||||
if profile is None:
|
||||
return "&cd_adm_result=0"
|
||||
|
||||
@@ -972,8 +971,8 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_change_name_request(self, data: Dict) -> str:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
async def handle_change_name_request(self, data: Dict) -> str:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
|
||||
# make sure user has enough Vocaloid Points
|
||||
if profile["vcld_pts"] < int(data["chg_name_price"]):
|
||||
@@ -981,7 +980,7 @@ class DivaBase:
|
||||
|
||||
# update the vocaloid points and player name
|
||||
new_vcld_pts = profile["vcld_pts"] - int(data["chg_name_price"])
|
||||
self.data.profile.update_profile(
|
||||
await self.data.profile.update_profile(
|
||||
profile["user"], player_name=data["player_name"], vcld_pts=new_vcld_pts
|
||||
)
|
||||
|
||||
@@ -992,15 +991,15 @@ class DivaBase:
|
||||
|
||||
return response
|
||||
|
||||
def handle_change_passwd_request(self, data: Dict) -> str:
|
||||
profile = self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
async def handle_change_passwd_request(self, data: Dict) -> str:
|
||||
profile = await self.data.profile.get_profile(data["pd_id"], self.version)
|
||||
|
||||
# TODO: return correct error number instead of 0
|
||||
if data["passwd"] != profile["passwd"]:
|
||||
return "&cd_adm_result=0"
|
||||
|
||||
# set password to true and update the saved password
|
||||
self.data.profile.update_profile(
|
||||
await self.data.profile.update_profile(
|
||||
profile["user"], passwd_stat=1, passwd=data["new_passwd"]
|
||||
)
|
||||
|
||||
|
||||
+18
-28
@@ -1,4 +1,6 @@
|
||||
from twisted.web.http import Request
|
||||
from starlette.requests import Request
|
||||
from starlette.responses import PlainTextResponse
|
||||
from starlette.routing import Route
|
||||
import yaml
|
||||
import logging, coloredlogs
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
@@ -51,17 +53,16 @@ class DivaServlet(BaseServlet):
|
||||
level=self.game_cfg.server.loglevel, logger=self.logger, fmt=log_fmt_str
|
||||
)
|
||||
|
||||
def get_endpoint_matchers(self) -> Tuple[List[Tuple[str, str, Dict]], List[Tuple[str, str, Dict]]]:
|
||||
return (
|
||||
[],
|
||||
[("render_POST", "/DivaServlet/", {})]
|
||||
)
|
||||
def get_routes(self) -> List[Route]:
|
||||
return [
|
||||
Route("/DivaServlet/", self.render_POST, methods=['POST'])
|
||||
]
|
||||
|
||||
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.server.hostname}:{Utils.get_title_port(self.core_cfg)}/DivaServlet/", self.core_cfg.server.hostname)
|
||||
|
||||
return (f"http://{self.core_cfg.title.hostname}/DivaServlet/", self.core_cfg.title.hostname)
|
||||
return (f"http://{self.core_cfg.server.hostname}/DivaServlet/", self.core_cfg.server.hostname)
|
||||
|
||||
@classmethod
|
||||
def is_game_enabled(
|
||||
@@ -78,9 +79,9 @@ class DivaServlet(BaseServlet):
|
||||
|
||||
return True
|
||||
|
||||
def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
req_raw = request.content.getvalue()
|
||||
url_header = request.getAllHeaders()
|
||||
async def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes:
|
||||
req_raw = await request.body()
|
||||
url_header = request.headers
|
||||
|
||||
# Ping Dispatch
|
||||
if "THIS_STRING_SEPARATES" in str(url_header):
|
||||
@@ -103,9 +104,7 @@ class DivaServlet(BaseServlet):
|
||||
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"
|
||||
)
|
||||
return PlainTextResponse(f"cmd={bin_req_data['cmd']}&req_id={bin_req_data['req_id']}&stat=ok{resp}")
|
||||
|
||||
# Main Dispatch
|
||||
json_string = json.dumps(
|
||||
@@ -122,7 +121,7 @@ class DivaServlet(BaseServlet):
|
||||
) # Decompressing the gzip
|
||||
except zlib.error as e:
|
||||
self.logger.error(f"Failed to defalte! {e} -> {gz_string}")
|
||||
return "stat=0"
|
||||
return PlainTextResponse("stat=0")
|
||||
|
||||
req_kvp = urllib.parse.unquote(url_data)
|
||||
req_data = {}
|
||||
@@ -141,27 +140,18 @@ class DivaServlet(BaseServlet):
|
||||
# Load the requests
|
||||
try:
|
||||
handler = getattr(self.base, func_to_find)
|
||||
resp = handler(req_data)
|
||||
resp = await 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"
|
||||
)
|
||||
return PlainTextResponse(f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok")
|
||||
|
||||
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"
|
||||
)
|
||||
return PlainTextResponse(f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok")
|
||||
|
||||
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}"
|
||||
)
|
||||
|
||||
return (
|
||||
f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok{resp}".encode(
|
||||
"utf-8"
|
||||
)
|
||||
)
|
||||
return PlainTextResponse(f"cmd={req_data['cmd']}&req_id={req_data['req_id']}&stat=ok{resp}")
|
||||
|
||||
+14
-14
@@ -28,7 +28,7 @@ class DivaReader(BaseReader):
|
||||
self.logger.error(f"Invalid project diva version {version}")
|
||||
exit(1)
|
||||
|
||||
def read(self) -> None:
|
||||
async def read(self) -> None:
|
||||
pull_bin_ram = True
|
||||
pull_bin_rom = True
|
||||
pull_opt_rom = True
|
||||
@@ -48,14 +48,14 @@ class DivaReader(BaseReader):
|
||||
self.logger.warning("No option directory specified, skipping")
|
||||
|
||||
if pull_bin_ram:
|
||||
self.read_ram(f"{self.bin_dir}/ram")
|
||||
await self.read_ram(f"{self.bin_dir}/ram")
|
||||
if pull_bin_rom:
|
||||
self.read_rom(f"{self.bin_dir}/rom")
|
||||
await self.read_rom(f"{self.bin_dir}/rom")
|
||||
if pull_opt_rom:
|
||||
for dir in opt_dirs:
|
||||
self.read_rom(f"{dir}/rom")
|
||||
await self.read_rom(f"{dir}/rom")
|
||||
|
||||
def read_ram(self, ram_root_dir: str) -> None:
|
||||
async def read_ram(self, ram_root_dir: str) -> None:
|
||||
self.logger.info(f"Read RAM from {ram_root_dir}")
|
||||
|
||||
if path.exists(f"{ram_root_dir}/databank"):
|
||||
@@ -91,7 +91,7 @@ class DivaReader(BaseReader):
|
||||
f"Added shop item {split[x+0]}"
|
||||
)
|
||||
|
||||
self.data.static.put_shop(
|
||||
await self.data.static.put_shop(
|
||||
self.version,
|
||||
split[x + 0],
|
||||
split[x + 2],
|
||||
@@ -109,7 +109,7 @@ class DivaReader(BaseReader):
|
||||
for x in range(0, len(split), 7):
|
||||
self.logger.info(f"Added item {split[x+0]}")
|
||||
|
||||
self.data.static.put_items(
|
||||
await self.data.static.put_items(
|
||||
self.version,
|
||||
split[x + 0],
|
||||
split[x + 2],
|
||||
@@ -123,7 +123,7 @@ class DivaReader(BaseReader):
|
||||
elif file.startswith("QuestInfo") and len(split) >= 9:
|
||||
self.logger.info(f"Added quest {split[0]}")
|
||||
|
||||
self.data.static.put_quests(
|
||||
await self.data.static.put_quests(
|
||||
self.version,
|
||||
split[0],
|
||||
split[6],
|
||||
@@ -141,7 +141,7 @@ class DivaReader(BaseReader):
|
||||
else:
|
||||
self.logger.warning(f"Databank folder not found in {ram_root_dir}, skipping")
|
||||
|
||||
def read_rom(self, rom_root_dir: str) -> None:
|
||||
async def read_rom(self, rom_root_dir: str) -> None:
|
||||
self.logger.info(f"Read ROM from {rom_root_dir}")
|
||||
pv_list: Dict[str, Dict] = {}
|
||||
|
||||
@@ -199,7 +199,7 @@ class DivaReader(BaseReader):
|
||||
diff = pv_data["difficulty"]["easy"]["0"]["level"].split("_")
|
||||
self.logger.info(f"Added song {song_id} chart 0")
|
||||
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
0,
|
||||
@@ -220,7 +220,7 @@ class DivaReader(BaseReader):
|
||||
diff = pv_data["difficulty"]["normal"]["0"]["level"].split("_")
|
||||
self.logger.info(f"Added song {song_id} chart 1")
|
||||
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
1,
|
||||
@@ -238,7 +238,7 @@ class DivaReader(BaseReader):
|
||||
diff = pv_data["difficulty"]["hard"]["0"]["level"].split("_")
|
||||
self.logger.info(f"Added song {song_id} chart 2")
|
||||
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
2,
|
||||
@@ -257,7 +257,7 @@ class DivaReader(BaseReader):
|
||||
diff = pv_data["difficulty"]["extreme"]["0"]["level"].split("_")
|
||||
self.logger.info(f"Added song {song_id} chart 3")
|
||||
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
3,
|
||||
@@ -275,7 +275,7 @@ class DivaReader(BaseReader):
|
||||
diff = pv_data["difficulty"]["extreme"]["1"]["level"].split("_")
|
||||
self.logger.info(f"Added song {song_id} chart 4")
|
||||
|
||||
self.data.static.put_music(
|
||||
await self.data.static.put_music(
|
||||
self.version,
|
||||
song_id,
|
||||
4,
|
||||
|
||||
@@ -25,10 +25,10 @@ customize = Table(
|
||||
|
||||
|
||||
class DivaCustomizeItemData(BaseData):
|
||||
def put_customize_item(self, aime_id: int, version: int, item_id: int) -> None:
|
||||
async def put_customize_item(self, aime_id: int, version: int, item_id: int) -> None:
|
||||
sql = insert(customize).values(version=version, user=aime_id, item_id=item_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} Failed to insert diva profile customize item! aime id: {aime_id} item: {item_id}"
|
||||
@@ -36,7 +36,7 @@ class DivaCustomizeItemData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_customize_items(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
async def get_customize_items(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
"""
|
||||
Given a game version and an aime id, return all the customize items, not used directly
|
||||
"""
|
||||
@@ -44,12 +44,12 @@ class DivaCustomizeItemData(BaseData):
|
||||
and_(customize.c.version == version, customize.c.user == aime_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_customize_items_have_string(self, aime_id: int, version: int) -> str:
|
||||
async def get_customize_items_have_string(self, aime_id: int, version: int) -> str:
|
||||
"""
|
||||
Given a game version and an aime id, return the cstmz_itm_have hex string
|
||||
required for diva directly
|
||||
|
||||
@@ -26,7 +26,7 @@ shop = Table(
|
||||
|
||||
|
||||
class DivaItemData(BaseData):
|
||||
def put_shop(
|
||||
async def put_shop(
|
||||
self,
|
||||
aime_id: int,
|
||||
version: int,
|
||||
@@ -48,7 +48,7 @@ class DivaItemData(BaseData):
|
||||
ms_itm_flg_ary=ms_itm_flg_ary,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} Failed to insert diva profile! aime id: {aime_id} array: {mdl_eqp_ary}"
|
||||
@@ -56,13 +56,13 @@ class DivaItemData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_shop(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
async def get_shop(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
"""
|
||||
Given a game version and either a profile or aime id, return the profile
|
||||
"""
|
||||
sql = shop.select(and_(shop.c.version == version, shop.c.user == aime_id))
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
@@ -23,10 +23,10 @@ module = Table(
|
||||
|
||||
|
||||
class DivaModuleData(BaseData):
|
||||
def put_module(self, aime_id: int, version: int, module_id: int) -> None:
|
||||
async def put_module(self, aime_id: int, version: int, module_id: int) -> None:
|
||||
sql = insert(module).values(version=version, user=aime_id, module_id=module_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} Failed to insert diva profile module! aime id: {aime_id} module: {module_id}"
|
||||
@@ -34,18 +34,18 @@ class DivaModuleData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_modules(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
async def get_modules(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
"""
|
||||
Given a game version and an aime id, return all the modules, not used directly
|
||||
"""
|
||||
sql = module.select(and_(module.c.version == version, module.c.user == aime_id))
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_modules_have_string(self, aime_id: int, version: int) -> str:
|
||||
async def get_modules_have_string(self, aime_id: int, version: int) -> str:
|
||||
"""
|
||||
Given a game version and an aime id, return the mdl_have hex string
|
||||
required for diva directly
|
||||
|
||||
@@ -70,7 +70,7 @@ profile = Table(
|
||||
|
||||
|
||||
class DivaProfileData(BaseData):
|
||||
def create_profile(
|
||||
async def create_profile(
|
||||
self, version: int, aime_id: int, player_name: str
|
||||
) -> Optional[int]:
|
||||
"""
|
||||
@@ -82,7 +82,7 @@ class DivaProfileData(BaseData):
|
||||
|
||||
conflict = sql.on_duplicate_key_update(player_name=sql.inserted.player_name)
|
||||
|
||||
result = self.execute(conflict)
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"{__name__} Failed to insert diva profile! aime id: {aime_id} username: {player_name}"
|
||||
@@ -90,21 +90,21 @@ class DivaProfileData(BaseData):
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def update_profile(self, aime_id: int, **profile_args) -> None:
|
||||
async def update_profile(self, aime_id: int, **profile_args) -> None:
|
||||
"""
|
||||
Given an aime_id update the profile corresponding to the arguments
|
||||
which are the diva_profile Columns
|
||||
"""
|
||||
sql = profile.update(profile.c.user == aime_id).values(**profile_args)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(
|
||||
f"update_profile: failed to update profile! profile: {aime_id}"
|
||||
)
|
||||
return None
|
||||
|
||||
def get_profile(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
async def get_profile(self, aime_id: int, version: int) -> Optional[List[Dict]]:
|
||||
"""
|
||||
Given a game version and either a profile or aime id, return the profile
|
||||
"""
|
||||
@@ -112,7 +112,7 @@ class DivaProfileData(BaseData):
|
||||
and_(profile.c.version == version, profile.c.user == aime_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user