add back games, conform them to new title dispatch

This commit is contained in:
Hay1tsme
2023-02-17 01:02:21 -05:00
parent f18e939dd0
commit 7e3396a7ff
214 changed files with 19412 additions and 23 deletions

View File

@ -0,0 +1,6 @@
from titles.mai2.schema.profile import Mai2ProfileData
from titles.mai2.schema.item import Mai2ItemData
from titles.mai2.schema.static import Mai2StaticData
from titles.mai2.schema.score import Mai2ScoreData
__all__ = [Mai2ProfileData, Mai2ItemData, Mai2StaticData, Mai2ScoreData]

298
titles/mai2/schema/item.py Normal file
View File

@ -0,0 +1,298 @@
from core.data.schema import BaseData, metadata
from typing import Optional, Dict, List
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON
from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select
from sqlalchemy.dialects.mysql import insert
from sqlalchemy.engine import Row
character = Table(
"mai2_item_character",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("character_id", Integer, nullable=False),
Column("level", Integer, nullable=False, server_default="1"),
Column("awakening", Integer, nullable=False, server_default="0"),
Column("use_count", Integer, nullable=False, server_default="0"),
UniqueConstraint("user", "character_id", name="mai2_item_character_uk"),
mysql_charset='utf8mb4'
)
card = Table(
"mai2_item_card",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("card_kind", Integer, nullable=False),
Column("card_id", Integer, nullable=False),
Column("chara_id", Integer, nullable=False),
Column("map_id", Integer, nullable=False),
Column("start_date", String(255), nullable=False),
Column("end_date", String(255), nullable=False),
UniqueConstraint("user", "card_kind", "card_id", name="mai2_item_card_uk"),
mysql_charset='utf8mb4'
)
item = Table(
"mai2_item_item",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("item_kind", Integer, nullable=False),
Column("item_id", Integer, nullable=False),
Column("stock", Integer, nullable=False, server_default="1"),
Column("is_valid", Boolean, nullable=False, server_default="1"),
UniqueConstraint("user", "item_kind", "item_id", name="mai2_item_item_uk"),
mysql_charset='utf8mb4'
)
map = Table(
"mai2_item_map",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("map_id", Integer, nullable=False),
Column("distance", Integer, nullable=False),
Column("is_lock", Boolean, nullable=False, server_default="0"),
Column("is_clear", Boolean, nullable=False, server_default="0"),
Column("is_complete", Boolean, nullable=False, server_default="0"),
UniqueConstraint("user", "map_id", name="mai2_item_map_uk"),
mysql_charset='utf8mb4'
)
login_bonus = Table(
"mai2_item_login_bonus",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("bonus_id", Integer, nullable=False),
Column("point", Integer, nullable=False),
Column("is_current", Boolean, nullable=False, server_default="0"),
Column("is_complete", Boolean, nullable=False, server_default="0"),
UniqueConstraint("user", "bonus_id", name="mai2_item_login_bonus_uk"),
mysql_charset='utf8mb4'
)
friend_season_ranking = Table(
"mai2_item_friend_season_ranking",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("season_id", Integer, nullable=False),
Column("point", Integer, nullable=False),
Column("rank", Integer, nullable=False),
Column("reward_get", Boolean, nullable=False),
Column("user_name", String(8), nullable=False),
Column("record_date", String(255), nullable=False),
UniqueConstraint("user", "season_id", "user_name", name="mai2_item_login_bonus_uk"),
mysql_charset='utf8mb4'
)
favorite = Table(
"mai2_item_favorite",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("itemKind", Integer, nullable=False),
Column("itemIdList", JSON),
UniqueConstraint("user", "itemKind", name="mai2_item_favorite_uk"),
mysql_charset='utf8mb4'
)
charge = Table(
"mai2_item_charge",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("charge_id", Integer, nullable=False),
Column("stock", Integer, nullable=False),
Column("purchase_date", String(255), nullable=False),
Column("valid_date", String(255), nullable=False),
UniqueConstraint("user", "charge_id", name="mai2_item_charge_uk"),
mysql_charset='utf8mb4'
)
class Mai2ItemData(BaseData):
def put_item(self, user_id: int, item_kind: int, item_id: int, stock: int, is_valid: bool) -> None:
sql = insert(item).values(
user=user_id,
item_kind=item_kind,
item_id=item_id,
stock=stock,
is_valid=is_valid,
)
conflict = sql.on_duplicate_key_update(
stock=stock,
is_valid=is_valid,
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_item: failed to insert item! user_id: {user_id}, item_kind: {item_kind}, item_id: {item_id}")
return None
return result.lastrowid
def get_items(self, user_id: int, item_kind: int = None) -> Optional[List[Row]]:
if item_kind is None:
sql = item.select(item.c.user == user_id)
else:
sql = item.select(and_(item.c.user == user_id, item.c.item_kind == item_kind))
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def get_item(self, user_id: int, item_kind: int, item_id: int) -> Optional[Row]:
sql = item.select(and_(item.c.user == user_id, item.c.item_kind == item_kind, item.c.item_id == item_id))
result = self.execute(sql)
if result is None: return None
return result.fetchone()
def put_login_bonus(self, user_id: int, bonus_id: int, point: int, is_current: bool, is_complete: bool) -> None:
sql = insert(login_bonus).values(
user=user_id,
bonus_id=bonus_id,
point=point,
is_current=is_current,
is_complete=is_complete,
)
conflict = sql.on_duplicate_key_update(
point=point,
is_current=is_current,
is_complete=is_complete,
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_login_bonus: failed to insert item! user_id: {user_id}, bonus_id: {bonus_id}, point: {point}")
return None
return result.lastrowid
def get_login_bonuses(self, user_id: int) -> Optional[List[Row]]:
sql = login_bonus.select(login_bonus.c.user == user_id)
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def get_login_bonus(self, user_id: int, bonus_id: int) -> Optional[Row]:
sql = login_bonus.select(and_(login_bonus.c.user == user_id, login_bonus.c.bonus_id == bonus_id))
result = self.execute(sql)
if result is None: return None
return result.fetchone()
def put_map(self, user_id: int, map_id: int, distance: int, is_lock: bool, is_clear: bool, is_complete: bool) -> None:
sql = insert(map).values(
user=user_id,
map_id=map_id,
distance=distance,
is_lock=is_lock,
is_clear=is_clear,
is_complete=is_complete,
)
conflict = sql.on_duplicate_key_update(
distance=distance,
is_lock=is_lock,
is_clear=is_clear,
is_complete=is_complete,
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_map: failed to insert item! user_id: {user_id}, map_id: {map_id}, distance: {distance}")
return None
return result.lastrowid
def get_maps(self, user_id: int) -> Optional[List[Row]]:
sql = map.select(map.c.user == user_id)
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def get_map(self, user_id: int, map_id: int) -> Optional[Row]:
sql = map.select(and_(map.c.user == user_id, map.c.map_id == map_id))
result = self.execute(sql)
if result is None: return None
return result.fetchone()
def put_character(self, user_id: int, character_id: int, level: int, awakening: int, use_count: int) -> None:
sql = insert(character).values(
user=user_id,
character_id=character_id,
level=level,
awakening=awakening,
use_count=use_count,
)
conflict = sql.on_duplicate_key_update(
level=level,
awakening=awakening,
use_count=use_count,
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_character: failed to insert item! user_id: {user_id}, character_id: {character_id}, level: {level}")
return None
return result.lastrowid
def get_characters(self, user_id: int) -> Optional[List[Row]]:
sql = character.select(character.c.user == user_id)
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def get_character(self, user_id: int, character_id: int) -> Optional[Row]:
sql = character.select(and_(character.c.user == user_id, character.c.character_id == character_id))
result = self.execute(sql)
if result is None: return None
return result.fetchone()
def get_friend_season_ranking(self, user_id: int) -> Optional[Row]:
sql = friend_season_ranking.select(friend_season_ranking.c.user == user_id)
result = self.execute(sql)
if result is None:return None
return result.fetchone()
def put_favorite(self, user_id: int, kind: int, item_id_list: List[int]) -> Optional[int]:
sql = insert(favorite).values(
user=user_id,
kind=kind,
item_id_list=item_id_list
)
conflict = sql.on_duplicate_key_update(
item_id_list=item_id_list
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_favorite: failed to insert item! user_id: {user_id}, kind: {kind}")
return None
return result.lastrowid
def get_favorites(self, user_id: int, kind: int = None) -> Optional[Row]:
if kind is None:
sql = favorite.select(favorite.c.user == user_id)
else:
sql = favorite.select(and_(
favorite.c.user == user_id,
favorite.c.itemKind == kind
))
result = self.execute(sql)
if result is None:return None
return result.fetchall()

View File

@ -0,0 +1,402 @@
from core.data.schema import BaseData, metadata
from titles.mai2.const import Mai2Constants
from typing import Optional, Dict, List
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, BigInteger
from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select
from sqlalchemy.engine import Row
from sqlalchemy.dialects.mysql import insert
from datetime import datetime
detail = Table(
"mai2_profile_detail",
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("userName", String(25)),
Column("isNetMember", Integer),
Column("iconId", Integer),
Column("plateId", Integer),
Column("titleId", Integer),
Column("partnerId", Integer),
Column("frameId", Integer),
Column("selectMapId", Integer),
Column("totalAwake", Integer),
Column("gradeRating", Integer),
Column("musicRating", Integer),
Column("playerRating", Integer),
Column("highestRating", Integer),
Column("gradeRank", Integer),
Column("classRank", Integer),
Column("courseRank", Integer),
Column("charaSlot", JSON),
Column("charaLockSlot", JSON),
Column("contentBit", BigInteger),
Column("playCount", Integer),
Column("eventWatchedDate", String(25)),
Column("lastGameId", String(25)),
Column("lastRomVersion", String(25)),
Column("lastDataVersion", String(25)),
Column("lastLoginDate", String(25)),
Column("lastPairLoginDate", String(25)), # new with uni+
Column("lastPlayDate", String(25)),
Column("lastTrialPlayDate", String(25)), # new with uni+
Column("lastPlayCredit", Integer),
Column("lastPlayMode", Integer),
Column("lastPlaceId", Integer),
Column("lastPlaceName", String(25)),
Column("lastAllNetId", Integer),
Column("lastRegionId", Integer),
Column("lastRegionName", String(25)),
Column("lastClientId", String(25)),
Column("lastCountryCode", String(25)),
Column("lastSelectEMoney", Integer),
Column("lastSelectTicket", Integer),
Column("lastSelectCourse", Integer),
Column("lastCountCourse", Integer),
Column("firstGameId", String(25)),
Column("firstRomVersion", String(25)),
Column("firstDataVersion", String(25)),
Column("firstPlayDate", String(25)),
Column("compatibleCmVersion", String(25)),
Column("dailyBonusDate", String(25)),
Column("dailyCourseBonusDate", String(25)),
Column("playVsCount", Integer),
Column("playSyncCount", Integer),
Column("winCount", Integer),
Column("helpCount", Integer),
Column("comboCount", Integer),
Column("totalDeluxscore", BigInteger),
Column("totalBasicDeluxscore", BigInteger),
Column("totalAdvancedDeluxscore", BigInteger),
Column("totalExpertDeluxscore", BigInteger),
Column("totalMasterDeluxscore", BigInteger),
Column("totalReMasterDeluxscore", BigInteger),
Column("totalSync", Integer),
Column("totalBasicSync", Integer),
Column("totalAdvancedSync", Integer),
Column("totalExpertSync", Integer),
Column("totalMasterSync", Integer),
Column("totalReMasterSync", Integer),
Column("totalAchievement", BigInteger),
Column("totalBasicAchievement", BigInteger),
Column("totalAdvancedAchievement", BigInteger),
Column("totalExpertAchievement", BigInteger),
Column("totalMasterAchievement", BigInteger),
Column("totalReMasterAchievement", BigInteger),
Column("playerOldRating", BigInteger),
Column("playerNewRating", BigInteger),
Column("dateTime", BigInteger),
Column("banState", Integer), # new with uni+
UniqueConstraint("user", "version", name="mai2_profile_detail_uk"),
mysql_charset='utf8mb4'
)
ghost = Table(
"mai2_profile_ghost",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("version_int", Integer, nullable=False),
Column("name", String(25)),
Column("iconId", Integer),
Column("plateId", Integer),
Column("titleId", Integer),
Column("rate", Integer),
Column("udemaeRate", Integer),
Column("courseRank", Integer),
Column("classRank", Integer),
Column("classValue", Integer),
Column("playDatetime", String(25)),
Column("shopId", Integer),
Column("regionCode", Integer),
Column("typeId", Integer),
Column("musicId", Integer),
Column("difficulty", Integer),
Column("version", Integer),
Column("resultBitList", JSON),
Column("resultNum", Integer),
Column("achievement", Integer),
UniqueConstraint("user", "version", "musicId", "difficulty", name="mai2_profile_ghost_uk"),
mysql_charset='utf8mb4'
)
extend = Table(
"mai2_profile_extend",
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("selectMusicId", Integer),
Column("selectDifficultyId", Integer),
Column("categoryIndex", Integer),
Column("musicIndex", Integer),
Column("extraFlag", Integer),
Column("selectScoreType", Integer),
Column("extendContentBit", BigInteger),
Column("isPhotoAgree", Boolean),
Column("isGotoCodeRead", Boolean),
Column("selectResultDetails", Boolean),
Column("sortCategorySetting", Integer),
Column("sortMusicSetting", Integer),
Column("selectedCardList", JSON),
Column("encountMapNpcList", JSON),
UniqueConstraint("user", "version", name="mai2_profile_extend_uk"),
mysql_charset='utf8mb4'
)
option = Table(
"mai2_profile_option",
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("selectMusicId", Integer),
Column("optionKind", Integer),
Column("noteSpeed", Integer),
Column("slideSpeed", Integer),
Column("touchSpeed", Integer),
Column("tapDesign", Integer),
Column("holdDesign", Integer),
Column("slideDesign", Integer),
Column("starType", Integer),
Column("outlineDesign", Integer),
Column("noteSize", Integer),
Column("slideSize", Integer),
Column("touchSize", Integer),
Column("starRotate", Integer),
Column("dispCenter", Integer),
Column("dispChain", Integer),
Column("dispRate", Integer),
Column("dispBar", Integer),
Column("touchEffect", Integer),
Column("submonitorAnimation", Integer),
Column("submonitorAchive", Integer),
Column("submonitorAppeal", Integer),
Column("matching", Integer),
Column("trackSkip", Integer),
Column("brightness", Integer),
Column("mirrorMode", Integer),
Column("dispJudge", Integer),
Column("dispJudgePos", Integer),
Column("dispJudgeTouchPos", Integer),
Column("adjustTiming", Integer),
Column("judgeTiming", Integer),
Column("ansVolume", Integer),
Column("tapHoldVolume", Integer),
Column("criticalSe", Integer),
Column("breakSe", Integer),
Column("breakVolume", Integer),
Column("exSe", Integer),
Column("exVolume", Integer),
Column("slideSe", Integer),
Column("slideVolume", Integer),
Column("touchHoldVolume", Integer),
Column("damageSeVolume", Integer),
Column("headPhoneVolume", Integer),
Column("sortTab", Integer),
Column("sortMusic", Integer),
UniqueConstraint("user", "version", name="mai2_profile_option_uk"),
mysql_charset='utf8mb4'
)
rating = Table(
"mai2_profile_rating",
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("rating", Integer),
Column("ratingList", JSON),
Column("newRatingList", JSON),
Column("nextRatingList", JSON),
Column("nextNewRatingList", JSON),
Column("udemae", JSON),
UniqueConstraint("user", "version", name="mai2_profile_rating_uk"),
mysql_charset='utf8mb4'
)
region = Table(
"mai2_profile_region",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("regionId", Integer),
Column("playCount", Integer, server_default="1"),
Column("created", String(25)),
UniqueConstraint("user", "regionId", name="mai2_profile_region_uk"),
mysql_charset='utf8mb4'
)
activity = Table(
"mai2_profile_activity",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("kind", Integer, nullable=False),
Column("activityId", Integer, nullable=False),
Column("param1", Integer, nullable=False),
Column("param2", Integer, nullable=False),
Column("param3", Integer, nullable=False),
Column("param4", Integer, nullable=False),
Column("sortNumber", Integer, nullable=False),
UniqueConstraint("user", "kind", "activityId", name="mai2_profile_activity_uk"),
mysql_charset='utf8mb4'
)
class Mai2ProfileData(BaseData):
def put_profile_detail(self, user_id: int, version: int, detail_data: Dict) -> Optional[Row]:
detail_data["user"] = user_id
detail_data["version"] = version
sql = insert(detail).values(**detail_data)
conflict = sql.on_duplicate_key_update(**detail_data)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_profile: Failed to create profile! user_id {user_id}")
return None
return result.lastrowid
def get_profile_detail(self, user_id: int, version: int) -> Optional[Row]:
sql = select(detail).where(and_(detail.c.user == user_id, detail.c.version == version))
result = self.execute(sql)
if result is None:return None
return result.fetchone()
def put_profile_ghost(self, user_id: int, version: int, ghost_data: Dict) -> Optional[int]:
ghost_data["user"] = user_id
ghost_data["version_int"] = version
sql = insert(ghost).values(**ghost_data)
conflict = sql.on_duplicate_key_update(**ghost_data)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_profile_ghost: failed to update! {user_id}")
return None
return result.lastrowid
def get_profile_ghost(self, user_id: int, version: int) -> Optional[Row]:
sql = select(ghost).where(and_(ghost.c.user == user_id, ghost.c.version_int == version))
result = self.execute(sql)
if result is None:return None
return result.fetchone()
def put_profile_extend(self, user_id: int, version: int, extend_data: Dict) -> Optional[int]:
extend_data["user"] = user_id
extend_data["version"] = version
sql = insert(extend).values(**extend_data)
conflict = sql.on_duplicate_key_update(**extend_data)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_profile_extend: failed to update! {user_id}")
return None
return result.lastrowid
def get_profile_extend(self, user_id: int, version: int) -> Optional[Row]:
sql = select(extend).where(and_(extend.c.user == user_id, extend.c.version == version))
result = self.execute(sql)
if result is None:return None
return result.fetchone()
def put_profile_option(self, user_id: int, version: int, option_data: Dict) -> Optional[int]:
option_data["user"] = user_id
option_data["version"] = version
sql = insert(option).values(**option_data)
conflict = sql.on_duplicate_key_update(**option_data)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_profile_option: failed to update! {user_id}")
return None
return result.lastrowid
def get_profile_option(self, user_id: int, version: int) -> Optional[Row]:
sql = select(option).where(and_(option.c.user == user_id, option.c.version == version))
result = self.execute(sql)
if result is None:return None
return result.fetchone()
def put_profile_rating(self, user_id: int, version: int, rating_data: Dict) -> Optional[int]:
rating_data["user"] = user_id
rating_data["version"] = version
sql = insert(rating).values(**rating_data)
conflict = sql.on_duplicate_key_update(**rating_data)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_profile_rating: failed to update! {user_id}")
return None
return result.lastrowid
def get_profile_rating(self, user_id: int, version: int) -> Optional[Row]:
sql = select(rating).where(and_(rating.c.user == user_id, rating.c.version == version))
result = self.execute(sql)
if result is None:return None
return result.fetchone()
def put_profile_region(self, user_id: int, region_id: int) -> Optional[int]:
sql = insert(region).values(
user = user_id,
regionId = region_id,
created = datetime.strftime(datetime.now(), Mai2Constants.DATE_TIME_FORMAT)
)
conflict = sql.on_duplicate_key_update(
playCount = region.c.playCount + 1
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_region: failed to update! {user_id}")
return None
return result.lastrowid
def get_regions(self, user_id: int) -> Optional[List[Dict]]:
sql = select(region).where(region.c.user == user_id)
result = self.execute(sql)
if result is None:return None
return result.fetchall()
def put_profile_activity(self, user_id: int, activity_data: Dict) -> Optional[int]:
if "id" in activity_data:
activity_data["activityId"] = activity_data["id"]
activity_data.pop("id")
activity_data["user"] = user_id
sql = insert(activity).values(**activity_data)
conflict = sql.on_duplicate_key_update(**activity_data)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"put_profile_activity: failed to update! user_id: {user_id}")
return None
return result.lastrowid
def get_profile_activity(self, user_id: int, kind: int = None) -> Optional[Row]:
sql = activity.select(
and_(
activity.c.user == user_id,
(activity.c.kind == kind) if kind is not None else True,
)
)
result = self.execute(sql)
if result is None:return None
return result.fetchone()

226
titles/mai2/schema/score.py Normal file
View File

@ -0,0 +1,226 @@
from typing import Dict, List, Optional
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, BigInteger
from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select
from sqlalchemy.engine import Row
from sqlalchemy.dialects.mysql import insert
from core.data.schema import BaseData, metadata
best_score = Table(
"mai2_score_best",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("musicId", Integer),
Column("level", Integer),
Column("playCount", Integer),
Column("achievement", Integer),
Column("comboStatus", Integer),
Column("syncStatus", Integer),
Column("deluxscoreMax", Integer),
Column("scoreRank", Integer),
UniqueConstraint("user", "musicId", "level", name="mai2_score_best_uk"),
mysql_charset='utf8mb4'
)
playlog = Table(
"mai2_playlog",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("userId", BigInteger),
Column("orderId", Integer),
Column("playlogId", BigInteger),
Column("version", Integer),
Column("placeId", Integer),
Column("placeName", String(255)),
Column("loginDate", BigInteger),
Column("playDate", String(255)),
Column("userPlayDate", String(255)),
Column("type", Integer),
Column("musicId", Integer),
Column("level", Integer),
Column("trackNo", Integer),
Column("vsMode", Integer),
Column("vsUserName", String(255)),
Column("vsStatus", Integer),
Column("vsUserRating", Integer),
Column("vsUserAchievement", Integer),
Column("vsUserGradeRank", Integer),
Column("vsRank", Integer),
Column("playerNum", Integer),
Column("playedUserId1", BigInteger),
Column("playedUserName1", String(255)),
Column("playedMusicLevel1", Integer),
Column("playedUserId2", BigInteger),
Column("playedUserName2", String(255)),
Column("playedMusicLevel2", Integer),
Column("playedUserId3", BigInteger),
Column("playedUserName3", String(255)),
Column("playedMusicLevel3", Integer),
Column("characterId1", Integer),
Column("characterLevel1", Integer),
Column("characterAwakening1", Integer),
Column("characterId2", Integer),
Column("characterLevel2", Integer),
Column("characterAwakening2", Integer),
Column("characterId3", Integer),
Column("characterLevel3", Integer),
Column("characterAwakening3", Integer),
Column("characterId4", Integer),
Column("characterLevel4", Integer),
Column("characterAwakening4", Integer),
Column("characterId5", Integer),
Column("characterLevel5", Integer),
Column("characterAwakening5", Integer),
Column("achievement", Integer),
Column("deluxscore", Integer),
Column("scoreRank", Integer),
Column("maxCombo", Integer),
Column("totalCombo", Integer),
Column("maxSync", Integer),
Column("totalSync", Integer),
Column("tapCriticalPerfect", Integer),
Column("tapPerfect", Integer),
Column("tapGreat", Integer),
Column("tapGood", Integer),
Column("tapMiss", Integer),
Column("holdCriticalPerfect", Integer),
Column("holdPerfect", Integer),
Column("holdGreat", Integer),
Column("holdGood", Integer),
Column("holdMiss", Integer),
Column("slideCriticalPerfect", Integer),
Column("slidePerfect", Integer),
Column("slideGreat", Integer),
Column("slideGood", Integer),
Column("slideMiss", Integer),
Column("touchCriticalPerfect", Integer),
Column("touchPerfect", Integer),
Column("touchGreat", Integer),
Column("touchGood", Integer),
Column("touchMiss", Integer),
Column("breakCriticalPerfect", Integer),
Column("breakPerfect", Integer),
Column("breakGreat", Integer),
Column("breakGood", Integer),
Column("breakMiss", Integer),
Column("isTap", Boolean),
Column("isHold", Boolean),
Column("isSlide", Boolean),
Column("isTouch", Boolean),
Column("isBreak", Boolean),
Column("isCriticalDisp", Boolean),
Column("isFastLateDisp", Boolean),
Column("fastCount", Integer),
Column("lateCount", Integer),
Column("isAchieveNewRecord", Boolean),
Column("isDeluxscoreNewRecord", Boolean),
Column("comboStatus", Integer),
Column("syncStatus", Integer),
Column("isClear", Boolean),
Column("beforeRating", Integer),
Column("afterRating", Integer),
Column("beforeGrade", Integer),
Column("afterGrade", Integer),
Column("afterGradeRank", Integer),
Column("beforeDeluxRating", Integer),
Column("afterDeluxRating", Integer),
Column("isPlayTutorial", Boolean),
Column("isEventMode", Boolean),
Column("isFreedomMode", Boolean),
Column("playMode", Integer),
Column("isNewFree", Boolean),
Column("extNum1", Integer),
Column("extNum2", Integer),
mysql_charset='utf8mb4'
)
course = Table(
"mai2_score_course",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("user", ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False),
Column("courseId", Integer),
Column("isLastClear", Boolean),
Column("totalRestlife", Integer),
Column("totalAchievement", Integer),
Column("totalDeluxscore", Integer),
Column("playCount", Integer),
Column("clearDate", String(25)),
Column("lastPlayDate", String(25)),
Column("bestAchievement", Integer),
Column("bestAchievementDate", String(25)),
Column("bestDeluxscore", Integer),
Column("bestDeluxscoreDate", String(25)),
UniqueConstraint("user", "courseId", name="mai2_score_best_uk"),
mysql_charset='utf8mb4'
)
class Mai2ScoreData(BaseData):
def put_best_score(self, user_id: int, score_data: Dict) -> Optional[int]:
sql = insert(best_score).values(**score_data)
conflict = sql.on_duplicate_key_update(**score_data)
result = self.execute(conflict)
if result is None:
self.logger.error(f"put_best_score: Failed to insert best score! user_id {user_id}")
return None
return result.lastrowid
def get_best_scores(self, user_id: int, song_id: int = None) -> Optional[List[Row]]:
sql = best_score.select(
and_(
best_score.c.user == user_id,
(best_score.c.song_id == song_id) if song_id is not None else True
)
)
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def get_best_score(self, user_id: int, song_id: int, chart_id: int) -> Optional[Row]:
sql = best_score.select(
and_(
best_score.c.user == user_id,
best_score.c.song_id == song_id,
best_score.c.chart_id == chart_id
)
)
result = self.execute(sql)
if result is None: return None
return result.fetchone()
def put_playlog(self, user_id: int, playlog_data: Dict) -> Optional[int]:
sql = insert(playlog).values(**playlog_data)
conflict = sql.on_duplicate_key_update(**playlog_data)
result = self.execute(conflict)
if result is None:
self.logger.error(f"put_playlog: Failed to insert! user_id {user_id}")
return None
return result.lastrowid
def put_course(self, user_id: int, course_data: Dict) -> Optional[int]:
sql = insert(course).values(**course_data)
conflict = sql.on_duplicate_key_update(**course_data)
result = self.execute(conflict)
if result is None:
self.logger.error(f"put_course: Failed to insert! user_id {user_id}")
return None
return result.lastrowid
def get_courses(self, user_id: int) -> Optional[List[Row]]:
sql = course.select(best_score.c.user == user_id)
result = self.execute(sql)
if result is None: return None
return result.fetchone()

View File

@ -0,0 +1,178 @@
from core.data.schema.base import BaseData, metadata
from typing import Optional, Dict, List
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, Float
from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select
from sqlalchemy.engine import Row
from sqlalchemy.dialects.mysql import insert
event = Table(
"mai2_static_event",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("version", Integer,nullable=False),
Column("eventId", Integer),
Column("type", Integer),
Column("name", String(255)),
Column("enabled", Boolean, server_default="1"),
UniqueConstraint("version", "eventId", "type", name="mai2_static_event_uk"),
mysql_charset='utf8mb4'
)
music = Table(
"mai2_static_music",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("version", Integer,nullable=False),
Column("songId", Integer),
Column("chartId", Integer),
Column("title", String(255)),
Column("artist", String(255)),
Column("genre", String(255)),
Column("bpm", Integer),
Column("addedVersion", String(255)),
Column("difficulty", Float),
Column("noteDesigner", String(255)),
UniqueConstraint("songId", "chartId", "version", name="mai2_static_music_uk"),
mysql_charset='utf8mb4'
)
ticket = Table(
"mai2_static_ticket",
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("version", Integer,nullable=False),
Column("ticketId", Integer),
Column("kind", Integer),
Column("name", String(255)),
Column("price", Integer, server_default="1"),
Column("enabled", Boolean, server_default="1"),
UniqueConstraint("version","ticketId", name="mai2_static_ticket_uk"),
mysql_charset='utf8mb4'
)
class Mai2StaticData(BaseData):
def put_game_event(self, version: int, type: int, event_id: int, name: str) -> Optional[int]:
sql = insert(event).values(
version = version,
type = type,
eventId = event_id,
name = name,
)
conflict = sql.on_duplicate_key_update(
eventId = event_id
)
result = self.execute(conflict)
if result is None:
self.logger.warning(f"put_game_event: Failed to insert event! event_id {event_id} type {type} name {name}")
return result.lastrowid
def get_game_events(self, version: int) -> Optional[List[Row]]:
sql = event.select(event.c.version == version)
result = self.execute(sql)
if result is None:
return None
return result.fetchall()
def get_enabled_events(self, version: int) -> Optional[List[Row]]:
sql = select(event).where(and_(
event.c.version == version,
event.c.enabled == True
))
result = self.execute(sql)
if result is None: return None
return result.fetchall()
def toggle_game_events(self, version: int, event_id: int, toggle: bool) -> Optional[List]:
sql = event.update(and_(event.c.version == version, event.c.event_id == event_id)).values(
enabled = int(toggle)
)
result = self.execute(sql)
if result is None:
self.logger.warning(f"toggle_game_events: Failed to update event! event_id {event_id} toggle {toggle}")
return result.last_updated_params()
def put_game_music(self, version: int, song_id: int, chart_id: int, title: str, artist: str,
genre: str, bpm: str, added_version: str, difficulty: float, note_designer: str) -> None:
sql = insert(music).values(
version = version,
songId = song_id,
chartId = chart_id,
title = title,
artist = artist,
genre = genre,
bpm = bpm,
addedVersion = added_version,
difficulty = difficulty,
noteDesigner = note_designer,
)
conflict = sql.on_duplicate_key_update(
title = title,
artist = artist,
genre = genre,
bpm = bpm,
addedVersion = added_version,
difficulty = difficulty,
noteDesigner = note_designer,
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"Failed to insert song {song_id} chart {chart_id}")
return None
return result.lastrowid
def put_game_ticket(self, version: int, ticket_id: int, ticket_type: int, ticket_price: int, name: str) -> Optional[int]:
sql = insert(ticket).values(
version = version,
ticketId = ticket_id,
kind = ticket_type,
price = ticket_price,
name = name
)
conflict = sql.on_duplicate_key_update(
price = ticket_price
)
result = self.execute(conflict)
if result is None:
self.logger.warn(f"Failed to insert charge {ticket_id} type {ticket_type}")
return None
return result.lastrowid
def get_enabled_tickets(self, version: int, kind: int = None) -> Optional[List[Row]]:
if kind is not None:
sql = select(ticket).where(and_(
ticket.c.version == version,
ticket.c.enabled == True,
ticket.c.kind == kind
))
else:
sql = select(ticket).where(and_(
ticket.c.version == version,
ticket.c.enabled == True
))
result = self.execute(sql)
if result is None:return None
return result.fetchall()
def get_music_chart(self, version: int, song_id: int, chart_id: int) -> Optional[List[Row]]:
sql = select(music).where(and_(
music.c.version == version,
music.c.songId == song_id,
music.c.chartId == chart_id
))
result = self.execute(sql)
if result is None: return None
return result.fetchone()