From a2f71dc553fad8472a306f7492bbacb7444dbb72 Mon Sep 17 00:00:00 2001 From: Dniel97 Date: Wed, 26 Mar 2025 15:22:55 +0100 Subject: [PATCH] ongeki: bright MEMORY Act.3 support added --- changelog.md | 4 ++++ docs/game_specific_info.md | 5 ++++- example_config/cardmaker.yaml | 6 +++--- example_config/ongeki.yaml | 22 ++++++++++++++++------ readme.md | 1 + titles/ongeki/bright.py | 2 +- titles/ongeki/brightmemoryact3.py | 24 ++++++++++++++++++++++++ titles/ongeki/const.py | 18 ++++++++++-------- titles/ongeki/index.py | 26 +++++++++++++++----------- titles/ongeki/read.py | 3 ++- titles/ongeki/schema/item.py | 14 +++++++++++--- 11 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 titles/ongeki/brightmemoryact3.py diff --git a/changelog.md b/changelog.md index a1e3f85..4620084 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,10 @@ # Changelog Documenting updates to ARTEMiS, to be updated every time the master branch is pushed to. +## 20250327 ++ O.N.G.E.K.I. bright MEMORY Act.3 support added ++ CardMaker support updated + ## 20240811 ### System + Change backend from Twisted to Starlette diff --git a/docs/game_specific_info.md b/docs/game_specific_info.md index 16c15e7..7337191 100644 --- a/docs/game_specific_info.md +++ b/docs/game_specific_info.md @@ -463,7 +463,10 @@ After that, on next login the present should be received (or whenever it suppose * FESTiVAL: Yes (added in A031) * FESTiVAL PLUS: Yes (added in A035) * BUDDiES: Yes (added in A039) -* O.N.G.E.K.I. bright MEMORY: Yes + * BUDDiES PLUS: Yes (added in A047) +* O.N.G.E.K.I.: + * bright MEMORY: Yes + * bright MEMORY Act.3 (added in A046) ### Importer diff --git a/example_config/cardmaker.yaml b/example_config/cardmaker.yaml index fb17756..b88f75d 100644 --- a/example_config/cardmaker.yaml +++ b/example_config/cardmaker.yaml @@ -8,6 +8,6 @@ version: chuni: 2.00.00 maimai: 1.20.00 1: - ongeki: 1.35.03 - chuni: 2.10.00 - maimai: 1.30.00 \ No newline at end of file + ongeki: 1.45.01 + chuni: 2.25.00 + maimai: 1.45.00 diff --git a/example_config/ongeki.yaml b/example_config/ongeki.yaml index 9af5efe..9ed04a6 100644 --- a/example_config/ongeki.yaml +++ b/example_config/ongeki.yaml @@ -7,12 +7,12 @@ gachas: enabled_gachas: - 1011 - 1012 - - 1043 - - 1067 - - 1068 - - 1069 - - 1070 - - 1071 + # - 1043 + # - 1067 + # - 1068 + # - 1069 + # - 1070 + # - 1071 - 1072 - 1073 - 1074 @@ -30,12 +30,22 @@ gachas: - 1156 - 1163 - 1164 + # 5th anniversary gacha + - 1165 + # 2024 gacha + - 1166 + # 6th anniversary gacha + - 1167 + # 2025 gacha + - 1168 version: 6: card_maker: 1.30.01 7: card_maker: 1.35.03 + 8: + card_maker: 1.45.01 crypto: encrypted_only: False \ No newline at end of file diff --git a/readme.md b/readme.md index e44c137..57f81a4 100644 --- a/readme.md +++ b/readme.md @@ -60,6 +60,7 @@ Games listed below have been tested and confirmed working. Only game versions ol + R.E.D. PLUS + bright + bright MEMORY + + bright MEMORY Act.3 + POKKÉN TOURNAMENT + Final Online diff --git a/titles/ongeki/bright.py b/titles/ongeki/bright.py index 5c95af3..c8979cb 100644 --- a/titles/ongeki/bright.py +++ b/titles/ongeki/bright.py @@ -196,7 +196,7 @@ class OngekiBright(OngekiBase): # make sure to only show gachas for the current version # so only up to bright, 1140 is the first bright memory gacha - if self.version == OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY: + if self.version >= OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY: game_gacha_list.append(tmp) elif ( self.version == OngekiConstants.VER_ONGEKI_BRIGHT diff --git a/titles/ongeki/brightmemoryact3.py b/titles/ongeki/brightmemoryact3.py new file mode 100644 index 0000000..4c0cf16 --- /dev/null +++ b/titles/ongeki/brightmemoryact3.py @@ -0,0 +1,24 @@ +from typing import Dict + +from core.config import CoreConfig +from titles.ongeki.brightmemory import OngekiBrightMemory +from titles.ongeki.const import OngekiConstants +from titles.ongeki.config import OngekiConfig + + +class OngekiBrightMemoryAct3(OngekiBrightMemory): + def __init__(self, core_cfg: CoreConfig, game_cfg: OngekiConfig) -> None: + super().__init__(core_cfg, game_cfg) + self.version = OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY_ACT3 + + 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" + ret["gameSetting"]["onlineDataVersion"] = "1.45.00" + ret["gameSetting"]["maxCountCharacter"] = 50 + ret["gameSetting"]["maxCountCard"] = 300 + ret["gameSetting"]["maxCountItem"] = 300 + ret["gameSetting"]["maxCountMusic"] = 50 + ret["gameSetting"]["maxCountMusicItem"] = 300 + ret["gameSetting"]["maxCountRivalMusic"] = 300 + return ret diff --git a/titles/ongeki/const.py b/titles/ongeki/const.py index a7658f7..71ea7f2 100644 --- a/titles/ongeki/const.py +++ b/titles/ongeki/const.py @@ -15,6 +15,7 @@ class OngekiConstants: VER_ONGEKI_RED_PLUS = 5 VER_ONGEKI_BRIGHT = 6 VER_ONGEKI_BRIGHT_MEMORY = 7 + VER_ONGEKI_BRIGHT_MEMORY_ACT3 = 8 EVT_TYPES: Enum = Enum( "EVT_TYPES", @@ -94,14 +95,15 @@ class OngekiConstants: Lunatic = 10 VERSION_NAMES = ( - "ONGEKI", - "ONGEKI +", - "ONGEKI SUMMER", - "ONGEKI SUMMER +", - "ONGEKI R.E.D.", - "ONGEKI R.E.D. +", - "ONGEKI bright", - "ONGEKI bright MEMORY", + "O.N.G.E.K.I.", + "O.N.G.E.K.I. PLUS", + "O.N.G.E.K.I. SUMMER", + "O.N.G.E.K.I. SUMMER PLUS", + "O.N.G.E.K.I. R.E.D.", + "O.N.G.E.K.I. R.E.D. PLUS", + "O.N.G.E.K.I. bright", + "O.N.G.E.K.I. bright MEMORY", + "O.N.G.E.K.I. bright MEMORY Act.3", ) @classmethod diff --git a/titles/ongeki/index.py b/titles/ongeki/index.py index 3bd0e15..3960cfa 100644 --- a/titles/ongeki/index.py +++ b/titles/ongeki/index.py @@ -29,6 +29,7 @@ from .red import OngekiRed from .redplus import OngekiRedPlus from .bright import OngekiBright from .brightmemory import OngekiBrightMemory +from .brightmemoryact3 import OngekiBrightMemoryAct3 class OngekiServlet(BaseServlet): @@ -50,6 +51,7 @@ class OngekiServlet(BaseServlet): OngekiRedPlus(core_cfg, self.game_cfg), OngekiBright(core_cfg, self.game_cfg), OngekiBrightMemory(core_cfg, self.game_cfg), + OngekiBrightMemoryAct3(core_cfg, self.game_cfg), ] self.logger = logging.getLogger("ongeki") @@ -150,26 +152,28 @@ class OngekiServlet(BaseServlet): return Response(zlib.compress(b'{"returnCode": 1}')) req_raw = await request.body() - encrtped = False + encrypted = False internal_ver = 0 client_ip = Utils.get_ip_addr(request) if version < 105: # 1.0 internal_ver = OngekiConstants.VER_ONGEKI - elif version >= 105 and version < 110: # Plus + elif version >= 105 and version < 110: # PLUS internal_ver = OngekiConstants.VER_ONGEKI_PLUS - elif version >= 110 and version < 115: # Summer + elif version >= 110 and version < 115: # SUMMER internal_ver = OngekiConstants.VER_ONGEKI_SUMMER - elif version >= 115 and version < 120: # Summer Plus + elif version >= 115 and version < 120: # SUMMER PLUS internal_ver = OngekiConstants.VER_ONGEKI_SUMMER_PLUS - elif version >= 120 and version < 125: # Red + elif version >= 120 and version < 125: # R.E.D. internal_ver = OngekiConstants.VER_ONGEKI_RED - elif version >= 125 and version < 130: # Red Plus + elif version >= 125 and version < 130: # R.E.D. PLUS internal_ver = OngekiConstants.VER_ONGEKI_RED_PLUS - elif version >= 130 and version < 135: # Bright + elif version >= 130 and version < 135: # bright internal_ver = OngekiConstants.VER_ONGEKI_BRIGHT - elif version >= 135 and version < 145: # Bright Memory + elif version >= 135 and version < 145: # bright MEMORY internal_ver = OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY + elif version >= 145: # bright MEMORY Act 3 + internal_ver = OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY_ACT3 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 @@ -204,10 +208,10 @@ class OngekiServlet(BaseServlet): ) return Response(zlib.compress(b'{"stat": "0"}')) - encrtped = True + encrypted = True if ( - not encrtped + not encrypted and self.game_cfg.crypto.encrypted_only and version >= 120 ): @@ -258,7 +262,7 @@ class OngekiServlet(BaseServlet): resp_raw = json.dumps(resp, ensure_ascii=False).encode("utf-8") zipped = zlib.compress(resp_raw) - if not encrtped or version < 120: + if not encrypted or version < 120: if version < 105: return Response(resp_raw) return Response(zipped) diff --git a/titles/ongeki/read.py b/titles/ongeki/read.py index 18f1e8a..dff5cf8 100644 --- a/titles/ongeki/read.py +++ b/titles/ongeki/read.py @@ -37,7 +37,8 @@ class OngekiReader(BaseReader): "1025": OngekiConstants.VER_ONGEKI_RED_PLUS, "1030": OngekiConstants.VER_ONGEKI_BRIGHT, "1035": OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY, - "1040": OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY + "1040": OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY, + "1045": OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY_ACT3, } node = troot.find("VersionID").find("id") diff --git a/titles/ongeki/schema/item.py b/titles/ongeki/schema/item.py index 274e16d..6145116 100644 --- a/titles/ongeki/schema/item.py +++ b/titles/ongeki/schema/item.py @@ -578,7 +578,11 @@ class OngekiItemData(BaseData): return result.lastrowid async def get_mission_points(self, version: int, aime_id: int) -> Optional[List[Dict]]: - sql = select(mission_point).where(and_(mission_point.c.user == aime_id, mission_point.c.version == version)) + sql = select(mission_point).where(and_( + mission_point.c.user == aime_id, + mission_point.c.version <= version) + ).order_by(mission_point.c.version.desc()) + result = await self.execute(sql) if result is None: @@ -702,7 +706,11 @@ class OngekiItemData(BaseData): return result.lastrowid async def get_tech_event(self, version: int, aime_id: int) -> Optional[List[Dict]]: - sql = select(tech_event).where(and_(tech_event.c.user == aime_id, tech_event.c.version == version)) + sql = select(tech_event).where(and_( + tech_event.c.user == aime_id, + tech_event.c.version <= version) + ).order_by(tech_event.c.version.desc()) + result = await self.execute(sql) if result is None: @@ -794,7 +802,7 @@ class OngekiItemData(BaseData): async def get_ranking_event_ranks(self, version: int, aime_id: int) -> Optional[List[Dict]]: # Calculates player rank on GameRequest from server, and sends it back, official spec would rank players in maintenance period, on TODO list - sql = select(event_point.c.id, event_point.c.user, event_point.c.eventId, event_point.c.type, func.row_number().over(partition_by=event_point.c.eventId, order_by=event_point.c.point.desc()).label('rank'), event_point.c.date, event_point.c.point).where(event_point.c.version == version) + sql = select(event_point.c.id, event_point.c.user, event_point.c.eventId, event_point.c.type, func.row_number().over(partition_by=event_point.c.eventId, order_by=event_point.c.point.desc()).label('rank'), event_point.c.date, event_point.c.point).where(event_point.c.version <= version).order_by(event_point.c.version.desc()) result = await self.execute(sql) if result is None: self.logger.error(f"failed to rank aime_id: {aime_id} ranking event positions")