Merge branch 'develop' into idac
This commit is contained in:
@@ -925,6 +925,17 @@ class ChuniBase:
|
||||
for rp in upsert["userRecentPlayerList"]:
|
||||
pass
|
||||
|
||||
for rating_type in {"userRatingBaseList", "userRatingBaseHotList", "userRatingBaseNextList"}:
|
||||
if rating_type not in upsert:
|
||||
continue
|
||||
|
||||
await self.data.profile.put_profile_rating(
|
||||
user_id,
|
||||
self.version,
|
||||
rating_type,
|
||||
upsert[rating_type],
|
||||
)
|
||||
|
||||
return {"returnCode": "1"}
|
||||
|
||||
async def handle_upsert_user_chargelog_api_request(self, data: Dict) -> Dict:
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
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.engine.base import Connection
|
||||
from sqlalchemy import Table, Column, UniqueConstraint, and_
|
||||
from sqlalchemy.types import Integer, String, Boolean, JSON, BigInteger
|
||||
from sqlalchemy.schema import ForeignKey
|
||||
from sqlalchemy.engine import Row
|
||||
from sqlalchemy.sql import func, select
|
||||
from sqlalchemy.sql import select, delete
|
||||
from sqlalchemy.dialects.mysql import insert
|
||||
|
||||
from core.data.schema import BaseData, metadata
|
||||
@@ -393,6 +392,26 @@ team = Table(
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
rating = Table(
|
||||
"chuni_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("type", String(255), nullable=False),
|
||||
Column("index", Integer, nullable=False),
|
||||
Column("musicId", Integer),
|
||||
Column("difficultId", Integer),
|
||||
Column("romVersionCode", Integer),
|
||||
Column("score", Integer),
|
||||
UniqueConstraint("user", "version", "type", "index", name="chuni_profile_rating_best_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
|
||||
class ChuniProfileData(BaseData):
|
||||
async def update_name(self, user_id: int, new_name: str) -> bool:
|
||||
@@ -714,3 +733,27 @@ class ChuniProfileData(BaseData):
|
||||
return {
|
||||
"total_play_count": total_play_count
|
||||
}
|
||||
|
||||
async def put_profile_rating(
|
||||
self,
|
||||
aime_id: int,
|
||||
version: int,
|
||||
rating_type: str,
|
||||
rating_data: List[Dict],
|
||||
):
|
||||
inserted_values = [
|
||||
{"user": aime_id, "version": version, "type": rating_type, "index": i, **x}
|
||||
for (i, x) in enumerate(rating_data)
|
||||
]
|
||||
sql = insert(rating).values(inserted_values)
|
||||
update_dict = {x.name: x for x in sql.inserted if x.name != "id"}
|
||||
sql = sql.on_duplicate_key_update(**update_dict)
|
||||
result = await self.execute(sql)
|
||||
|
||||
if result is None:
|
||||
self.logger.warn(
|
||||
f"put_profile_rating: Could not insert {rating_type}, aime_id: {aime_id}",
|
||||
)
|
||||
return
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
@@ -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):
|
||||
@@ -225,12 +226,6 @@ class CardMakerReader(BaseReader):
|
||||
True if troot.find("disable").text == "false" else False
|
||||
)
|
||||
|
||||
# check if a date is part of the name and disable the
|
||||
# card if it is
|
||||
enabled = (
|
||||
False if re.search(r"\d{2}/\d{2}/\d{2}", name) else enabled
|
||||
)
|
||||
|
||||
await self.mai2_data.static.put_card(
|
||||
version, card_id, name, enabled=enabled
|
||||
)
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
saleID.,<EFBFBD>J<EFBFBD>n<EFBFBD><EFBFBD>,<EFBFBD>I<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,ShopID,Price,
|
||||
0,1411696799,1443236400,0,7000,
|
||||
1,1411783199,1443322800,1,7000,
|
||||
|
@@ -1,4 +0,0 @@
|
||||
shopID.,整理用No.,Ver.,出現フラグ,出現フラグ参照ID,条件,出現時間,消滅時間,ItemCode,価格,表示タイプ,Text,Type,Value(op),Value,対象曲,Difficulty(op),Difficulty,Level(op),Level,Grade(Op),Grade,GaugeType(op),GaugeType,HS(op)i,HS,APP,DAP,F-V,F-H,FullCombo,Combo(op),Combo,ClearRate(op),ClearRate,プレイ日,地域,
|
||||
3000,1,1.00.00,1,-1,-,1411697520.0288,1443233520.0288,skb0000,10,1,MASTER以上の2曲S+以上フルコンボクリアする。,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
3001,2,1.00.00,1,-1,-,1411697520.0288,1443233520.0288,skb0001,10,1,Next Frontier (Master)をクリア,0,-1,-1,bleeze,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
3002,3,1.00.00,1,-1,-,1412103600.0288,1443639598.992,skb0002,10,2,Master以上を1曲をS+以上でクリアする。,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,1,
|
||||
|
@@ -1,11 +0,0 @@
|
||||
shopID.,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pNo.,Ver.,<EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><EFBFBD><EFBFBD>O,<EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><EFBFBD><EFBFBD>O<EFBFBD>Q<EFBFBD><EFBFBD>ID,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD>o<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>Ŏ<EFBFBD><EFBFBD><EFBFBD>,ItemCode,<EFBFBD><EFBFBD><EFBFBD>i,<EFBFBD>\<5C><><EFBFBD>^<5E>C<EFBFBD>v,Text,Type,Value(op),Value,<EFBFBD>Ώۋ<EFBFBD>,Difficulty(op),Difficulty,Level(op),Level,Grade(Op),Grade,GaugeType(op),GaugeType,HS(op)i,HS,APP,DAP,F-V,F-H,FullCombo,Combo(op),Combo,ClearRate(op),ClearRate,<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>C<EFBFBD><EFBFBD>,<EFBFBD>n<EFBFBD><EFBFBD>,
|
||||
5000,1,10000,1,-1,-,1411697520,1443233520,ske0000,10,1,MASTER<EFBFBD>ȏ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>S+<2B>ȏ<EFBFBD>t<EFBFBD><74><EFBFBD>R<EFBFBD><52><EFBFBD>{<7B>N<EFBFBD><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>B,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5001,2,10000,1,-1,-,1411697520,1443233520,ske0001,10,1,Next Frontier (Master<65>j<EFBFBD><6A><EFBFBD>N<EFBFBD><4E><EFBFBD>A,0,-1,-1,megaro,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5002,3,10000,1,-1,-,1412103600,1443639598,ske0002,10,2,Master<EFBFBD>ȏ<EFBFBD><EFBFBD>1<EFBFBD>Ȃ<EFBFBD>S+<2B>ȏ<EFBFBD>ŃN<C583><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>B,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,1,
|
||||
5003,4,10000,1,-1,-,1412103600,1443639598,ske0003,10,0,Master<EFBFBD>ȏ<EFBFBD><EFBFBD>1<EFBFBD>Ȃ<EFBFBD>S+<2B>ȏ<EFBFBD>ŃN<C583><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>B,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5004,5,10000,1,-1,-,1412103600,1443639598,ske0004,10,2,2<EFBFBD>ȃN<EFBFBD><EFBFBD><EFBFBD>A,1,1,2,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5005,5,10000,1,-1,-,1412103600,1443639598,ske0005,10,2,3<EFBFBD>ȃN<EFBFBD><EFBFBD><EFBFBD>A,1,1,3,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5006,5,10000,1,-1,-,1412103600,1443639598,ske0006,10,2,4<EFBFBD>ȃN<EFBFBD><EFBFBD><EFBFBD>A,1,1,4,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5007,5,10000,1,-1,-,1412103600,1443639598,ske0007,10,2,5<EFBFBD>ȃN<EFBFBD><EFBFBD><EFBFBD>A,1,1,5,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5008,5,10000,1,-1,-,1412103600,1443639598,ske0008,10,2,6<EFBFBD>ȃN<EFBFBD><EFBFBD><EFBFBD>A,1,1,6,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
5009,5,10000,1,-1,-,1412103600,1443639598,ske0009,10,2,7<EFBFBD>ȃN<EFBFBD><EFBFBD><EFBFBD>A,1,1,7,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
|
@@ -1,6 +0,0 @@
|
||||
shopID.,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pNo.,Ver.,<EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><EFBFBD><EFBFBD>O,<EFBFBD>o<EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><EFBFBD><EFBFBD>O<EFBFBD>Q<EFBFBD><EFBFBD>ID,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD>o<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD>Ŏ<EFBFBD><EFBFBD><EFBFBD>,ItemCode,<EFBFBD><EFBFBD><EFBFBD>i,<EFBFBD>\<5C><><EFBFBD>^<5E>C<EFBFBD>v,Text,Type,Value(op),Value,<EFBFBD>Ώۋ<EFBFBD>,Difficulty(op),Difficulty,Level(op),Level,Grade(Op),Grade,GaugeType(op),GaugeType,HS(op)i,HS,APP,DAP,F-V,F-H,FullCombo,Combo(op),Combo,ClearRate(op),ClearRate,<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>C<EFBFBD><EFBFBD>,<EFBFBD>n<EFBFBD><EFBFBD>,
|
||||
4000,1,10000,1,-1,-,1411697520,4096483201,skt0000,10,1,MASTER<EFBFBD>ȏ<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>S+<2B>ȏ<EFBFBD>t<EFBFBD><74><EFBFBD>R<EFBFBD><52><EFBFBD>{<7B>N<EFBFBD><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>B,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
4001,2,10000,1,-1,-,1411697520,4096483201,skt0001,10,1,Next Frontier (Master<65>j<EFBFBD><6A><EFBFBD>N<EFBFBD><4E><EFBFBD>A,0,-1,-1,megaro,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
4002,3,10000,1,-1,-,1412103600,4096483201,skt0002,10,2,Master<EFBFBD>ȏ<EFBFBD><EFBFBD>1<EFBFBD>Ȃ<EFBFBD>S+<2B>ȏ<EFBFBD>ŃN<C583><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>B,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,1,
|
||||
4003,4,10000,1,-1,-,1412103600,4096483201,skt0003,10,0,Master<EFBFBD>ȏ<EFBFBD><EFBFBD>1<EFBFBD>Ȃ<EFBFBD>S+<2B>ȏ<EFBFBD>ŃN<C583><4E><EFBFBD>A<EFBFBD><41><EFBFBD><EFBFBD>B,1,1,1,-,1,2,-1,-1,1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
4004,5,10000,1,-1,-,1412103600,4096483201,skt0004,10,2,aaaaaaaaaaaaaaaaa,1,1,20,-,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,,,
|
||||
|
@@ -73,42 +73,6 @@ class CxbRevSunriseS1(CxbBase):
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
|
||||
# ShopListSale load
|
||||
ret_str += "\r\n#ShopListSale\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss1/Shop/ShopList_Sale.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
|
||||
# ShopListSkinBg load
|
||||
ret_str += "\r\n#ShopListSkinBg\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss1/Shop/ShopList_SkinBg.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
|
||||
# ShopListSkinEffect load
|
||||
ret_str += "\r\n#ShopListSkinEffect\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss1/Shop/ShopList_SkinEffect.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
|
||||
# ShopListSkinNotes load
|
||||
ret_str += "\r\n#ShopListSkinNotes\r\n"
|
||||
with open(
|
||||
r"titles/cxb/data/rss1/Shop/ShopList_SkinNotes.csv", encoding="shift-jis"
|
||||
) as shop:
|
||||
lines = shop.readlines()
|
||||
for line in lines:
|
||||
ret_str += f"{line[:-1]}\r\n"
|
||||
|
||||
# ShopListTitle load
|
||||
ret_str += "\r\n#ShopListTitle\r\n"
|
||||
with open(
|
||||
|
||||
32
titles/mai2/buddies.py
Normal file
32
titles/mai2/buddies.py
Normal file
@@ -0,0 +1,32 @@
|
||||
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
|
||||
|
||||
async def handle_get_user_new_item_api_request(self, data: Dict) -> Dict:
|
||||
# TODO: Added in 1.41, implement this?
|
||||
user_id = data["userId"]
|
||||
version = data.get("version", 1041000)
|
||||
user_playlog_list = data.get("userPlaylogList", [])
|
||||
|
||||
return {
|
||||
"userId": user_id,
|
||||
"itemKind": -1,
|
||||
"itemId": -1,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -212,6 +212,9 @@ class Mai2DX(Mai2Base):
|
||||
),
|
||||
)
|
||||
await self.data.item.put_friend_season_ranking(user_id, fsr)
|
||||
|
||||
if "user2pPlaylog" in upsert:
|
||||
await self.data.score.put_playlog_2p(user_id, upsert["user2pPlaylog"])
|
||||
|
||||
return {"returnCode": 1, "apiName": "UpsertUserAllApi"}
|
||||
|
||||
|
||||
@@ -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")
|
||||
@@ -257,8 +259,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
|
||||
|
||||
@@ -40,6 +40,8 @@ detail = Table(
|
||||
Column("charaLockSlot", JSON),
|
||||
Column("contentBit", BigInteger),
|
||||
Column("playCount", Integer),
|
||||
Column("currentPlayCount", Integer), # new with buddies
|
||||
Column("renameCredit", Integer), # new with buddies
|
||||
Column("mapStock", Integer), # new with fes+
|
||||
Column("eventWatchedDate", String(25)),
|
||||
Column("lastGameId", String(25)),
|
||||
|
||||
@@ -145,11 +145,34 @@ playlog = Table(
|
||||
Column("isNewFree", Boolean),
|
||||
Column("extNum1", Integer),
|
||||
Column("extNum2", Integer),
|
||||
Column("extNum4", Integer, server_default="0"),
|
||||
Column("extNum4", Integer),
|
||||
Column("extBool1", Boolean), # new with buddies
|
||||
Column("trialPlayAchievement", Integer),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
# new with buddies
|
||||
playlog_2p = Table(
|
||||
"mai2_playlog_2p",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column(
|
||||
"user",
|
||||
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
|
||||
nullable=False,
|
||||
),
|
||||
# TODO: ForeignKey to aime_user?
|
||||
Column("userId1", Integer),
|
||||
Column("userId2", Integer),
|
||||
# TODO: ForeignKey to mai2_profile_detail?
|
||||
Column("userName1", String(25)),
|
||||
Column("userName2", String(25)),
|
||||
Column("regionId", Integer),
|
||||
Column("placeId", Integer),
|
||||
Column("user2pPlaylogDetailList", JSON),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
course = Table(
|
||||
"mai2_score_course",
|
||||
metadata,
|
||||
@@ -343,6 +366,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_playlog_2p(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_playlog_2p: 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
|
||||
|
||||
@@ -1067,6 +1067,24 @@ class OngekiBase:
|
||||
if "userKopList" in upsert:
|
||||
for x in upsert["userKopList"]:
|
||||
await self.data.profile.put_kop(user_id, x)
|
||||
|
||||
for rating_type in {
|
||||
"userRatingBaseBestList",
|
||||
"userRatingBaseBestNewList",
|
||||
"userRatingBaseHotList",
|
||||
"userRatingBaseNextList",
|
||||
"userRatingBaseNextNewList",
|
||||
"userRatingBaseHotNextList",
|
||||
}:
|
||||
if rating_type not in upsert:
|
||||
continue
|
||||
|
||||
await self.data.profile.put_profile_rating(
|
||||
user_id,
|
||||
self.version,
|
||||
rating_type,
|
||||
upsert[rating_type],
|
||||
)
|
||||
|
||||
return {"returnCode": 1, "apiName": "upsertUserAll"}
|
||||
|
||||
|
||||
@@ -246,6 +246,26 @@ rival = Table(
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
rating = Table(
|
||||
"ongeki_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("type", String(255), nullable=False),
|
||||
Column("index", Integer, nullable=False),
|
||||
Column("musicId", Integer),
|
||||
Column("difficultId", Integer),
|
||||
Column("romVersionCode", Integer),
|
||||
Column("score", Integer),
|
||||
UniqueConstraint("user", "version", "type", "index", name="ongeki_profile_rating_best_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
|
||||
class OngekiProfileData(BaseData):
|
||||
def __init__(self, cfg: CoreConfig, conn: Connection) -> None:
|
||||
@@ -508,10 +528,35 @@ class OngekiProfileData(BaseData):
|
||||
)
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
async def delete_rival(self, aime_id: int, rival_id: int) -> Optional[int]:
|
||||
sql = delete(rival).where(rival.c.user==aime_id, rival.c.rivalUserId==rival_id)
|
||||
result = await self.execute(sql)
|
||||
if result is None:
|
||||
self.logger.error(f"delete_rival: failed to delete! aime_id: {aime_id}, rival_id: {rival_id}")
|
||||
else:
|
||||
return result.rowcount
|
||||
return result.rowcount
|
||||
|
||||
async def put_profile_rating(
|
||||
self,
|
||||
aime_id: int,
|
||||
version: int,
|
||||
rating_type: str,
|
||||
rating_data: List[Dict],
|
||||
):
|
||||
inserted_values = [
|
||||
{"user": aime_id, "version": version, "type": rating_type, "index": i, **x}
|
||||
for (i, x) in enumerate(rating_data)
|
||||
]
|
||||
sql = insert(rating).values(inserted_values)
|
||||
update_dict = {x.name: x for x in sql.inserted if x.name != "id"}
|
||||
sql = sql.on_duplicate_key_update(**update_dict)
|
||||
result = await self.execute(sql)
|
||||
|
||||
if result is None:
|
||||
self.logger.warn(
|
||||
f"put_profile_rating_{rating_type}: Could not insert rating entries, aime_id: {aime_id}",
|
||||
)
|
||||
return
|
||||
|
||||
return result.lastrowid
|
||||
|
||||
@@ -11,25 +11,24 @@ from titles.wacca.handlers import *
|
||||
|
||||
|
||||
class WaccaS(WaccaBase):
|
||||
allowed_stages = [
|
||||
(1513, 13),
|
||||
(1512, 12),
|
||||
(1511, 11),
|
||||
(1510, 10),
|
||||
(1509, 9),
|
||||
(1508, 8),
|
||||
(1507, 7),
|
||||
(1506, 6),
|
||||
(1505, 5),
|
||||
(1514, 4),
|
||||
(1513, 3),
|
||||
(1512, 2),
|
||||
(1511, 1),
|
||||
]
|
||||
|
||||
def __init__(self, cfg: CoreConfig, game_cfg: WaccaConfig) -> None:
|
||||
super().__init__(cfg, game_cfg)
|
||||
self.version = WaccaConstants.VER_WACCA_S
|
||||
self.allowed_stages = [
|
||||
(1513, 13),
|
||||
(1512, 12),
|
||||
(1511, 11),
|
||||
(1510, 10),
|
||||
(1509, 9),
|
||||
(1508, 8),
|
||||
(1507, 7),
|
||||
(1506, 6),
|
||||
(1505, 5),
|
||||
(1504, 4),
|
||||
(1503, 3),
|
||||
(1502, 2),
|
||||
(1501, 1),
|
||||
]
|
||||
|
||||
async def handle_advertise_GetNews_request(self, data: Dict) -> Dict:
|
||||
resp = GetNewsResponseV2()
|
||||
|
||||
Reference in New Issue
Block a user