Merge remote-tracking branch 'origin/develop' into fork_develop

This commit is contained in:
Dniel97 2023-07-16 19:07:56 +02:00
commit 859bf4bf5d
Signed by untrusted user: Dniel97
GPG Key ID: 6180B3C768FB2E08
24 changed files with 113 additions and 239 deletions

View File

@ -0,0 +1,2 @@
ALTER TABLE ongeki_static_events
DROP COLUMN startDate;

View File

@ -0,0 +1,2 @@
ALTER TABLE ongeki_static_events
ADD COLUMN startDate TIMESTAMP NOT NULL DEFAULT current_timestamp();

View File

@ -51,7 +51,7 @@ ALTER TABLE mai2_item_favorite MODIFY COLUMN itemKind int(11) NOT NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN seasonId int(11) NOT NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN point int(11) NOT NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN rank int(11) NOT NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN `rank` int(11) NOT NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN rewardGet tinyint(1) NOT NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN userName varchar(8) NOT NULL;

View File

@ -35,7 +35,7 @@ ALTER TABLE mai2_item_favorite MODIFY COLUMN itemKind int(11) NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN seasonId int(11) NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN point int(11) NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN rank int(11) NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN `rank` int(11) NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN rewardGet tinyint(1) NULL;
ALTER TABLE mai2_item_friend_season_ranking MODIFY COLUMN userName varchar(8) NULL;

View File

