AimeNet/ARTEMiS/bud.patch

261 lines
9.1 KiB
Diff

diff --git a/core/data/schema/versions/SDEZ_8_rollback.sql b/core/data/schema/versions/SDEZ_8_rollback.sql
new file mode 100644
index 0000000..cfc5d4c
--- /dev/null
+++ b/core/data/schema/versions/SDEZ_8_rollback.sql
@@ -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`;
diff --git a/core/data/schema/versions/SDEZ_9_upgrade.sql b/core/data/schema/versions/SDEZ_9_upgrade.sql
new file mode 100644
index 0000000..4481075
--- /dev/null
+++ b/core/data/schema/versions/SDEZ_9_upgrade.sql
@@ -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;
diff --git a/docs/game_specific_info.md b/docs/game_specific_info.md
index 5810ff8..0bdc572 100644
--- a/docs/game_specific_info.md
+++ b/docs/game_specific_info.md
@@ -201,6 +201,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
diff --git a/readme.md b/readme.md
index cbd89c9..8d0e04e 100644
--- a/readme.md
+++ b/readme.md
@@ -11,7 +11,7 @@ Games listed below have been tested and confirmed working. Only game versions ol
+ All versions + omnimix
+ maimai DX
- + All versions up to FESTiVAL PLUS
+ + All versions up to BUDDiES
+ Hatsune Miku: Project DIVA Arcade
+ All versions
diff --git a/titles/cm/read.py b/titles/cm/read.py
index 376789d..80684bd 100644
--- a/titles/cm/read.py
+++ b/titles/cm/read.py
@@ -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):
diff --git a/titles/mai2/__init__.py b/titles/mai2/__init__.py
index 4857644..a3c178e 100644
--- a/titles/mai2/__init__.py
+++ b/titles/mai2/__init__.py
@@ -16,4 +16,4 @@ game_codes = [
Mai2Constants.GAME_CODE_GREEN,
Mai2Constants.GAME_CODE,
]
-current_schema_version = 8
+current_schema_version = 9
diff --git a/titles/mai2/buddies.py b/titles/mai2/buddies.py
new file mode 100644
index 0000000..ccc73bb
--- /dev/null
+++ b/titles/mai2/buddies.py
@@ -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
+
+ def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
+ user_data = super().handle_cm_get_user_preview_api_request(data)
+
+ # hardcode lastDataVersion for CardMaker
+ user_data["lastDataVersion"] = "1.40.00"
+ return user_data
diff --git a/titles/mai2/const.py b/titles/mai2/const.py
index a4c29db..ce70d70 100644
--- a/titles/mai2/const.py
+++ b/titles/mai2/const.py
@@ -53,6 +53,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 +77,7 @@ class Mai2Constants:
"maimai DX UNiVERSE PLUS",
"maimai DX FESTiVAL",
"maimai DX FESTiVAL PLUS",
+ "maimai DX BUDDiES",
)
@classmethod
diff --git a/titles/mai2/dx.py b/titles/mai2/dx.py
index 508cebb..56489dc 100644
--- a/titles/mai2/dx.py
+++ b/titles/mai2/dx.py
@@ -213,6 +213,9 @@ class Mai2DX(Mai2Base):
)
self.data.item.put_friend_season_ranking(user_id, fsr)
+ if "user2pPlaylog" in upsert:
+ self.data.score.put_2p_playlog(user_id, upsert["user2pPlaylog"])
+
return {"returnCode": 1, "apiName": "UpsertUserAllApi"}
def handle_get_user_data_api_request(self, data: Dict) -> Dict:
diff --git a/titles/mai2/index.py b/titles/mai2/index.py
index 793aaef..b4cb228 100644
--- a/titles/mai2/index.py
+++ b/titles/mai2/index.py
@@ -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")
@@ -252,8 +254,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.getHeader("Mai-Encoding") is not None
diff --git a/titles/mai2/schema/profile.py b/titles/mai2/schema/profile.py
index 211440d..bcb4997 100644
--- a/titles/mai2/schema/profile.py
+++ b/titles/mai2/schema/profile.py
@@ -40,6 +40,7 @@ detail = Table(
Column("charaLockSlot", JSON),
Column("contentBit", BigInteger),
Column("playCount", Integer),
+ Column("currentPlayCount", Integer), # new with buddies
Column("mapStock", Integer), # new with fes+
Column("eventWatchedDate", String(25)),
Column("lastGameId", String(25)),
@@ -96,6 +97,7 @@ detail = Table(
Column("playerNewRating", BigInteger),
Column("dateTime", BigInteger),
Column("banState", Integer), # new with uni+
+ Column("renameCredit", Integer), # new with buddies
UniqueConstraint("user", "version", name="mai2_profile_detail_uk"),
mysql_charset="utf8mb4",
)
@@ -217,7 +219,7 @@ extend = Table(
Column("isPhotoAgree", Boolean),
Column("isGotoCodeRead", Boolean),
Column("selectResultDetails", Boolean),
- Column("selectResultScoreViewType", Integer), # new with fes+
+ Column("selectResultScoreViewType", Integer), # new with fes+
Column("sortCategorySetting", Integer),
Column("sortMusicSetting", Integer),
Column("selectedCardList", JSON),
diff --git a/titles/mai2/schema/score.py b/titles/mai2/schema/score.py
index 181a895..7f29b2b 100644
--- a/titles/mai2/schema/score.py
+++ b/titles/mai2/schema/score.py
@@ -146,10 +146,29 @@ playlog = Table(
Column("extNum1", Integer),
Column("extNum2", Integer),
Column("extNum4", Integer, server_default="0"),
+ Column("extBool1", Boolean), # new with buddies
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),
+)
+
course = Table(
"mai2_score_course",
metadata,
@@ -344,6 +363,18 @@ class Mai2ScoreData(BaseData):
return None
return result.lastrowid
+ def put_2p_playlog(self, user_id: int, playlog_data: Dict) -> Optional[int]:
+ if not playlog_data["user2pPlaylogDetailList"]:
+ self.logger.info("1P play, ignoring.")
+ return None
+ playlog_data["user"] = user_id
+ sql = insert(playlog_2p).values(**playlog_data)
+ conflict = sql.on_duplicate_key_update(**playlog_data)
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(f"put_2p_playlog: Failed to insert! user_id {user_id}")
+ return None
+
def put_course(self, user_id: int, course_data: Dict) -> Optional[int]:
course_data["user"] = user_id
sql = insert(course).values(**course_data)