diff --git a/core/data/schema/versions/SDBT_4_rollback.sql b/core/data/schema/versions/SDBT_4_rollback.sql new file mode 100644 index 0000000..90a0e4f --- /dev/null +++ b/core/data/schema/versions/SDBT_4_rollback.sql @@ -0,0 +1,12 @@ +SET FOREIGN_KEY_CHECKS = 0; + +ALTER TABLE chuni_score_playlog + CHANGE COLUMN isClear isClear TINYINT(1) NULL DEFAULT NULL; + +ALTER TABLE aime.chuni_score_best + CHANGE COLUMN isSuccess isSuccess TINYINT(1) NULL DEFAULT NULL ; + +ALTER TABLE chuni_score_playlog + DROP COLUMN ticketId; + +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/core/data/schema/versions/SDBT_5_upgrade.sql b/core/data/schema/versions/SDBT_5_upgrade.sql new file mode 100644 index 0000000..ab362bb --- /dev/null +++ b/core/data/schema/versions/SDBT_5_upgrade.sql @@ -0,0 +1,12 @@ +SET FOREIGN_KEY_CHECKS = 0; + +ALTER TABLE chuni_score_playlog + CHANGE COLUMN isClear isClear TINYINT(6) NULL DEFAULT NULL; + +ALTER TABLE aime.chuni_score_best + CHANGE COLUMN isSuccess isSuccess INT(11) NULL DEFAULT NULL ; + +ALTER TABLE chuni_score_playlog + ADD COLUMN ticketId INT(11) NULL AFTER machineType; + +SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/docs/game_specific_info.md b/docs/game_specific_info.md index 8d1aa1d..5810ff8 100644 --- a/docs/game_specific_info.md +++ b/docs/game_specific_info.md @@ -54,6 +54,7 @@ Games listed below have been tested and confirmed working. | 11 | CHUNITHM NEW!! | | 12 | CHUNITHM NEW PLUS!! | | 13 | CHUNITHM SUN | +| 14 | CHUNITHM SUN PLUS | ### Importer @@ -74,7 +75,6 @@ Config file is located in `config/chuni.yaml`. |------------------|----------------------------------------------------------------------------------------------------------------| | `news_msg` | If this is set, the news at the top of the main screen will be displayed (up to Chunithm Paradise Lost) | | `name` | If this is set, all players that are not on a team will use this one by default. | -| `rank_scale` | Scales the in-game ranking based on the number of teams within the database | | `use_login_bonus`| This is used to enable the login bonuses | | `crypto` | This option is used to enable the TLS Encryption | @@ -132,12 +132,6 @@ INSERT INTO aime.chuni_profile_team (teamName) VALUES (); ``` Team names can be regular ASCII, and they will be displayed ingame. -On smaller installations, you may also wish to enable scaled team rankings. By default, Chunithm determines team ranking within the first 100 teams. This can be configured in the YAML: -```yaml -team: - rank_scale: True # Scales the in-game ranking based on the number of teams within the database, rather than the default scale of ~100 that the game normally uses. -``` - ### Favorite songs You can set the songs that will be in a user's Favorite Songs category using the following SQL entries: ```sql diff --git a/example_config/chuni.yaml b/example_config/chuni.yaml index 578bcb3..72a1d98 100644 --- a/example_config/chuni.yaml +++ b/example_config/chuni.yaml @@ -19,6 +19,9 @@ version: 13: rom: 2.10.00 data: 2.10.00 + 14: + rom: 2.15.00 + data: 2.15.00 crypto: encrypted_only: False \ No newline at end of file diff --git a/readme.md b/readme.md index c527090..cbd89c9 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,7 @@ A network service emulator for games running SEGA'S ALL.NET service, and similar Games listed below have been tested and confirmed working. Only game versions older then the version currently active in arcades, or games versions that have not recieved a major update in over one year, are supported. + CHUNITHM - + All versions up to SUN + + All versions up to SUN PLUS + crossbeats REV. + All versions + omnimix diff --git a/titles/chuni/__init__.py b/titles/chuni/__init__.py index 0c3cc79..dc0e2f4 100644 --- a/titles/chuni/__init__.py +++ b/titles/chuni/__init__.py @@ -6,5 +6,5 @@ from titles.chuni.read import ChuniReader index = ChuniServlet database = ChuniData reader = ChuniReader -game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW] -current_schema_version = 4 +game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW, ChuniConstants.GAME_CODE_INT] +current_schema_version = 5 \ No newline at end of file diff --git a/titles/chuni/base.py b/titles/chuni/base.py index 7272e54..674fb9c 100644 --- a/titles/chuni/base.py +++ b/titles/chuni/base.py @@ -240,7 +240,6 @@ 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( data["userId"], data["kind"] @@ -420,13 +419,13 @@ class ChuniBase: all_entries = self.data.score.get_rival_music(rival_id) # Process the entries based on max_count and nextIndex - for music in all_entries[next_index:]: + for music in all_entries: music_id = music["musicId"] level = music["level"] score = music["scoreMax"] rank = music["scoreRank"] - # Create a music entry for the current music_id + # Create a music entry for the current music_id if it's unique music_entry = next((entry for entry in user_rival_music_list if entry["musicId"] == music_id), None) if music_entry is None: music_entry = { @@ -436,15 +435,20 @@ class ChuniBase: } user_rival_music_list.append(music_entry) - # Create a level entry for the current level - level_entry = { - "level": level, - "scoreMax": score, - "scoreRank": rank - } - music_entry["userRivalMusicDetailList"].append(level_entry) + # Create a level entry for the current level if it's unique or has a higher score + level_entry = next((entry for entry in music_entry["userRivalMusicDetailList"] if entry["level"] == level), None) + if level_entry is None: + level_entry = { + "level": level, + "scoreMax": score, + "scoreRank": rank + } + music_entry["userRivalMusicDetailList"].append(level_entry) + elif score > level_entry["scoreMax"]: + level_entry["scoreMax"] = score + level_entry["scoreRank"] = rank - # Calculate the length for each "musicId" by counting the levels + # Calculate the length for each "musicId" by counting the unique levels for music_entry in user_rival_music_list: music_entry["length"] = len(music_entry["userRivalMusicDetailList"]) @@ -452,11 +456,11 @@ class ChuniBase: result = { "userId": data["userId"], "rivalId": data["rivalId"], - "nextIndex": str(next_index + len(all_entries) if len(all_entries) <= len(user_rival_music_list) else -1), - "userRivalMusicList": user_rival_music_list[:max_count] + "nextIndex": str(next_index + len(user_rival_music_list[next_index: next_index + max_count]) if max_count <= len(user_rival_music_list[next_index: next_index + max_count]) else -1), + "userRivalMusicList": user_rival_music_list[next_index: next_index + max_count] } - return result + def handle_get_user_favorite_item_api_request(self, data: Dict) -> Dict: user_fav_item_list = [] @@ -873,9 +877,12 @@ class ChuniBase: if "userPlaylogList" in upsert: for playlog in upsert["userPlaylogList"]: # convert the player names to utf-8 - playlog["playedUserName1"] = self.read_wtf8(playlog["playedUserName1"]) - playlog["playedUserName2"] = self.read_wtf8(playlog["playedUserName2"]) - playlog["playedUserName3"] = self.read_wtf8(playlog["playedUserName3"]) + if playlog["playedUserName1"] is not None: + playlog["playedUserName1"] = self.read_wtf8(playlog["playedUserName1"]) + if playlog["playedUserName2"] is not None: + 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) if "userTeamPoint" in upsert: @@ -947,4 +954,4 @@ class ChuniBase: return { "userId": data["userId"], "userNetBattleData": {"recentNBSelectMusicList": []}, - } + } \ No newline at end of file diff --git a/titles/chuni/const.py b/titles/chuni/const.py index b3a4cb5..3e83378 100644 --- a/titles/chuni/const.py +++ b/titles/chuni/const.py @@ -1,6 +1,7 @@ class ChuniConstants: GAME_CODE = "SDBT" GAME_CODE_NEW = "SDHD" + GAME_CODE_INT = "SDGS" CONFIG_NAME = "chuni.yaml" @@ -18,7 +19,7 @@ class ChuniConstants: VER_CHUNITHM_NEW = 11 VER_CHUNITHM_NEW_PLUS = 12 VER_CHUNITHM_SUN = 13 - + VER_CHUNITHM_SUN_PLUS = 14 VERSION_NAMES = [ "CHUNITHM", "CHUNITHM PLUS", @@ -33,9 +34,10 @@ class ChuniConstants: "CHUNITHM PARADISE", "CHUNITHM NEW!!", "CHUNITHM NEW PLUS!!", - "CHUNITHM SUN" + "CHUNITHM SUN", + "CHUNITHM SUN PLUS" ] @classmethod def game_ver_to_string(cls, ver: int): - return cls.VERSION_NAMES[ver] + return cls.VERSION_NAMES[ver] \ No newline at end of file diff --git a/titles/chuni/index.py b/titles/chuni/index.py index 670dbe8..434d22f 100644 --- a/titles/chuni/index.py +++ b/titles/chuni/index.py @@ -31,6 +31,7 @@ from .paradise import ChuniParadise from .new import ChuniNew from .newplus import ChuniNewPlus from .sun import ChuniSun +from .sunplus import ChuniSunPlus class ChuniServlet(BaseServlet): @@ -58,6 +59,7 @@ class ChuniServlet(BaseServlet): ChuniNew, ChuniNewPlus, ChuniSun, + ChuniSunPlus, ] self.logger = logging.getLogger("chuni") @@ -120,8 +122,8 @@ class ChuniServlet(BaseServlet): return ( [], [ - ("render_POST", "/{version}/ChuniServlet/{endpoint}", {}), - ("render_POST", "/{version}/ChuniServlet/MatchingServer/{endpoint}", {}) + ("render_POST", "/{game}/{version}/ChuniServlet/{endpoint}", {}), + ("render_POST", "/{game}/{version}/ChuniServlet/MatchingServer/{endpoint}", {}) ] ) @@ -139,53 +141,69 @@ class ChuniServlet(BaseServlet): return False return True - + def get_allnet_info(self, game_code: str, game_ver: int, keychip: str) -> Tuple[str, str]: if not self.core_cfg.server.is_using_proxy and Utils.get_title_port(self.core_cfg) != 80: - return (f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_ver}/", self.core_cfg.title.hostname) + return (f"http://{self.core_cfg.title.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_code}/{game_ver}/", self.core_cfg.title.hostname) - return (f"http://{self.core_cfg.title.hostname}/{game_ver}/", self.core_cfg.title.hostname) + return (f"http://{self.core_cfg.title.hostname}/{game_code}/{game_ver}/", self.core_cfg.title.hostname) def render_POST(self, request: Request, game_code: str, matchers: Dict) -> bytes: endpoint = matchers['endpoint'] version = int(matchers['version']) - + game_code = matchers['game'] + if endpoint.lower() == "ping": return zlib.compress(b'{"returnCode": "1"}') req_raw = request.content.getvalue() + encrtped = False internal_ver = 0 client_ip = Utils.get_ip_addr(request) - if version < 105: # 1.0 - internal_ver = ChuniConstants.VER_CHUNITHM - elif version >= 105 and version < 110: # PLUS - internal_ver = ChuniConstants.VER_CHUNITHM_PLUS - elif version >= 110 and version < 115: # AIR - internal_ver = ChuniConstants.VER_CHUNITHM_AIR - elif version >= 115 and version < 120: # AIR PLUS - internal_ver = ChuniConstants.VER_CHUNITHM_AIR_PLUS - elif version >= 120 and version < 125: # STAR - internal_ver = ChuniConstants.VER_CHUNITHM_STAR - elif version >= 125 and version < 130: # STAR PLUS - internal_ver = ChuniConstants.VER_CHUNITHM_STAR_PLUS - elif version >= 130 and version < 135: # AMAZON - internal_ver = ChuniConstants.VER_CHUNITHM_AMAZON - elif version >= 135 and version < 140: # AMAZON PLUS - internal_ver = ChuniConstants.VER_CHUNITHM_AMAZON_PLUS - elif version >= 140 and version < 145: # CRYSTAL - internal_ver = ChuniConstants.VER_CHUNITHM_CRYSTAL - elif version >= 145 and version < 150: # CRYSTAL PLUS - internal_ver = ChuniConstants.VER_CHUNITHM_CRYSTAL_PLUS - elif version >= 150 and version < 200: # PARADISE - internal_ver = ChuniConstants.VER_CHUNITHM_PARADISE - elif version >= 200 and version < 205: # NEW!! - internal_ver = ChuniConstants.VER_CHUNITHM_NEW - elif version >= 205 and version < 210: # NEW PLUS!! - internal_ver = ChuniConstants.VER_CHUNITHM_NEW_PLUS - elif version >= 210: # SUN - internal_ver = ChuniConstants.VER_CHUNITHM_SUN + if game_code == "SDHD" or game_code == "SDBT": # JP + if version < 105: # 1.0 + internal_ver = ChuniConstants.VER_CHUNITHM + elif version >= 105 and version < 110: # PLUS + internal_ver = ChuniConstants.VER_CHUNITHM_PLUS + elif version >= 110 and version < 115: # AIR + internal_ver = ChuniConstants.VER_CHUNITHM_AIR + elif version >= 115 and version < 120: # AIR PLUS + internal_ver = ChuniConstants.VER_CHUNITHM_AIR_PLUS + elif version >= 120 and version < 125: # STAR + internal_ver = ChuniConstants.VER_CHUNITHM_STAR + elif version >= 125 and version < 130: # STAR PLUS + internal_ver = ChuniConstants.VER_CHUNITHM_STAR_PLUS + elif version >= 130 and version < 135: # AMAZON + internal_ver = ChuniConstants.VER_CHUNITHM_AMAZON + elif version >= 135 and version < 140: # AMAZON PLUS + internal_ver = ChuniConstants.VER_CHUNITHM_AMAZON_PLUS + elif version >= 140 and version < 145: # CRYSTAL + internal_ver = ChuniConstants.VER_CHUNITHM_CRYSTAL + elif version >= 145 and version < 150: # CRYSTAL PLUS + internal_ver = ChuniConstants.VER_CHUNITHM_CRYSTAL_PLUS + elif version >= 150 and version < 200: # PARADISE + internal_ver = ChuniConstants.VER_CHUNITHM_PARADISE + elif version >= 200 and version < 205: # NEW!! + internal_ver = ChuniConstants.VER_CHUNITHM_NEW + elif version >= 205 and version < 210: # NEW PLUS!! + internal_ver = ChuniConstants.VER_CHUNITHM_NEW_PLUS + elif version >= 210 and version < 215: # SUN + internal_ver = ChuniConstants.VER_CHUNITHM_SUN + elif version >= 215: # SUN + internal_ver = ChuniConstants.VER_CHUNITHM_SUN_PLUS + elif game_code == "SDGS": # Int + if version < 110: # SUPERSTAR + internal_ver = ChuniConstants.PARADISE + elif version >= 110 and version < 115: # NEW + internal_ver = ChuniConstants.VER_CHUNITHM_NEW + elif version >= 115 and version < 120: # NEW PLUS!! + internal_ver = ChuniConstants.VER_CHUNITHM_NEW_PLUS + elif version >= 120 and version < 125: # SUN + internal_ver = ChuniConstants.VER_CHUNITHM_SUN + elif version >= 125: # SUN PLUS + internal_ver = ChuniConstants.VER_CHUNITHM_SUN_PLUS if all(c in string.hexdigits for c in endpoint) and len(endpoint) == 32: # If we get a 32 character long hex string, it's a hash and we're @@ -250,6 +268,7 @@ class ChuniServlet(BaseServlet): self.logger.info(f"v{version} {endpoint} request from {client_ip}") self.logger.debug(req_data) + endpoint = endpoint.replace("C3Exp", "") if game_code == "SDGS" else endpoint func_to_find = "handle_" + inflection.underscore(endpoint) + "_request" handler_cls = self.versions[internal_ver](self.core_cfg, self.game_cfg) @@ -284,4 +303,4 @@ class ChuniServlet(BaseServlet): bytes.fromhex(self.game_cfg.crypto.keys[internal_ver][1]), ) - return crypt.encrypt(padded) + return crypt.encrypt(padded) \ No newline at end of file diff --git a/titles/chuni/new.py b/titles/chuni/new.py index fd495f1..8a658bf 100644 --- a/titles/chuni/new.py +++ b/titles/chuni/new.py @@ -71,11 +71,11 @@ class ChuniNew(ChuniBase): "matchErrorLimit": 9999, "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}/200/ChuniServlet/", - "matchingUriX": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/200/ChuniServlet/", + "matchingUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/", + "matchingUriX": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/", # 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}/200/ChuniServlet/", - "reflectorUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/200/ChuniServlet/", + "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/", }, "isDumpUpload": False, "isAou": False, diff --git a/titles/chuni/newplus.py b/titles/chuni/newplus.py index 1a6876c..749173c 100644 --- a/titles/chuni/newplus.py +++ b/titles/chuni/newplus.py @@ -21,16 +21,16 @@ class ChuniNewPlus(ChuniNew): ] ret["gameSetting"][ "matchingUri" - ] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/205/ChuniServlet/" + ] = 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}/205/ChuniServlet/" + ] = 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}/205/ChuniServlet/" + ] = 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}/205/ChuniServlet/" + ] = 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: @@ -38,4 +38,4 @@ class ChuniNewPlus(ChuniNew): # hardcode lastDataVersion for CardMaker 1.35 A028 user_data["lastDataVersion"] = "2.05.00" - return user_data + return user_data \ No newline at end of file diff --git a/titles/chuni/schema/score.py b/titles/chuni/schema/score.py index 7712e3f..7e41b8f 100644 --- a/titles/chuni/schema/score.py +++ b/titles/chuni/schema/score.py @@ -24,7 +24,7 @@ course = Table( Column("scoreMax", Integer), Column("isFullCombo", Boolean), Column("isAllJustice", Boolean), - Column("isSuccess", Boolean), + Column("isSuccess", Integer), Column("scoreRank", Integer), Column("eventId", Integer), Column("lastPlayDate", String(25)), @@ -32,7 +32,7 @@ course = Table( Column("param2", Integer), Column("param3", Integer), Column("param4", Integer), - Column("isClear", Boolean), + Column("isClear", Integer), Column("theoryCount", Integer), Column("orderId", Integer), Column("playerRating", Integer), @@ -60,7 +60,7 @@ best_score = Table( Column("maxComboCount", Integer), Column("isFullCombo", Boolean), Column("isAllJustice", Boolean), - Column("isSuccess", Boolean), + Column("isSuccess", Integer), Column("fullChain", Integer), Column("maxChain", Integer), Column("scoreRank", Integer), @@ -125,7 +125,7 @@ playlog = Table( Column("characterId", Integer), Column("skillId", Integer), Column("playKind", Integer), - Column("isClear", Boolean), + Column("isClear", Integer), Column("skillLevel", Integer), Column("skillEffect", Integer), Column("placeName", String(255)), @@ -136,6 +136,7 @@ playlog = Table( Column("judgeHeaven", Integer), Column("regionId", Integer), Column("machineType", Integer), + Column("ticketId", Integer), mysql_charset="utf8mb4" ) @@ -255,4 +256,3 @@ class ChuniScoreData(BaseData): if result is None: return None return result.fetchall() - diff --git a/titles/chuni/sun.py b/titles/chuni/sun.py index 86784b5..9a82a65 100644 --- a/titles/chuni/sun.py +++ b/titles/chuni/sun.py @@ -17,16 +17,16 @@ class ChuniSun(ChuniNewPlus): 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}/210/ChuniServlet/" + ] = 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}/210/ChuniServlet/" + ] = 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}/210/ChuniServlet/" + ] = 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}/210/ChuniServlet/" + ] = 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: @@ -34,4 +34,4 @@ class ChuniSun(ChuniNewPlus): # hardcode lastDataVersion for CardMaker 1.35 A032 user_data["lastDataVersion"] = "2.10.00" - return user_data + return user_data \ No newline at end of file diff --git a/titles/chuni/sunplus.py b/titles/chuni/sunplus.py new file mode 100644 index 0000000..66a7f3b --- /dev/null +++ b/titles/chuni/sunplus.py @@ -0,0 +1,37 @@ +from typing import Dict, Any + +from core.config import CoreConfig +from titles.chuni.sun import ChuniSun +from titles.chuni.const import ChuniConstants +from titles.chuni.config import ChuniConfig + + +class ChuniSunPlus(ChuniSun): + def __init__(self, core_cfg: CoreConfig, game_cfg: ChuniConfig) -> None: + 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) + + # 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" + return user_data diff --git a/titles/cm/base.py b/titles/cm/base.py index c95beb5..b911983 100644 --- a/titles/cm/base.py +++ b/titles/cm/base.py @@ -45,7 +45,7 @@ class CardMakerBase: { "modelKind": 0, "type": 1, - "titleUri": f"{uri}/{self._parse_int_ver(games_ver['chuni'])}/ChuniServlet/", + "titleUri": f"{uri}/SDHD/{self._parse_int_ver(games_ver['chuni'])}/ChuniServlet/", }, # maimai DX {