Add maimai DX BUDDIES support ,Int version work #116
8
core/data/schema/versions/SDEZ_8_rollback.sql
Normal file
8
core/data/schema/versions/SDEZ_8_rollback.sql
Normal file
@ -0,0 +1,8 @@
|
||||
ALTER TABLE mai2_profile_detail
|
||||
DROP COLUMN currentPlayCount,
|
||||
DROP COLUMN renameCredit;
|
||||
|
||||
ALTER TABLE mai2_playlog
|
||||
DROP COLUMN extBool1;
|
||||
|
||||
DROP TABLE IF EXISTS `mai2_playlog_2p`;
|
20
core/data/schema/versions/SDEZ_9_upgrade.sql
Normal file
20
core/data/schema/versions/SDEZ_9_upgrade.sql
Normal file
@ -0,0 +1,20 @@
|
||||
ALTER TABLE mai2_profile_detail
|
||||
ADD currentPlayCount INT NULL AFTER playCount,
|
||||
ADD renameCredit INT NULL AFTER banState;
|
||||
|
||||
ALTER TABLE mai2_playlog
|
||||
ADD extBool1 BOOLEAN NULL AFTER extNum4;
|
||||
|
||||
CREATE TABLE `mai2_playlog_2p` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`user` INT NOT NULL,
|
||||
`userId1` BIGINT,
|
||||
`userId2` BIGINT,
|
||||
`userName1` VARCHAR(255),
|
||||
`userName2` VARCHAR(255),
|
||||
`regionId` INT,
|
||||
`placeId` INT,
|
||||
`user2pPlaylogDetailList` JSON,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY (`user`) REFERENCES `aime_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
@ -192,6 +192,7 @@ Config file is located in `config/cxb.yaml`.
|
||||
| SDEZ | 18 | maimai DX UNiVERSE PLUS |
|
||||
| SDEZ | 19 | maimai DX FESTiVAL |
|
||||
| SDEZ | 20 | maimai DX FESTiVAL PLUS |
|
||||
| SDEZ | 21 | maimai DX BUDDiES |
|
||||
|
||||
### Importer
|
||||
|
||||
@ -406,6 +407,7 @@ After that, on next login the present should be received (or whenever it suppose
|
||||
* UNiVERSE PLUS: Yes
|
||||
* 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
|
||||
|
||||
|
||||
|
@ -47,6 +47,7 @@ Games listed below have been tested and confirmed working. Only game versions ol
|
||||
+ UNiVERSE PLUS
|
||||
+ FESTiVAL
|
||||
+ FESTiVAL PLUS
|
||||
+ BUDDiES
|
||||
|
||||
+ O.N.G.E.K.I.
|
||||
+ SUMMER
|
||||
|
@ -195,7 +195,7 @@ class ChuniServlet(BaseServlet):
|
||||
internal_ver = ChuniConstants.VER_CHUNITHM_NEW_PLUS
|
||||
elif version >= 210 and version < 215: # SUN
|
||||
internal_ver = ChuniConstants.VER_CHUNITHM_SUN
|
||||
elif version >= 215: # SUN
|
||||
elif version >= 215: # SUN PLUS
|
||||
internal_ver = ChuniConstants.VER_CHUNITHM_SUN_PLUS
|
||||
elif game_code == "SDGS": # Int
|
||||
if version < 110: # SUPERSTAR
|
||||
|
@ -51,7 +51,7 @@ class CardMakerBase:
|
||||
{
|
||||
"modelKind": 1,
|
||||
"type": 1,
|
||||
"titleUri": f"{uri}/{self._parse_int_ver(games_ver['maimai'])}/Maimai2Servlet/",
|
||||
"titleUri": f"{uri}/SDEZ/{self._parse_int_ver(games_ver['maimai'])}/Maimai2Servlet/",
|
||||
},
|
||||
# ONGEKI
|
||||
{
|
||||
|
@ -206,6 +206,7 @@ class CardMakerReader(BaseReader):
|
||||
"1.25": Mai2Constants.VER_MAIMAI_DX_UNIVERSE_PLUS,
|
||||
"1.30": Mai2Constants.VER_MAIMAI_DX_FESTIVAL,
|
||||
"1.35": Mai2Constants.VER_MAIMAI_DX_FESTIVAL_PLUS,
|
||||
"1.40": Mai2Constants.VER_MAIMAI_DX_BUDDIES,
|
||||
}
|
||||
|
||||
for root, dirs, files in os.walk(base_dir):
|
||||
|
@ -7,6 +7,7 @@ index = Mai2Servlet
|
||||
database = Mai2Data
|
||||
reader = Mai2Reader
|
||||
game_codes = [
|
||||
Mai2Constants.GAME_CODE_INT,
|
||||
Mai2Constants.GAME_CODE_DX,
|
||||
Mai2Constants.GAME_CODE_FINALE,
|
||||
Mai2Constants.GAME_CODE_MILK,
|
||||
|
19
titles/mai2/buddies.py
Normal file
19
titles/mai2/buddies.py
Normal file
@ -0,0 +1,19 @@
|
||||
from typing import Dict
|
||||
|
||||
from core.config import CoreConfig
|
||||
from titles.mai2.festivalplus import Mai2FestivalPlus
|
||||
from titles.mai2.const import Mai2Constants
|
||||
from titles.mai2.config import Mai2Config
|
||||
|
||||
|
||||
class Mai2Buddies(Mai2FestivalPlus):
|
||||
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
|
||||
super().__init__(cfg, game_cfg)
|
||||
self.version = Mai2Constants.VER_MAIMAI_DX_BUDDIES
|
||||
|
||||
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
|
||||
user_data["lastDataVersion"] = "1.40.00"
|
||||
return user_data
|
@ -28,6 +28,7 @@ class Mai2Constants:
|
||||
GAME_CODE_MILK = "SDDZ"
|
||||
GAME_CODE_FINALE = "SDEY"
|
||||
GAME_CODE_DX = "SDEZ"
|
||||
GAME_CODE_INT = "SDGA"
|
||||
|
||||
CONFIG_NAME = "mai2.yaml"
|
||||
|
||||
@ -53,6 +54,7 @@ class Mai2Constants:
|
||||
VER_MAIMAI_DX_UNIVERSE_PLUS = 18
|
||||
VER_MAIMAI_DX_FESTIVAL = 19
|
||||
VER_MAIMAI_DX_FESTIVAL_PLUS = 20
|
||||
VER_MAIMAI_DX_BUDDIES = 21
|
||||
|
||||
VERSION_STRING = (
|
||||
"maimai",
|
||||
@ -76,6 +78,7 @@ class Mai2Constants:
|
||||
"maimai DX UNiVERSE PLUS",
|
||||
"maimai DX FESTiVAL",
|
||||
"maimai DX FESTiVAL PLUS",
|
||||
"maimai DX BUDDiES",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
@ -213,6 +213,9 @@ class Mai2DX(Mai2Base):
|
||||
)
|
||||
await self.data.item.put_friend_season_ranking(user_id, fsr)
|
||||
|
||||
if "user2pPlaylog" in upsert:
|
||||
await self.data.score.put_2p_playlog(user_id, upsert["user2pPlaylog"])
|
||||
|
||||
return {"returnCode": 1, "apiName": "UpsertUserAllApi"}
|
||||
|
||||
async def handle_get_user_data_api_request(self, data: Dict) -> Dict:
|
||||
|
@ -25,6 +25,7 @@ from .universe import Mai2Universe
|
||||
from .universeplus import Mai2UniversePlus
|
||||
from .festival import Mai2Festival
|
||||
from .festivalplus import Mai2FestivalPlus
|
||||
from .buddies import Mai2Buddies
|
||||
|
||||
|
||||
class Mai2Servlet(BaseServlet):
|
||||
@ -58,6 +59,7 @@ class Mai2Servlet(BaseServlet):
|
||||
Mai2UniversePlus,
|
||||
Mai2Festival,
|
||||
Mai2FestivalPlus,
|
||||
Mai2Buddies,
|
||||
]
|
||||
|
||||
self.logger = logging.getLogger("mai2")
|
||||
@ -111,18 +113,18 @@ class Mai2Servlet(BaseServlet):
|
||||
Route("/{version:int}/MaimaiServlet/usbdl/{endpoint:str}", self.handle_usbdl),
|
||||
Route("/{version:int}/MaimaiServlet/deliver/{endpoint:str}", self.handle_deliver),
|
||||
Route("/{version:int}/MaimaiServlet/{endpoint:str}", self.handle_mai, methods=['POST']),
|
||||
Route("/{version:int}/Maimai2Servlet/{endpoint:str}", self.handle_mai2, methods=['POST']),
|
||||
Route("/{game:str}/{version:int}/Maimai2Servlet/{endpoint:str}", self.handle_mai2, 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.server.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_ver}/",
|
||||
f"http://{self.core_cfg.server.hostname}:{Utils.get_title_port(self.core_cfg)}/{game_code}/{game_ver}/",
|
||||
f"{self.core_cfg.server.hostname}",
|
||||
)
|
||||
|
||||
return (
|
||||
f"http://{self.core_cfg.server.hostname}/{game_ver}/",
|
||||
f"http://{self.core_cfg.server.hostname}/{game_code}/{game_ver}/",
|
||||
f"{self.core_cfg.server.hostname}",
|
||||
)
|
||||
|
||||
@ -237,6 +239,7 @@ class Mai2Servlet(BaseServlet):
|
||||
async def handle_mai2(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 Response(zlib.compress(b'{"returnCode": "1"}'))
|
||||
|
||||
@ -257,8 +260,10 @@ class Mai2Servlet(BaseServlet):
|
||||
internal_ver = Mai2Constants.VER_MAIMAI_DX_UNIVERSE_PLUS
|
||||
elif version >= 130 and version < 135: # FESTiVAL
|
||||
internal_ver = Mai2Constants.VER_MAIMAI_DX_FESTIVAL
|
||||
elif version >= 135: # FESTiVAL PLUS
|
||||
elif version >= 135 and version < 140: # FESTiVAL PLUS
|
||||
internal_ver = Mai2Constants.VER_MAIMAI_DX_FESTIVAL_PLUS
|
||||
elif version >= 140: # BUDDiES
|
||||
internal_ver = Mai2Constants.VER_MAIMAI_DX_BUDDIES
|
||||
|
||||
if (
|
||||
request.headers.get("Mai-Encoding") is not None
|
||||
@ -288,6 +293,7 @@ class Mai2Servlet(BaseServlet):
|
||||
self.logger.info(f"v{version} {endpoint} request from {client_ip}")
|
||||
self.logger.debug(req_data)
|
||||
|
||||
endpoint = endpoint.replace("MaimaiExp", "") if game_code == "SDGA" else endpoint
|
||||
func_to_find = "handle_" + inflection.underscore(endpoint) + "_request"
|
||||
handler_cls = self.versions[internal_ver](self.core_cfg, self.game_cfg)
|
||||
|
||||
|
@ -40,6 +40,8 @@ detail = Table(
|
||||
Column("charaLockSlot", JSON),
|
||||
Column("contentBit", BigInteger),
|
||||
Column("playCount", Integer),
|
||||
Column("currentPlayCount", Integer), # new with bud
|
||||
Column("renameCredit", Integer), # new with bud
|
||||
Column("mapStock", Integer), # new with fes+
|
||||
Column("eventWatchedDate", String(25)),
|
||||
Column("lastGameId", String(25)),
|
||||
|
@ -146,10 +146,30 @@ playlog = Table(
|
||||
Column("extNum1", Integer),
|
||||
Column("extNum2", Integer),
|
||||
Column("extNum4", Integer, server_default="0"),
|
||||
Column("extBool1", Boolean), # new with bud
|
||||
Column("trialPlayAchievement", Integer),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
playlog_2p = Table( # new with buddies, the in-game name is 2pPlaylog
|
||||
"mai2_playlog_2p",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column(
|
||||
"user",
|
||||
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
|
||||
nullable=False,
|
||||
),
|
||||
Column("userId1", BigInteger),
|
||||
Column("userId2", BigInteger),
|
||||
Column("userName1", String(255)),
|
||||
Column("userName2", String(255)),
|
||||
Column("regionId", Integer),
|
||||
Column("placeId", Integer),
|
||||
Column("user2pPlaylogDetailList", JSON),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
course = Table(
|
||||
"mai2_score_course",
|
||||
metadata,
|
||||
@ -343,6 +363,18 @@ class Mai2ScoreData(BaseData):
|
||||
self.logger.error(f"put_playlog: Failed to insert! user_id {user_id} is_dx {is_dx}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
async def put_2p_playlog(self, user_id: int, playlog_2p_data: Dict) -> Optional[int]:
|
||||
playlog_2p_data["user"] = user_id
|
||||
sql = insert(playlog_2p).values(**playlog_2p_data)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(**playlog_2p_data)
|
||||
|
||||
result = await self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.error(f"put_2p_playlog: Failed to insert! user_id {user_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
async def put_course(self, user_id: int, course_data: Dict) -> Optional[int]:
|
||||
course_data["user"] = user_id
|
||||
|
Loading…
Reference in New Issue
Block a user