Merge branch 'develop' into idac

This commit is contained in:
Dniel97
2024-03-26 22:42:16 +01:00
27 changed files with 625 additions and 124 deletions

View File

@@ -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:

View File

@@ -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

View File

@@ -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
)

View File

@@ -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 saleID. �J�n�� �I���� ShopID Price
2 0 1411696799 1443236400 0 7000
3 1 1411783199 1443322800 1 7000

View File

@@ -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 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 プレイ日 地域
2 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
3 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
4 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

View File

@@ -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 shopID. �����pNo. Ver. �o���t���O �o���t���O�Q��ID ���� �o������ ���Ŏ��� ItemCode ���i �\���^�C�v 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 �v���C�� �n��
2 5000 1 10000 1 -1 - 1411697520 1443233520 ske0000 10 1 MASTER�ȏ��2��S+�ȏ�t���R���{�N���A����B 1 1 1 - 1 2 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
3 5001 2 10000 1 -1 - 1411697520 1443233520 ske0001 10 1 Next Frontier (Master�j���N���A 0 -1 -1 megaro -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
4 5002 3 10000 1 -1 - 1412103600 1443639598 ske0002 10 2 Master�ȏ��1�Ȃ�S+�ȏ�ŃN���A����B 1 1 1 - 1 2 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1
5 5003 4 10000 1 -1 - 1412103600 1443639598 ske0003 10 0 Master�ȏ��1�Ȃ�S+�ȏ�ŃN���A����B 1 1 1 - 1 2 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
6 5004 5 10000 1 -1 - 1412103600 1443639598 ske0004 10 2 2�ȃN���A 1 1 2 - -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
7 5005 5 10000 1 -1 - 1412103600 1443639598 ske0005 10 2 3�ȃN���A 1 1 3 - -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
8 5006 5 10000 1 -1 - 1412103600 1443639598 ske0006 10 2 4�ȃN���A 1 1 4 - -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
9 5007 5 10000 1 -1 - 1412103600 1443639598 ske0007 10 2 5�ȃN���A 1 1 5 - -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
10 5008 5 10000 1 -1 - 1412103600 1443639598 ske0008 10 2 6�ȃN���A 1 1 6 - -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
11 5009 5 10000 1 -1 - 1412103600 1443639598 ske0009 10 2 7�ȃN���A 1 1 7 - -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1

View File

@@ -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,,,
1 shopID. �����pNo. Ver. �o���t���O �o���t���O�Q��ID ���� �o������ ���Ŏ��� ItemCode ���i �\���^�C�v 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 �v���C�� �n��
2 4000 1 10000 1 -1 - 1411697520 4096483201 skt0000 10 1 MASTER�ȏ��2��S+�ȏ�t���R���{�N���A����B 1 1 1 - 1 2 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
3 4001 2 10000 1 -1 - 1411697520 4096483201 skt0001 10 1 Next Frontier (Master�j���N���A 0 -1 -1 megaro -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
4 4002 3 10000 1 -1 - 1412103600 4096483201 skt0002 10 2 Master�ȏ��1�Ȃ�S+�ȏ�ŃN���A����B 1 1 1 - 1 2 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 1
5 4003 4 10000 1 -1 - 1412103600 4096483201 skt0003 10 0 Master�ȏ��1�Ȃ�S+�ȏ�ŃN���A����B 1 1 1 - 1 2 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
6 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

View File

@@ -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
View 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,
}

View File

@@ -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

View File

@@ -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"}

View File

@@ -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

View File

@@ -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)),

View File

@@ -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

View File

@@ -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"}

View File

@@ -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

View File

@@ -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()