@ -230,12 +230,12 @@ python dbutils.py --game SBZV upgrade
|------------|----------------------------|
| 0 | O.N.G.E.K.I. |
| 1 | O.N.G.E.K.I. + |
| 2 | O.N.G.E.K.I. Summer |
| 3 | O.N.G.E.K.I. Summer + |
| 4 | O.N.G.E.K.I. Red |
| 5 | O.N.G.E.K.I. Red + |
| 6 | O.N.G.E.K.I. Bright |
| 7 | O.N.G.E.K.I. Bright Memory |
| 2 | O.N.G.E.K.I. SUMMER |
| 3 | O.N.G.E.K.I. SUMMER + |
| 4 | O.N.G.E.K.I. R.E.D. |
| 5 | O.N.G.E.K.I. R.E.D. + |
| 6 | O.N.G.E.K.I. bright |
| 7 | O.N.G.E.K.I. bright MEMORY |
### Importer
@ -285,12 +285,12 @@ python dbutils.py --game SDDT upgrade
* Card Maker 1.30:
* CHUNITHM NEW!!: Yes
* maimai DX UNiVERSE: Yes
* O.N.G.E.K.I. Bright: Yes
* O.N.G.E.K.I. bright: Yes
* Card Maker 1.35:
* CHUNITHM SUN: Yes (NEW PLUS!! up to A032)
* maimai DX FESTiVAL: Yes (up to A035) (UNiVERSE PLUS up to A031)
* O.N.G.E.K.I. Bright Memory: Yes
* O.N.G.E.K.I. bright MEMORY: Yes
### Importer
@ -347,6 +347,14 @@ version:
ongeki: 1.35.03
```
For now you also need to update your `config/ongeki.yaml` with the correct version number, for example:
```yaml
version:
7: # O.N.G.E.K.I. bright MEMORY
card_maker: 1.35.03
```
### O.N.G.E.K.I.
Gacha "無料ガチャ" can only pull from the free cards with the following probabilities: 94%: R, 5% SR and 1% chance of

View File

@ -29,3 +29,9 @@ gachas:
- 1156
- 1163
- 1164
version:
6:
card_maker: 1.30.01
7:
card_maker: 1.35.03

View File

@ -21,7 +21,7 @@ Games listed below have been tested and confirmed working. Only game versions ol
+ 1.35
+ O.N.G.E.K.I.
+ All versions up to Bright Memory
+ All versions up to bright MEMORY
+ WACCA
+ Lily R

View File

@ -129,6 +129,6 @@ class CardMakerServlet:
if resp is None:
resp = {"returnCode": 1}
self.logger.info(f"Response {resp}")
self.logger.debug(f"Response {resp}")
return zlib.compress(json.dumps(resp, ensure_ascii=False).encode("utf-8"))

View File

@ -89,8 +89,7 @@ class CardMakerReader(BaseReader):
version_ids = {
"v2_00": ChuniConstants.VER_CHUNITHM_NEW,
"v2_05": ChuniConstants.VER_CHUNITHM_NEW_PLUS,
# Chunithm SUN, ignore for now
"v2_10": ChuniConstants.VER_CHUNITHM_NEW_PLUS + 1,
"v2_10": ChuniConstants.VER_CHUNITHM_SUN,
}
for root, dirs, files in os.walk(base_dir):
@ -138,8 +137,7 @@ class CardMakerReader(BaseReader):
version_ids = {
"v2_00": ChuniConstants.VER_CHUNITHM_NEW,
"v2_05": ChuniConstants.VER_CHUNITHM_NEW_PLUS,
# Chunithm SUN, ignore for now
"v2_10": ChuniConstants.VER_CHUNITHM_NEW_PLUS + 1,
"v2_10": ChuniConstants.VER_CHUNITHM_SUN,
}
for root, dirs, files in os.walk(base_dir):
@ -226,6 +224,12 @@ 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
)
self.mai2_data.static.put_card(
version, card_id, name, enabled=enabled
)

View File

@ -568,176 +568,3 @@ class Mai2DX(Mai2Base):
"nextIndex": next_index,
"userMusicList": [{"userMusicDetailList": music_detail_list}],
}
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
p = self.data.profile.get_profile_detail(data["userId"], self.version)
if p is None:
return {}
return {
"userName": p["userName"],
"rating": p["playerRating"],
# hardcode lastDataVersion for CardMaker 1.34
"lastDataVersion": "1.20.00",
"isLogin": False,
"isExistSellingCard": False,
}
def handle_cm_get_user_data_api_request(self, data: Dict) -> Dict:
# user already exists, because the preview checks that already
p = self.data.profile.get_profile_detail(data["userId"], self.version)
cards = self.data.card.get_user_cards(data["userId"])
if cards is None or len(cards) == 0:
# This should never happen
self.logger.error(
f"handle_get_user_data_api_request: Internal error - No cards found for user id {data['userId']}"
)
return {}
# get the dict representation of the row so we can modify values
user_data = p._asdict()
# remove the values the game doesn't want
user_data.pop("id")
user_data.pop("user")
user_data.pop("version")
return {"userId": data["userId"], "userData": user_data}
def handle_cm_login_api_request(self, data: Dict) -> Dict:
return {"returnCode": 1}
def handle_cm_logout_api_request(self, data: Dict) -> Dict:
return {"returnCode": 1}
def handle_cm_get_selling_card_api_request(self, data: Dict) -> Dict:
selling_cards = self.data.static.get_enabled_cards(self.version)
if selling_cards is None:
return {"length": 0, "sellingCardList": []}
selling_card_list = []
for card in selling_cards:
tmp = card._asdict()
tmp.pop("id")
tmp.pop("version")
tmp.pop("cardName")
tmp.pop("enabled")
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"
)
selling_card_list.append(tmp)
return {"length": len(selling_card_list), "sellingCardList": selling_card_list}
def handle_cm_get_user_card_api_request(self, data: Dict) -> Dict:
user_cards = self.data.item.get_cards(data["userId"])
if user_cards is None:
return {"returnCode": 1, "length": 0, "nextIndex": 0, "userCardList": []}
max_ct = data["maxCount"]
next_idx = data["nextIndex"]
start_idx = next_idx
end_idx = max_ct + start_idx
if len(user_cards[start_idx:]) > max_ct:
next_idx += max_ct
else:
next_idx = 0
card_list = []
for card in user_cards:
tmp = card._asdict()
tmp.pop("id")
tmp.pop("user")
tmp["startDate"] = datetime.strftime(tmp["startDate"], "%Y-%m-%d %H:%M:%S")
tmp["endDate"] = datetime.strftime(tmp["endDate"], "%Y-%m-%d %H:%M:%S")
card_list.append(tmp)
return {
"returnCode": 1,
"length": len(card_list[start_idx:end_idx]),
"nextIndex": next_idx,
"userCardList": card_list[start_idx:end_idx],
}
def handle_cm_get_user_item_api_request(self, data: Dict) -> Dict:
super().handle_get_user_item_api_request(data)
def handle_cm_get_user_character_api_request(self, data: Dict) -> Dict:
characters = self.data.item.get_characters(data["userId"])
chara_list = []
for chara in characters:
chara_list.append(
{
"characterId": chara["characterId"],
# no clue why those values are even needed
"point": 0,
"count": 0,
"level": chara["level"],
"nextAwake": 0,
"nextAwakePercent": 0,
"favorite": False,
"awakening": chara["awakening"],
"useCount": chara["useCount"],
}
)
return {
"returnCode": 1,
"length": len(chara_list),
"userCharacterList": chara_list,
}
def handle_cm_get_user_card_print_error_api_request(self, data: Dict) -> Dict:
return {"length": 0, "userPrintDetailList": []}
def handle_cm_upsert_user_print_api_request(self, data: Dict) -> Dict:
user_id = data["userId"]
upsert = data["userPrintDetail"]
# set a random card serial number
serial_id = "".join([str(randint(0, 9)) for _ in range(20)])
user_card = upsert["userCard"]
self.data.item.put_card(
user_id,
user_card["cardId"],
user_card["cardTypeId"],
user_card["charaId"],
user_card["mapId"],
)
# properly format userPrintDetail for the database
upsert.pop("userCard")
upsert.pop("serialId")
upsert["printDate"] = datetime.strptime(upsert["printDate"], "%Y-%m-%d")
self.data.item.put_user_print_detail(user_id, serial_id, upsert)
return {
"returnCode": 1,
"orderId": 0,
"serialId": serial_id,
"startDate": "2018-01-01 00:00:00",
"endDate": "2038-01-01 00:00:00",
}
def handle_cm_upsert_user_printlog_api_request(self, data: Dict) -> Dict:
return {
"returnCode": 1,
"orderId": 0,
"serialId": data["userPrintlog"]["serialId"],
}
def handle_cm_upsert_buy_card_api_request(self, data: Dict) -> Dict:
return {"returnCode": 1}

View File

@ -1,12 +1,12 @@
from typing import Dict
from core.config import CoreConfig
from titles.mai2.dx import Mai2DX
from titles.mai2.universeplus import Mai2UniversePlus
from titles.mai2.const import Mai2Constants
from titles.mai2.config import Mai2Config
class Mai2Festival(Mai2DX):
class Mai2Festival(Mai2UniversePlus):
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
super().__init__(cfg, game_cfg)
self.version = Mai2Constants.VER_MAIMAI_DX_FESTIVAL
@ -14,7 +14,7 @@ class Mai2Festival(Mai2DX):
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.36
# hardcode lastDataVersion for CardMaker 1.35
user_data["lastDataVersion"] = "1.30.00"
return user_data

View File

@ -4,12 +4,12 @@ import pytz
import json
from core.config import CoreConfig
from titles.mai2.dx import Mai2DX
from titles.mai2.dxplus import Mai2DXPlus
from titles.mai2.config import Mai2Config
from titles.mai2.const import Mai2Constants
class Mai2Splash(Mai2DX):
class Mai2Splash(Mai2DXPlus):
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
super().__init__(cfg, game_cfg)
self.version = Mai2Constants.VER_MAIMAI_DX_SPLASH

View File

@ -4,12 +4,12 @@ import pytz
import json
from core.config import CoreConfig
from titles.mai2.dx import Mai2DX
from titles.mai2.splash import Mai2Splash
from titles.mai2.config import Mai2Config
from titles.mai2.const import Mai2Constants
class Mai2SplashPlus(Mai2DX):
class Mai2SplashPlus(Mai2Splash):
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
super().__init__(cfg, game_cfg)
self.version = Mai2Constants.VER_MAIMAI_DX_SPLASH_PLUS

View File

@ -5,12 +5,12 @@ import pytz
import json
from core.config import CoreConfig
from titles.mai2.dx import Mai2DX
from titles.mai2.splashplus import Mai2SplashPlus
from titles.mai2.const import Mai2Constants
from titles.mai2.config import Mai2Config
class Mai2Universe(Mai2DX):
class Mai2Universe(Mai2SplashPlus):
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
super().__init__(cfg, game_cfg)
self.version = Mai2Constants.VER_MAIMAI_DX_UNIVERSE
@ -70,13 +70,13 @@ class Mai2Universe(Mai2DX):
tmp.pop("cardName")
tmp.pop("enabled")
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["startDate"] = datetime.strftime(tmp["startDate"], Mai2Constants.DATE_TIME_FORMAT)
tmp["endDate"] = datetime.strftime(tmp["endDate"], Mai2Constants.DATE_TIME_FORMAT)
tmp["noticeStartDate"] = datetime.strftime(
tmp["noticeStartDate"], "%Y-%m-%d %H:%M:%S"
tmp["noticeStartDate"], Mai2Constants.DATE_TIME_FORMAT
)
tmp["noticeEndDate"] = datetime.strftime(
tmp["noticeEndDate"], "%Y-%m-%d %H:%M:%S"
tmp["noticeEndDate"], Mai2Constants.DATE_TIME_FORMAT
)
selling_card_list.append(tmp)

View File

@ -1,12 +1,12 @@
from typing import Dict
from core.config import CoreConfig
from titles.mai2.dx import Mai2DX
from titles.mai2.universe import Mai2Universe
from titles.mai2.const import Mai2Constants
from titles.mai2.config import Mai2Config
class Mai2UniversePlus(Mai2DX):
class Mai2UniversePlus(Mai2Universe):
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
super().__init__(cfg, game_cfg)
self.version = Mai2Constants.VER_MAIMAI_DX_UNIVERSE_PLUS

View File

@ -7,4 +7,4 @@ index = OngekiServlet
database = OngekiData
reader = OngekiReader
game_codes = [OngekiConstants.GAME_CODE]
current_schema_version = 4
current_schema_version = 5

View File

@ -142,7 +142,7 @@ class OngekiBase:
def handle_get_game_point_api_request(self, data: Dict) -> Dict:
"""
Sets the GP ammount for A and B sets for 1 - 3 crdits
Sets the GP amount for A and B sets for 1 - 3 credits
"""
return {
"length": 6,
@ -155,13 +155,13 @@ class OngekiBase:
},
{
"type": 1,
"cost": 200,
"cost": 230,
"startDate": "2000-01-01 05:00:00.0",
"endDate": "2099-01-01 05:00:00.0",
},
{
"type": 2,
"cost": 300,
"cost": 370,
"startDate": "2000-01-01 05:00:00.0",
"endDate": "2099-01-01 05:00:00.0",
},
@ -256,7 +256,11 @@ class OngekiBase:
{
"type": event["type"],
"id": event["eventId"],
"startDate": "2017-12-05 07:00:00.0",
# actually use the startDate from the import so it
# properly shows all the events when new ones are imported
"startDate": datetime.strftime(
event["startDate"], "%Y-%m-%d %H:%M:%S.0"
),
"endDate": "2099-12-31 00:00:00.0",
}
)
@ -560,7 +564,11 @@ class OngekiBase:
def handle_get_user_recent_rating_api_request(self, data: Dict) -> Dict:
recent_rating = self.data.profile.get_profile_recent_rating(data["userId"])
if recent_rating is None:
return {}
return {
"userId": data["userId"],
"length": 0,
"userRecentRatingList": [],
}
userRecentRatingList = recent_rating["recentRating"]

View File

@ -43,15 +43,15 @@ class OngekiBright(OngekiBase):
user_data.pop("user")
user_data.pop("version")
# TODO: replace datetime objects with strings
# add access code that we don't store
user_data["accessCode"] = cards[0]["access_code"]
# hardcode Card Maker version for now
# Card Maker 1.34.00 = 1.30.01
# Card Maker 1.36.00 = 1.35.04
user_data["compatibleCmVersion"] = "1.30.01"
# add the compatible card maker version from config
card_maker_ver = self.game_cfg.version.version(self.version)
if card_maker_ver and card_maker_ver.get("card_maker"):
# Card Maker 1.30 = 1.30.01+
# Card Maker 1.35 = 1.35.03+
user_data["compatibleCmVersion"] = card_maker_ver.get("card_maker")
return {"userId": data["userId"], "userData": user_data}
@ -333,6 +333,8 @@ class OngekiBright(OngekiBase):
select_point = data["selectPoint"]
total_gacha_count, ceiling_gacha_count = 0, 0
# 0 = can still use Gacha Select, 1 = already used Gacha Select
use_select_point = 0
daily_gacha_cnt, five_gacha_cnt, eleven_gacha_cnt = 0, 0, 0
daily_gacha_date = datetime.strptime("2000-01-01", "%Y-%m-%d")
@ -344,6 +346,9 @@ class OngekiBright(OngekiBase):
daily_gacha_cnt = user_gacha["dailyGachaCnt"]
five_gacha_cnt = user_gacha["fiveGachaCnt"]
eleven_gacha_cnt = user_gacha["elevenGachaCnt"]
# if the Gacha Select has been used, make sure to keep it
if user_gacha["useSelectPoint"] == 1:
use_select_point = 1
# parse just the year, month and date
daily_gacha_date = user_gacha["dailyGachaDate"]
@ -359,7 +364,7 @@ class OngekiBright(OngekiBase):
totalGachaCnt=total_gacha_count + gacha_count,
ceilingGachaCnt=ceiling_gacha_count + gacha_count,
selectPoint=select_point,
useSelectPoint=0,
useSelectPoint=use_select_point,
dailyGachaCnt=daily_gacha_cnt + gacha_count,
fiveGachaCnt=five_gacha_cnt + 1 if gacha_count == 5 else five_gacha_cnt,
elevenGachaCnt=eleven_gacha_cnt + 1

View File

@ -136,14 +136,3 @@ class OngekiBrightMemory(OngekiBright):
def handle_get_game_music_release_state_api_request(self, data: Dict) -> Dict:
return {"techScore": 0, "cardNum": 0}
def handle_cm_get_user_data_api_request(self, data: Dict) -> Dict:
# check for a bright memory profile
user_data = super().handle_cm_get_user_data_api_request(data)
# hardcode Card Maker version for now
# Card Maker 1.34 = 1.30.01
# Card Maker 1.35 = 1.35.03
user_data["userData"]["compatibleCmVersion"] = "1.35.03"
return user_data

View File

@ -1,3 +1,4 @@
from ast import Dict
from typing import List
from core.config import CoreConfig
@ -33,7 +34,23 @@ class OngekiGachaConfig:
)
class OngekiCardMakerVersionConfig:
def __init__(self, parent_config: "OngekiConfig") -> None:
self.__config = parent_config
def version(self, version: int) -> Dict:
"""
in the form of:
<ongeki version>: {"card_maker": <compatible card maker version>}
6: {"card_maker": 1.30.01}
"""
return CoreConfig.get_config_field(
self.__config, "ongeki", "version", default={}
).get(version)
class OngekiConfig(dict):
def __init__(self) -> None:
self.server = OngekiServerConfig(self)
self.gachas = OngekiGachaConfig(self)
self.version = OngekiCardMakerVersionConfig(self)

View File

@ -66,13 +66,13 @@ class OngekiConstants:
VERSION_NAMES = (
"ONGEKI",
"ONGEKI+",
"ONGEKI Summer",
"ONGEKI Summer+",
"ONGEKI Red",
"ONGEKI Red+",
"ONGEKI Bright",
"ONGEKI Bright Memory",
"ONGEKI +",
"ONGEKI SUMMER",
"ONGEKI SUMMER +",
"ONGEKI R.E.D.",
"ONGEKI R.E.D. +",
"ONGEKI bright",
"ONGEKI bright MEMORY",
)
@classmethod

View File

@ -11,6 +11,7 @@ from os import path
from typing import Tuple
from core.config import CoreConfig
from core.utils import Utils
from titles.ongeki.config import OngekiConfig
from titles.ongeki.const import OngekiConstants
from titles.ongeki.base import OngekiBase
@ -101,6 +102,7 @@ class OngekiServlet:
url_split = url_path.split("/")
internal_ver = 0
endpoint = url_split[len(url_split) - 1]
client_ip = Utils.get_ip_addr(request)
if version < 105: # 1.0
internal_ver = OngekiConstants.VER_ONGEKI
@ -137,7 +139,10 @@ class OngekiServlet:
req_data = json.loads(unzip)
self.logger.info(f"v{version} {endpoint} request - {req_data}")
self.logger.info(
f"v{version} {endpoint} request from {client_ip}"
)
self.logger.debug(req_data)
func_to_find = "handle_" + inflection.underscore(endpoint) + "_request"
@ -156,6 +161,6 @@ class OngekiServlet:
if resp == None:
resp = {"returnCode": 1}
self.logger.info(f"Response {resp}")
self.logger.debug(f"Response {resp}")
return zlib.compress(json.dumps(resp, ensure_ascii=False).encode("utf-8"))

View File

@ -316,7 +316,7 @@ class OngekiProfileData(BaseData):
return result.fetchone()
def get_profile_rating_log(self, aime_id: int) -> Optional[List[Row]]:
sql = select(rating_log).where(recent_rating.c.user == aime_id)
sql = select(rating_log).where(rating_log.c.user == aime_id)
result = self.execute(sql)
if result is None:

View File

@ -16,6 +16,7 @@ events = Table(
Column("eventId", Integer),
Column("type", Integer),
Column("name", String(255)),
Column("startDate", TIMESTAMP, server_default=func.now()),
Column("enabled", Boolean, server_default="1"),
UniqueConstraint("version", "eventId", "type", name="ongeki_static_events_uk"),
mysql_charset="utf8mb4",