forked from Hay1tsme/artemis
mai2: add consecutive day login count, update db to v7, fix reader, courses, and docs
This commit is contained in:
parent
a680699939
commit
f279adb894
1
core/data/schema/versions/SDEZ_6_rollback.sql
Normal file
1
core/data/schema/versions/SDEZ_6_rollback.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE aime.mai2_profile_consec_logins;
|
9
core/data/schema/versions/SDEZ_7_upgrade.sql
Normal file
9
core/data/schema/versions/SDEZ_7_upgrade.sql
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE `mai2_profile_consec_logins` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`user` int(11) NOT NULL,
|
||||||
|
`version` int(11) NOT NULL,
|
||||||
|
`logins` int(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `mai2_profile_consec_logins_uk` (`user`,`version`),
|
||||||
|
CONSTRAINT `mai2_profile_consec_logins_ibfk_1` FOREIGN KEY (`user`) REFERENCES `aime_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
@ -129,30 +129,31 @@ Config file is located in `config/cxb.yaml`.
|
|||||||
|
|
||||||
| Game Code | Version ID | Version Name |
|
| Game Code | Version ID | Version Name |
|
||||||
|-----------|------------|-------------------------|
|
|-----------|------------|-------------------------|
|
||||||
| SDEZ | 0 | maimai DX |
|
|
||||||
| SDEZ | 1 | maimai DX PLUS |
|
|
||||||
| SDEZ | 2 | maimai DX Splash |
|
|
||||||
| SDEZ | 3 | maimai DX Splash PLUS |
|
|
||||||
| SDEZ | 4 | maimai DX Universe |
|
|
||||||
| SDEZ | 5 | maimai DX Universe PLUS |
|
|
||||||
| SDEZ | 6 | maimai DX Festival |
|
|
||||||
|
|
||||||
For versions pre-dx
|
For versions pre-dx
|
||||||
| Game Code | Version ID | Version Name |
|
| Game Code | Version ID | Version Name |
|
||||||
|-----------|------------|----------------------|
|
|-----------|------------|-------------------------|
|
||||||
| SBXL | 1000 | maimai |
|
| SBXL | 0 | maimai |
|
||||||
| SBXL | 1001 | maimai PLUS |
|
| SBXL | 1 | maimai PLUS |
|
||||||
| SBZF | 1002 | maimai GreeN |
|
| SBZF | 2 | maimai GreeN |
|
||||||
| SBZF | 1003 | maimai GreeN PLUS |
|
| SBZF | 3 | maimai GreeN PLUS |
|
||||||
| SDBM | 1004 | maimai ORANGE |
|
| SDBM | 4 | maimai ORANGE |
|
||||||
| SDBM | 1005 | maimai ORANGE PLUS |
|
| SDBM | 5 | maimai ORANGE PLUS |
|
||||||
| SDCQ | 1006 | maimai PiNK |
|
| SDCQ | 6 | maimai PiNK |
|
||||||
| SDCQ | 1007 | maimai PiNK PLUS |
|
| SDCQ | 7 | maimai PiNK PLUS |
|
||||||
| SDDK | 1008 | maimai MURASAKI |
|
| SDDK | 8 | maimai MURASAKI |
|
||||||
| SDDK | 1009 | maimai MURASAKI PLUS |
|
| SDDK | 9 | maimai MURASAKI PLUS |
|
||||||
| SDDZ | 1010 | maimai MILK |
|
| SDDZ | 10 | maimai MILK |
|
||||||
| SDDZ | 1011 | maimai MILK PLUS |
|
| SDDZ | 11 | maimai MILK PLUS |
|
||||||
| SDEY | 1012 | maimai FiNALE |
|
| SDEY | 12 | maimai FiNALE |
|
||||||
|
| SDEZ | 13 | maimai DX |
|
||||||
|
| SDEZ | 14 | maimai DX PLUS |
|
||||||
|
| SDEZ | 15 | maimai DX Splash |
|
||||||
|
| SDEZ | 16 | maimai DX Splash PLUS |
|
||||||
|
| SDEZ | 17 | maimai DX Universe |
|
||||||
|
| SDEZ | 18 | maimai DX Universe PLUS |
|
||||||
|
| SDEZ | 19 | maimai DX Festival |
|
||||||
|
|
||||||
### Importer
|
### Importer
|
||||||
|
|
||||||
|
@ -16,4 +16,4 @@ game_codes = [
|
|||||||
Mai2Constants.GAME_CODE_GREEN,
|
Mai2Constants.GAME_CODE_GREEN,
|
||||||
Mai2Constants.GAME_CODE,
|
Mai2Constants.GAME_CODE,
|
||||||
]
|
]
|
||||||
current_schema_version = 6
|
current_schema_version = 7
|
||||||
|
@ -140,6 +140,7 @@ class Mai2Base:
|
|||||||
|
|
||||||
def handle_user_login_api_request(self, data: Dict) -> Dict:
|
def handle_user_login_api_request(self, data: Dict) -> Dict:
|
||||||
profile = self.data.profile.get_profile_detail(data["userId"], self.version)
|
profile = self.data.profile.get_profile_detail(data["userId"], self.version)
|
||||||
|
consec = self.data.profile.get_consec_login(data["userId"], self.version)
|
||||||
|
|
||||||
if profile is not None:
|
if profile is not None:
|
||||||
lastLoginDate = profile["lastLoginDate"]
|
lastLoginDate = profile["lastLoginDate"]
|
||||||
@ -150,12 +151,32 @@ class Mai2Base:
|
|||||||
else:
|
else:
|
||||||
loginCt = 0
|
loginCt = 0
|
||||||
lastLoginDate = "2017-12-05 07:00:00.0"
|
lastLoginDate = "2017-12-05 07:00:00.0"
|
||||||
|
|
||||||
|
if consec is None or not consec:
|
||||||
|
consec_ct = 1
|
||||||
|
|
||||||
|
else:
|
||||||
|
lastlogindate_ = datetime.strptime(profile["lastLoginDate"], "%Y-%m-%d %H:%M:%S.%f").timestamp()
|
||||||
|
today_midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp()
|
||||||
|
yesterday_midnight = today_midnight - 86400
|
||||||
|
|
||||||
|
if lastlogindate_ < today_midnight:
|
||||||
|
consec_ct = consec['logins'] + 1
|
||||||
|
self.data.profile.add_consec_login(data["userId"], self.version)
|
||||||
|
|
||||||
|
elif lastlogindate_ < yesterday_midnight:
|
||||||
|
consec_ct = 1
|
||||||
|
self.data.profile.reset_consec_login(data["userId"], self.version)
|
||||||
|
|
||||||
|
else:
|
||||||
|
consec_ct = consec['logins']
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"returnCode": 1,
|
"returnCode": 1,
|
||||||
"lastLoginDate": lastLoginDate,
|
"lastLoginDate": lastLoginDate,
|
||||||
"loginCount": loginCt,
|
"loginCount": loginCt,
|
||||||
"consecutiveLoginCount": 0, # We don't really have a way to track this...
|
"consecutiveLoginCount": consec_ct, # Number of consecutive days we've logged in.
|
||||||
}
|
}
|
||||||
|
|
||||||
def handle_upload_user_playlog_api_request(self, data: Dict) -> Dict:
|
def handle_upload_user_playlog_api_request(self, data: Dict) -> Dict:
|
||||||
@ -747,3 +768,9 @@ class Mai2Base:
|
|||||||
"nextIndex": next_index,
|
"nextIndex": next_index,
|
||||||
"userMusicList": [{"userMusicDetailList": music_detail_list}],
|
"userMusicList": [{"userMusicDetailList": music_detail_list}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def handle_upload_user_portrait_api_request(self, data: Dict) -> Dict:
|
||||||
|
self.logger.debug(data)
|
||||||
|
|
||||||
|
def handle_upload_user_photo_api_request(self, data: Dict) -> Dict:
|
||||||
|
self.logger.debug(data)
|
@ -37,7 +37,7 @@ class Mai2Reader(BaseReader):
|
|||||||
|
|
||||||
def read(self) -> None:
|
def read(self) -> None:
|
||||||
data_dirs = []
|
data_dirs = []
|
||||||
if self.version < Mai2Constants.VER_MAIMAI:
|
if self.version >= Mai2Constants.VER_MAIMAI_DX:
|
||||||
if self.bin_dir is not None:
|
if self.bin_dir is not None:
|
||||||
data_dirs += self.get_data_directories(self.bin_dir)
|
data_dirs += self.get_data_directories(self.bin_dir)
|
||||||
|
|
||||||
@ -52,7 +52,6 @@ class Mai2Reader(BaseReader):
|
|||||||
self.read_tickets(f"{dir}/ticket")
|
self.read_tickets(f"{dir}/ticket")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.logger.warn("Pre-DX Readers are not yet implemented!")
|
|
||||||
if not os.path.exists(f"{self.bin_dir}/tables"):
|
if not os.path.exists(f"{self.bin_dir}/tables"):
|
||||||
self.logger.error(f"tables directory not found in {self.bin_dir}")
|
self.logger.error(f"tables directory not found in {self.bin_dir}")
|
||||||
return
|
return
|
||||||
|
@ -461,6 +461,17 @@ recent_rating = Table(
|
|||||||
mysql_charset="utf8mb4",
|
mysql_charset="utf8mb4",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
consec_logins = Table(
|
||||||
|
"mai2_profile_consec_logins",
|
||||||
|
metadata,
|
||||||
|
Column("id", Integer, primary_key=True, nullable=False),
|
||||||
|
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
|
||||||
|
Column("version", Integer, nullable=False),
|
||||||
|
Column("logins", Integer),
|
||||||
|
UniqueConstraint("user", "version", name="mai2_profile_consec_logins_uk"),
|
||||||
|
mysql_charset="utf8mb4",
|
||||||
|
)
|
||||||
|
|
||||||
class Mai2ProfileData(BaseData):
|
class Mai2ProfileData(BaseData):
|
||||||
def put_profile_detail(
|
def put_profile_detail(
|
||||||
self, user_id: int, version: int, detail_data: Dict, is_dx: bool = True
|
self, user_id: int, version: int, detail_data: Dict, is_dx: bool = True
|
||||||
@ -764,4 +775,43 @@ class Mai2ProfileData(BaseData):
|
|||||||
result = self.execute(sql)
|
result = self.execute(sql)
|
||||||
if result is None:
|
if result is None:
|
||||||
return None
|
return None
|
||||||
return result.fetchone()
|
return result.fetchone()
|
||||||
|
|
||||||
|
def add_consec_login(self, user_id: int, version: int) -> None:
|
||||||
|
sql = insert(consec_logins).values(
|
||||||
|
user=user_id,
|
||||||
|
version=version,
|
||||||
|
logins=1
|
||||||
|
)
|
||||||
|
|
||||||
|
conflict = sql.on_duplicate_key_update(
|
||||||
|
logins=consec_logins.c.logins + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(conflict)
|
||||||
|
if result is None:
|
||||||
|
self.logger.error(f"Failed to update consecutive login count for user {user_id} version {version}")
|
||||||
|
|
||||||
|
def get_consec_login(self, user_id: int, version: int) -> Optional[Row]:
|
||||||
|
sql = select(consec_logins).where(and_(
|
||||||
|
consec_logins.c.user==user_id,
|
||||||
|
consec_logins.c.version==version,
|
||||||
|
))
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
|
||||||
|
def reset_consec_login(self, user_id: int, version: int) -> Optional[Row]:
|
||||||
|
sql = consec_logins.update(and_(
|
||||||
|
consec_logins.c.user==user_id,
|
||||||
|
consec_logins.c.version==version,
|
||||||
|
)).values(
|
||||||
|
logins=1
|
||||||
|
)
|
||||||
|
|
||||||
|
result = self.execute(sql)
|
||||||
|
if result is None:
|
||||||
|
return None
|
||||||
|
return result.fetchone()
|
||||||
|
@ -362,4 +362,4 @@ class Mai2ScoreData(BaseData):
|
|||||||
result = self.execute(sql)
|
result = self.execute(sql)
|
||||||
if result is None:
|
if result is None:
|
||||||
return None
|
return None
|
||||||
return result.fetchone()
|
return result.fetchall()
|
||||||
|
Loading…
Reference in New Issue
Block a user