mirror of
https://gitea.tendokyu.moe/Hay1tsme/artemis.git
synced 2026-02-13 11:17:28 +08:00
Added support for maimai and Chunithm in Card Maker 1.34/1.35 (#14)
Co-authored-by: Dniel97 <Dniel97@noreply.gitea.tendokyu.moe> Reviewed-on: https://gitea.tendokyu.moe/Hay1tsme/artemis/pulls/14 Co-authored-by: Dniel97 <dniel97@noreply.gitea.tendokyu.moe> Co-committed-by: Dniel97 <dniel97@noreply.gitea.tendokyu.moe>
This commit is contained in:
@@ -588,3 +588,11 @@ class ChuniBase:
|
||||
|
||||
def handle_upsert_client_testmode_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_get_user_net_battle_data_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"userNetBattleData": {
|
||||
"recentNBSelectMusicList": []
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class ChuniServlet:
|
||||
return (True, f"http://{core_cfg.title.hostname}/{game_code}/$v/", "")
|
||||
|
||||
def render_POST(self, request: Request, version: int, url_path: str) -> bytes:
|
||||
if url_path.lower() == "/ping":
|
||||
if url_path.lower() == "ping":
|
||||
return zlib.compress(b'{"returnCode": "1"}')
|
||||
|
||||
req_raw = request.content.getvalue()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from random import randint
|
||||
from typing import Dict
|
||||
|
||||
from core.config import CoreConfig
|
||||
@@ -61,8 +61,8 @@ class ChuniNew(ChuniBase):
|
||||
}
|
||||
|
||||
def handle_remove_token_api_request(self, data: Dict) -> Dict:
|
||||
return { "returnCode": "1" }
|
||||
|
||||
return {"returnCode": "1"}
|
||||
|
||||
def handle_delete_token_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": "1"}
|
||||
|
||||
@@ -122,11 +122,355 @@ class ChuniNew(ChuniBase):
|
||||
"playerLevel": profile["playerLevel"],
|
||||
"rating": profile["rating"],
|
||||
"headphone": profile["headphone"],
|
||||
"chargeState": 0,
|
||||
"userNameEx": "0",
|
||||
# Enables favorites and teams
|
||||
"chargeState": 1,
|
||||
"userNameEx": "",
|
||||
"banState": 0,
|
||||
"classEmblemMedal": profile["classEmblemMedal"],
|
||||
"classEmblemBase": profile["classEmblemBase"],
|
||||
"battleRankId": profile["battleRankId"],
|
||||
}
|
||||
return data1
|
||||
|
||||
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
if p is None:
|
||||
return {}
|
||||
|
||||
return {
|
||||
"userName": p["userName"],
|
||||
"level": p["level"],
|
||||
"medal": p["medal"],
|
||||
"lastDataVersion": "2.00.00",
|
||||
"isLogin": False,
|
||||
}
|
||||
|
||||
def handle_printer_login_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": 1}
|
||||
|
||||
def handle_printer_logout_api_request(self, data: Dict) -> Dict:
|
||||
return {"returnCode": 1}
|
||||
|
||||
def handle_get_game_gacha_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
returns all current active banners (gachas)
|
||||
"""
|
||||
game_gachas = self.data.static.get_gachas(self.version)
|
||||
|
||||
# clean the database rows
|
||||
game_gacha_list = []
|
||||
for gacha in game_gachas:
|
||||
tmp = gacha._asdict()
|
||||
tmp.pop("id")
|
||||
tmp.pop("version")
|
||||
tmp["startDate"] = datetime.strftime(tmp["startDate"], "%Y-%m-%d %H:%M:%S")
|
||||
tmp["endDate"] = datetime.strftime(tmp["endDate"], "%Y-%m-%d %H:%M:%S")
|
||||
tmp["noticeStartDate"] = datetime.strftime(
|
||||
tmp["noticeStartDate"], "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
tmp["noticeEndDate"] = datetime.strftime(
|
||||
tmp["noticeEndDate"], "%Y-%m-%d %H:%M:%S"
|
||||
)
|
||||
|
||||
game_gacha_list.append(tmp)
|
||||
|
||||
return {
|
||||
"length": len(game_gacha_list),
|
||||
"gameGachaList": game_gacha_list,
|
||||
# no clue
|
||||
"registIdList": [],
|
||||
}
|
||||
|
||||
def handle_get_game_gacha_card_by_id_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
returns all valid cards for a given gachaId
|
||||
"""
|
||||
game_gacha_cards = self.data.static.get_gacha_cards(data["gachaId"])
|
||||
|
||||
game_gacha_card_list = []
|
||||
for gacha_card in game_gacha_cards:
|
||||
tmp = gacha_card._asdict()
|
||||
tmp.pop("id")
|
||||
game_gacha_card_list.append(tmp)
|
||||
|
||||
return {
|
||||
"gachaId": data["gachaId"],
|
||||
"length": len(game_gacha_card_list),
|
||||
# check isPickup from the chuni_static_gachas?
|
||||
"isPickup": False,
|
||||
"gameGachaCardList": game_gacha_card_list,
|
||||
# again no clue
|
||||
"emissionList": [],
|
||||
"afterCalcList": [],
|
||||
"ssrBookCalcList": [],
|
||||
}
|
||||
|
||||
def handle_cm_get_user_data_api_request(self, data: Dict) -> Dict:
|
||||
p = self.data.profile.get_profile_data(data["userId"], self.version)
|
||||
if p is None:
|
||||
return {}
|
||||
|
||||
profile = p._asdict()
|
||||
profile.pop("id")
|
||||
profile.pop("user")
|
||||
profile.pop("version")
|
||||
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"userData": profile,
|
||||
"userEmoney": [
|
||||
{
|
||||
"type": 0,
|
||||
"emoneyCredit": 100,
|
||||
"emoneyBrand": 1,
|
||||
"ext1": 0,
|
||||
"ext2": 0,
|
||||
"ext3": 0,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
def handle_get_user_gacha_api_request(self, data: Dict) -> Dict:
|
||||
user_gachas = self.data.item.get_user_gachas(data["userId"])
|
||||
if user_gachas is None:
|
||||
return {"userId": data["userId"], "length": 0, "userGachaList": []}
|
||||
|
||||
user_gacha_list = []
|
||||
for gacha in user_gachas:
|
||||
tmp = gacha._asdict()
|
||||
tmp.pop("id")
|
||||
tmp.pop("user")
|
||||
tmp["dailyGachaDate"] = datetime.strftime(tmp["dailyGachaDate"], "%Y-%m-%d")
|
||||
user_gacha_list.append(tmp)
|
||||
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": len(user_gacha_list),
|
||||
"userGachaList": user_gacha_list,
|
||||
}
|
||||
|
||||
def handle_get_user_printed_card_api_request(self, data: Dict) -> Dict:
|
||||
user_print_list = self.data.item.get_user_print_states(
|
||||
data["userId"], has_completed=True
|
||||
)
|
||||
if user_print_list is None:
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": 0,
|
||||
"nextIndex": -1,
|
||||
"userPrintedCardList": [],
|
||||
}
|
||||
|
||||
print_list = []
|
||||
next_idx = int(data["nextIndex"])
|
||||
max_ct = int(data["maxCount"])
|
||||
|
||||
for x in range(next_idx, len(user_print_list)):
|
||||
tmp = user_print_list[x]._asdict()
|
||||
print_list.append(tmp["cardId"])
|
||||
|
||||
if len(user_print_list) >= max_ct:
|
||||
break
|
||||
|
||||
if len(user_print_list) >= max_ct:
|
||||
next_idx = next_idx + max_ct
|
||||
else:
|
||||
next_idx = -1
|
||||
|
||||
return {
|
||||
"userId": data["userId"],
|
||||
"length": len(print_list),
|
||||
"nextIndex": next_idx,
|
||||
"userPrintedCardList": print_list,
|
||||
}
|
||||
|
||||
def handle_get_user_card_print_error_api_request(self, data: Dict) -> Dict:
|
||||
user_id = data["userId"]
|
||||
|
||||
user_print_states = self.data.item.get_user_print_states(
|
||||
user_id, has_completed=False
|
||||
)
|
||||
|
||||
card_print_state_list = []
|
||||
for card in user_print_states:
|
||||
tmp = card._asdict()
|
||||
tmp["orderId"] = tmp["id"]
|
||||
tmp.pop("user")
|
||||
tmp["limitDate"] = datetime.strftime(tmp["limitDate"], "%Y-%m-%d")
|
||||
|
||||
card_print_state_list.append(tmp)
|
||||
|
||||
return {
|
||||
"userId": user_id,
|
||||
"length": len(card_print_state_list),
|
||||
"userCardPrintStateList": card_print_state_list,
|
||||
}
|
||||
|
||||
def handle_cm_get_user_character_api_request(self, data: Dict) -> Dict:
|
||||
return super().handle_get_user_character_api_request(data)
|
||||
|
||||
def handle_cm_get_user_item_api_request(self, data: Dict) -> Dict:
|
||||
return super().handle_get_user_item_api_request(data)
|
||||
|
||||
def handle_roll_gacha_api_request(self, data: Dict) -> Dict:
|
||||
"""
|
||||
Handle a gacha roll API request, with:
|
||||
gachaId: the gachaId where the cards should be pulled from
|
||||
times: the number of gacha rolls
|
||||
characterId: the character which the user wants
|
||||
"""
|
||||
gacha_id = data["gachaId"]
|
||||
num_rolls = data["times"]
|
||||
chara_id = data["characterId"]
|
||||
|
||||
rolled_cards = []
|
||||
|
||||
# characterId is set after 10 rolls, where the user can select a card
|
||||
# from all gameGachaCards, therefore the correct cardId for a given
|
||||
# characterId should be returned
|
||||
if chara_id != -1:
|
||||
# get the
|
||||
card = self.data.static.get_gacha_card_by_character(gacha_id, chara_id)
|
||||
|
||||
tmp = card._asdict()
|
||||
tmp.pop("id")
|
||||
|
||||
rolled_cards.append(tmp)
|
||||
else:
|
||||
gacha_cards = self.data.static.get_gacha_cards(gacha_id)
|
||||
|
||||
# get the card id for each roll
|
||||
for _ in range(num_rolls):
|
||||
# get the index from all possible cards
|
||||
card_idx = randint(0, len(gacha_cards) - 1)
|
||||
# remove the index from the cards so it wont get pulled again
|
||||
card = gacha_cards.pop(card_idx)
|
||||
|
||||
# remove the "id" fronm the card
|
||||
tmp = card._asdict()
|
||||
tmp.pop("id")
|
||||
|
||||
rolled_cards.append(tmp)
|
||||
|
||||
return {"length": len(rolled_cards), "gameGachaCardList": rolled_cards}
|
||||
|
||||
def handle_cm_upsert_user_gacha_api_request(self, data: Dict) -> Dict:
|
||||
upsert = data["cmUpsertUserGacha"]
|
||||
user_id = data["userId"]
|
||||
place_id = data["placeId"]
|
||||
|
||||
# save the user data
|
||||
user_data = upsert["userData"]
|
||||
user_data.pop("rankUpChallengeResults")
|
||||
user_data.pop("userEmoney")
|
||||
|
||||
self.data.profile.put_profile_data(user_id, self.version, user_data)
|
||||
|
||||
# save the user gacha
|
||||
user_gacha = upsert["userGacha"]
|
||||
gacha_id = user_gacha["gachaId"]
|
||||
user_gacha.pop("gachaId")
|
||||
user_gacha.pop("dailyGachaDate")
|
||||
|
||||
self.data.item.put_user_gacha(user_id, gacha_id, user_gacha)
|
||||
|
||||
# save all user items
|
||||
if "userItemList" in upsert:
|
||||
for item in upsert["userItemList"]:
|
||||
self.data.item.put_item(user_id, item)
|
||||
|
||||
# add every gamegachaCard to database
|
||||
for card in upsert["gameGachaCardList"]:
|
||||
self.data.item.put_user_print_state(
|
||||
user_id,
|
||||
hasCompleted=False,
|
||||
placeId=place_id,
|
||||
cardId=card["cardId"],
|
||||
gachaId=card["gachaId"],
|
||||
)
|
||||
|
||||
# retrieve every game gacha card which has been added in order to get
|
||||
# the orderId for the next request
|
||||
user_print_states = self.data.item.get_user_print_states_by_gacha(
|
||||
user_id, gacha_id, has_completed=False
|
||||
)
|
||||
card_print_state_list = []
|
||||
for card in user_print_states:
|
||||
tmp = card._asdict()
|
||||
tmp["orderId"] = tmp["id"]
|
||||
tmp.pop("user")
|
||||
tmp["limitDate"] = datetime.strftime(tmp["limitDate"], "%Y-%m-%d")
|
||||
|
||||
card_print_state_list.append(tmp)
|
||||
|
||||
return {
|
||||
"returnCode": "1",
|
||||
"apiName": "CMUpsertUserGachaApi",
|
||||
"userCardPrintStateList": card_print_state_list,
|
||||
}
|
||||
|
||||
def handle_cm_upsert_user_printlog_api_request(self, data: Dict) -> Dict:
|
||||
return {
|
||||
"returnCode": 1,
|
||||
"orderId": 0,
|
||||
"serialId": "11111111111111111111",
|
||||
"apiName": "CMUpsertUserPrintlogApi",
|
||||
}
|
||||
|
||||
def handle_cm_upsert_user_print_api_request(self, data: Dict) -> Dict:
|
||||
user_print_detail = data["userPrintDetail"]
|
||||
user_id = data["userId"]
|
||||
|
||||
# generate random serial id
|
||||
serial_id = "".join([str(randint(0, 9)) for _ in range(20)])
|
||||
|
||||
# not needed because are either zero or unset
|
||||
user_print_detail.pop("orderId")
|
||||
user_print_detail.pop("printNumber")
|
||||
user_print_detail.pop("serialId")
|
||||
user_print_detail["printDate"] = datetime.strptime(
|
||||
user_print_detail["printDate"], "%Y-%m-%d"
|
||||
)
|
||||
|
||||
# add the entry to the user print table with the random serialId
|
||||
self.data.item.put_user_print_detail(user_id, serial_id, user_print_detail)
|
||||
|
||||
return {
|
||||
"returnCode": 1,
|
||||
"orderId": 0,
|
||||
"serialId": serial_id,
|
||||
"apiName": "CMUpsertUserPrintApi",
|
||||
}
|
||||
|
||||
def handle_cm_upsert_user_print_subtract_api_request(self, data: Dict) -> Dict:
|
||||
upsert = data["userCardPrintState"]
|
||||
user_id = data["userId"]
|
||||
place_id = data["placeId"]
|
||||
|
||||
# save all user items
|
||||
if "userItemList" in data:
|
||||
for item in data["userItemList"]:
|
||||
self.data.item.put_item(user_id, item)
|
||||
|
||||
# set the card print state to success and use the orderId as the key
|
||||
self.data.item.put_user_print_state(
|
||||
user_id,
|
||||
id=upsert["orderId"],
|
||||
hasCompleted=True
|
||||
)
|
||||
|
||||
return {"returnCode": "1", "apiName": "CMUpsertUserPrintSubtractApi"}
|
||||
|
||||
def handle_cm_upsert_user_print_cancel_api_request(self, data: Dict) -> Dict:
|
||||
order_ids = data["orderIdList"]
|
||||
user_id = data["userId"]
|
||||
|
||||
# set the card print state to success and use the orderId as the key
|
||||
for order_id in order_ids:
|
||||
self.data.item.put_user_print_state(
|
||||
user_id,
|
||||
id=order_id,
|
||||
hasCompleted=True
|
||||
)
|
||||
|
||||
return {"returnCode": "1", "apiName": "CMUpsertUserPrintCancelApi"}
|
||||
|
||||
@@ -30,3 +30,10 @@ class ChuniNewPlus(ChuniNew):
|
||||
"reflectorUri"
|
||||
] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/205/ChuniServlet/"
|
||||
return ret
|
||||
|
||||
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 1.35
|
||||
user_data["lastDataVersion"] = "2.05.00"
|
||||
return user_data
|
||||
|
||||
@@ -114,6 +114,76 @@ map_area = Table(
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
gacha = Table(
|
||||
"chuni_item_gacha",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column(
|
||||
"user",
|
||||
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
|
||||
nullable=False,
|
||||
),
|
||||
Column("gachaId", Integer, nullable=False),
|
||||
Column("totalGachaCnt", Integer, server_default="0"),
|
||||
Column("ceilingGachaCnt", Integer, server_default="0"),
|
||||
Column("dailyGachaCnt", Integer, server_default="0"),
|
||||
Column("fiveGachaCnt", Integer, server_default="0"),
|
||||
Column("elevenGachaCnt", Integer, server_default="0"),
|
||||
Column("dailyGachaDate", TIMESTAMP, nullable=False, server_default=func.now()),
|
||||
UniqueConstraint("user", "gachaId", name="chuni_item_gacha_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
print_state = Table(
|
||||
"chuni_item_print_state",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column(
|
||||
"user",
|
||||
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
|
||||
nullable=False,
|
||||
),
|
||||
Column("hasCompleted", Boolean, nullable=False, server_default="0"),
|
||||
Column(
|
||||
"limitDate", TIMESTAMP, nullable=False, server_default="2038-01-01 00:00:00.0"
|
||||
),
|
||||
Column("placeId", Integer),
|
||||
Column("cardId", Integer),
|
||||
Column("gachaId", Integer),
|
||||
UniqueConstraint("id", "user", name="chuni_item_print_state_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
print_detail = Table(
|
||||
"chuni_item_print_detail",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column(
|
||||
"user",
|
||||
ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
|
||||
nullable=False,
|
||||
),
|
||||
Column("cardId", Integer, nullable=False),
|
||||
Column("printDate", TIMESTAMP, nullable=False),
|
||||
Column("serialId", String(20), nullable=False),
|
||||
Column("placeId", Integer, nullable=False),
|
||||
Column("clientId", String(11), nullable=False),
|
||||
Column("printerSerialId", String(20), nullable=False),
|
||||
Column("printOption1", Boolean, server_default="0"),
|
||||
Column("printOption2", Boolean, server_default="0"),
|
||||
Column("printOption3", Boolean, server_default="0"),
|
||||
Column("printOption4", Boolean, server_default="0"),
|
||||
Column("printOption5", Boolean, server_default="0"),
|
||||
Column("printOption6", Boolean, server_default="0"),
|
||||
Column("printOption7", Boolean, server_default="0"),
|
||||
Column("printOption8", Boolean, server_default="0"),
|
||||
Column("printOption9", Boolean, server_default="0"),
|
||||
Column("printOption10", Boolean, server_default="0"),
|
||||
Column("created", String(255), server_default=""),
|
||||
UniqueConstraint("serialId", name="chuni_item_print_detail_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
|
||||
class ChuniItemData(BaseData):
|
||||
def put_character(self, user_id: int, character_data: Dict) -> Optional[int]:
|
||||
@@ -235,3 +305,89 @@ class ChuniItemData(BaseData):
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_user_gachas(self, aime_id: int) -> Optional[List[Row]]:
|
||||
sql = gacha.select(gacha.c.user == aime_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_user_gacha(
|
||||
self, aime_id: int, gacha_id: int, gacha_data: Dict
|
||||
) -> Optional[int]:
|
||||
sql = insert(gacha).values(user=aime_id, gachaId=gacha_id, **gacha_data)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(
|
||||
user=aime_id, gachaId=gacha_id, **gacha_data
|
||||
)
|
||||
result = self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warn(f"put_user_gacha: Failed to insert! aime_id: {aime_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_user_print_states(
|
||||
self, aime_id: int, has_completed: bool = False
|
||||
) -> Optional[List[Row]]:
|
||||
sql = print_state.select(
|
||||
and_(
|
||||
print_state.c.user == aime_id,
|
||||
print_state.c.hasCompleted == has_completed
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_user_print_states_by_gacha(
|
||||
self, aime_id: int, gacha_id: int, has_completed: bool = False
|
||||
) -> Optional[List[Row]]:
|
||||
sql = print_state.select(
|
||||
and_(
|
||||
print_state.c.user == aime_id,
|
||||
print_state.c.gachaId == gacha_id,
|
||||
print_state.c.hasCompleted == has_completed
|
||||
)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def put_user_print_state(self, aime_id: int, **print_data) -> Optional[int]:
|
||||
sql = insert(print_state).values(user=aime_id, **print_data)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(user=aime_id, **print_data)
|
||||
result = self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warn(
|
||||
f"put_user_print_state: Failed to insert! aime_id: {aime_id}"
|
||||
)
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def put_user_print_detail(
|
||||
self, aime_id: int, serial_id: str, user_print_data: Dict
|
||||
) -> Optional[int]:
|
||||
sql = insert(print_detail).values(
|
||||
user=aime_id, serialId=serial_id, **user_print_data
|
||||
)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(
|
||||
user=aime_id, **user_print_data
|
||||
)
|
||||
result = self.execute(conflict)
|
||||
|
||||
if result is None:
|
||||
self.logger.warn(
|
||||
f"put_user_print_detail: Failed to insert! aime_id: {aime_id}"
|
||||
)
|
||||
return None
|
||||
return result.lastrowid
|
||||
@@ -68,6 +68,60 @@ avatar = Table(
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
gachas = Table(
|
||||
"chuni_static_gachas",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column("version", Integer, nullable=False),
|
||||
Column("gachaId", Integer, nullable=False),
|
||||
Column("gachaName", String(255), nullable=False),
|
||||
Column("type", Integer, nullable=False, server_default="0"),
|
||||
Column("kind", Integer, nullable=False, server_default="0"),
|
||||
Column("isCeiling", Boolean, server_default="0"),
|
||||
Column("ceilingCnt", Integer, server_default="10"),
|
||||
Column("changeRateCnt1", Integer, server_default="0"),
|
||||
Column("changeRateCnt2", Integer, server_default="0"),
|
||||
Column("startDate", TIMESTAMP, server_default="2018-01-01 00:00:00.0"),
|
||||
Column("endDate", TIMESTAMP, server_default="2038-01-01 00:00:00.0"),
|
||||
Column("noticeStartDate", TIMESTAMP, server_default="2018-01-01 00:00:00.0"),
|
||||
Column("noticeEndDate", TIMESTAMP, server_default="2038-01-01 00:00:00.0"),
|
||||
UniqueConstraint("version", "gachaId", "gachaName", name="chuni_static_gachas_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
cards = Table(
|
||||
"chuni_static_cards",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column("version", Integer, nullable=False),
|
||||
Column("cardId", Integer, nullable=False),
|
||||
Column("charaName", String(255), nullable=False),
|
||||
Column("charaId", Integer, nullable=False),
|
||||
Column("presentName", String(255), nullable=False),
|
||||
Column("rarity", Integer, server_default="2"),
|
||||
Column("labelType", Integer, nullable=False),
|
||||
Column("difType", Integer, nullable=False),
|
||||
Column("miss", Integer, nullable=False),
|
||||
Column("combo", Integer, nullable=False),
|
||||
Column("chain", Integer, nullable=False),
|
||||
Column("skillName", String(255), nullable=False),
|
||||
UniqueConstraint("version", "cardId", name="chuni_static_cards_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
gacha_cards = Table(
|
||||
"chuni_static_gacha_cards",
|
||||
metadata,
|
||||
Column("id", Integer, primary_key=True, nullable=False),
|
||||
Column("gachaId", Integer, nullable=False),
|
||||
Column("cardId", Integer, nullable=False),
|
||||
Column("rarity", Integer, nullable=False),
|
||||
Column("weight", Integer, server_default="1"),
|
||||
Column("isPickup", Boolean, server_default="0"),
|
||||
UniqueConstraint("gachaId", "cardId", name="chuni_static_gacha_cards_uk"),
|
||||
mysql_charset="utf8mb4",
|
||||
)
|
||||
|
||||
|
||||
class ChuniStaticData(BaseData):
|
||||
def put_event(
|
||||
@@ -265,3 +319,112 @@ class ChuniStaticData(BaseData):
|
||||
if result is None:
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def put_gacha(
|
||||
self,
|
||||
version: int,
|
||||
gacha_id: int,
|
||||
gacha_name: int,
|
||||
**gacha_data,
|
||||
) -> Optional[int]:
|
||||
sql = insert(gachas).values(
|
||||
version=version,
|
||||
gachaId=gacha_id,
|
||||
gachaName=gacha_name,
|
||||
**gacha_data,
|
||||
)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(
|
||||
version=version,
|
||||
gachaId=gacha_id,
|
||||
gachaName=gacha_name,
|
||||
**gacha_data,
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warn(f"Failed to insert gacha! gacha_id {gacha_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_gachas(self, version: int) -> Optional[List[Dict]]:
|
||||
sql = gachas.select(gachas.c.version <= version).order_by(
|
||||
gachas.c.gachaId.asc()
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_gacha(self, version: int, gacha_id: int) -> Optional[Dict]:
|
||||
sql = gachas.select(
|
||||
and_(gachas.c.version <= version, gachas.c.gachaId == gacha_id)
|
||||
)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_gacha_card(
|
||||
self, gacha_id: int, card_id: int, **gacha_card
|
||||
) -> Optional[int]:
|
||||
sql = insert(gacha_cards).values(gachaId=gacha_id, cardId=card_id, **gacha_card)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(
|
||||
gachaId=gacha_id, cardId=card_id, **gacha_card
|
||||
)
|
||||
|
||||
result = self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warn(f"Failed to insert gacha card! gacha_id {gacha_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_gacha_cards(self, gacha_id: int) -> Optional[List[Dict]]:
|
||||
sql = gacha_cards.select(gacha_cards.c.gachaId == gacha_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchall()
|
||||
|
||||
def get_gacha_card_by_character(self, gacha_id: int, chara_id: int) -> Optional[Dict]:
|
||||
sql_sub = (
|
||||
select(cards.c.cardId)
|
||||
.filter(
|
||||
cards.c.charaId == chara_id
|
||||
)
|
||||
.scalar_subquery()
|
||||
)
|
||||
|
||||
# Perform the main query, also rename the resulting column to ranking
|
||||
sql = gacha_cards.select(and_(
|
||||
gacha_cards.c.gachaId == gacha_id,
|
||||
gacha_cards.c.cardId == sql_sub
|
||||
))
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def put_card(self, version: int, card_id: int, **card_data) -> Optional[int]:
|
||||
sql = insert(cards).values(version=version, cardId=card_id, **card_data)
|
||||
|
||||
conflict = sql.on_duplicate_key_update(**card_data)
|
||||
|
||||
result = self.execute(conflict)
|
||||
if result is None:
|
||||
self.logger.warn(f"Failed to insert card! card_id {card_id}")
|
||||
return None
|
||||
return result.lastrowid
|
||||
|
||||
def get_card(self, version: int, card_id: int) -> Optional[Dict]:
|
||||
sql = cards.select(and_(cards.c.version <= version, cards.c.cardId == card_id))
|
||||
|
||||
result = self.execute(sql)
|
||||
if result is None:
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
Reference in New Issue
Block a user