Merge branch 'develop' into fork_develop
This commit is contained in:
commit
0ab539173a
21
Dockerfile
Normal file
21
Dockerfile
Normal file
@ -0,0 +1,21 @@
|
||||
FROM python:3.9.15-slim-bullseye
|
||||
|
||||
RUN apt update && apt install default-libmysqlclient-dev build-essential libtk nodejs npm -y
|
||||
|
||||
WORKDIR /app
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip3 install -r requirements.txt
|
||||
RUN npm i -g nodemon
|
||||
|
||||
COPY entrypoint.sh entrypoint.sh
|
||||
RUN chmod +x entrypoint.sh
|
||||
|
||||
COPY index.py index.py
|
||||
COPY dbutils.py dbutils.py
|
||||
ADD core core
|
||||
ADD titles titles
|
||||
ADD config config
|
||||
ADD log log
|
||||
ADD cert cert
|
||||
|
||||
ENTRYPOINT [ "/app/entrypoint.sh" ]
|
@ -249,14 +249,18 @@ class AllnetServlet:
|
||||
signer = PKCS1_v1_5.new(rsa)
|
||||
digest = SHA.new()
|
||||
|
||||
kc_playlimit = int(req_dict[0]["playlimit"])
|
||||
kc_nearfull = int(req_dict[0]["nearfull"])
|
||||
kc_billigtype = int(req_dict[0]["billingtype"])
|
||||
kc_playcount = int(req_dict[0]["playcnt"])
|
||||
kc_serial: str = req_dict[0]["keychipid"]
|
||||
kc_game: str = req_dict[0]["gameid"]
|
||||
kc_date = strptime(req_dict[0]["date"], "%Y%m%d%H%M%S")
|
||||
kc_serial_bytes = kc_serial.encode()
|
||||
try:
|
||||
kc_playlimit = int(req_dict[0]["playlimit"])
|
||||
kc_nearfull = int(req_dict[0]["nearfull"])
|
||||
kc_billigtype = int(req_dict[0]["billingtype"])
|
||||
kc_playcount = int(req_dict[0]["playcnt"])
|
||||
kc_serial: str = req_dict[0]["keychipid"]
|
||||
kc_game: str = req_dict[0]["gameid"]
|
||||
kc_date = strptime(req_dict[0]["date"], "%Y%m%d%H%M%S")
|
||||
kc_serial_bytes = kc_serial.encode()
|
||||
|
||||
except KeyError as e:
|
||||
return f"result=5&linelimit=&message={e} field is missing".encode()
|
||||
|
||||
machine = self.data.arcade.get_machine(kc_serial)
|
||||
if machine is None and not self.config.server.allow_unregistered_serials:
|
||||
|
9
core/data/schema/versions/SBZV_4_rollback.sql
Normal file
9
core/data/schema/versions/SBZV_4_rollback.sql
Normal file
@ -0,0 +1,9 @@
|
||||
ALTER TABLE diva_profile
|
||||
DROP cnp_cid,
|
||||
DROP cnp_val,
|
||||
DROP cnp_rr,
|
||||
DROP cnp_sp,
|
||||
DROP btn_se_eqp,
|
||||
DROP sld_se_eqp,
|
||||
DROP chn_sld_se_eqp,
|
||||
DROP sldr_tch_se_eqp;
|
9
core/data/schema/versions/SBZV_5_upgrade.sql
Normal file
9
core/data/schema/versions/SBZV_5_upgrade.sql
Normal file
@ -0,0 +1,9 @@
|
||||
ALTER TABLE diva_profile
|
||||
ADD cnp_cid INT NOT NULL DEFAULT -1,
|
||||
ADD cnp_val INT NOT NULL DEFAULT -1,
|
||||
ADD cnp_rr INT NOT NULL DEFAULT -1,
|
||||
ADD cnp_sp VARCHAR(255) NOT NULL DEFAULT "",
|
||||
ADD btn_se_eqp INT NOT NULL DEFAULT -1,
|
||||
ADD sld_se_eqp INT NOT NULL DEFAULT -1,
|
||||
ADD chn_sld_se_eqp INT NOT NULL DEFAULT -1,
|
||||
ADD sldr_tch_se_eqp INT NOT NULL DEFAULT -1;
|
57
docker-compose.yml
Normal file
57
docker-compose.yml
Normal file
@ -0,0 +1,57 @@
|
||||
version: "3.9"
|
||||
services:
|
||||
app:
|
||||
hostname: ma.app
|
||||
build: .
|
||||
volumes:
|
||||
- ./aime:/app/aime
|
||||
|
||||
environment:
|
||||
CFG_DEV: 1
|
||||
CFG_CORE_SERVER_HOSTNAME: 0.0.0.0
|
||||
CFG_CORE_DATABASE_HOST: ma.db
|
||||
CFG_CORE_MEMCACHED_HOSTNAME: ma.memcached
|
||||
CFG_CORE_AIMEDB_KEY: keyhere
|
||||
CFG_CHUNI_SERVER_LOGLEVEL: debug
|
||||
|
||||
ports:
|
||||
- "80:80"
|
||||
- "8443:8443"
|
||||
- "22345:22345"
|
||||
|
||||
- "8080:8080"
|
||||
- "8090:8090"
|
||||
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
||||
db:
|
||||
hostname: ma.db
|
||||
image: mysql:8.0.31-debian
|
||||
environment:
|
||||
MYSQL_DATABASE: aime
|
||||
MYSQL_USER: aime
|
||||
MYSQL_PASSWORD: aime
|
||||
MYSQL_ROOT_PASSWORD: AimeRootPassword
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
|
||||
memcached:
|
||||
hostname: ma.memcached
|
||||
image: memcached:1.6.17-bullseye
|
||||
|
||||
phpmyadmin:
|
||||
hostname: ma.phpmyadmin
|
||||
image: phpmyadmin:latest
|
||||
environment:
|
||||
PMA_HOSTS: ma.db
|
||||
PMA_USER: root
|
||||
PMA_PASSWORD: AimeRootPassword
|
||||
APACHE_PORT: 8080
|
||||
ports:
|
||||
- "8080:8080"
|
||||
|
11
entrypoint.sh
Normal file
11
entrypoint.sh
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ -z "${CFG_DEV}" ]]; then
|
||||
echo Production mode
|
||||
python3 index.py
|
||||
else
|
||||
echo Development mode
|
||||
python3 dbutils.py create
|
||||
nodemon -w aime --legacy-watch index.py
|
||||
fi
|
||||
|
2
index.py
2
index.py
@ -42,7 +42,7 @@ class HttpDispatcher(resource.Resource):
|
||||
conditions=dict(method=["POST"]),
|
||||
)
|
||||
|
||||
self.map_post.connect(
|
||||
self.map_get.connect(
|
||||
"allnet_ping",
|
||||
"/naomitest.html",
|
||||
controller="allnet",
|
||||
|
@ -7,4 +7,4 @@ index = DivaServlet
|
||||
database = DivaData
|
||||
reader = DivaReader
|
||||
game_codes = [DivaConstants.GAME_CODE]
|
||||
current_schema_version = 4
|
||||
current_schema_version = 5
|
||||
|
@ -266,16 +266,17 @@ class DivaBase:
|
||||
def handle_festa_info_request(self, data: Dict) -> Dict:
|
||||
encoded = "&"
|
||||
params = {
|
||||
"fi_id": "1,-1",
|
||||
"fi_name": f"{self.core_cfg.server.name} Opening,xxx",
|
||||
"fi_kind": "0,0",
|
||||
"fi_id": "1,2",
|
||||
"fi_name": f"{self.core_cfg.server.name} Opening,Project DIVA Festa",
|
||||
# 0=PINK, 1=GREEN
|
||||
"fi_kind": "1,0",
|
||||
"fi_difficulty": "-1,-1",
|
||||
"fi_pv_id_lst": "ALL,ALL",
|
||||
"fi_attr": "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"fi_add_vp": "20,0",
|
||||
"fi_mul_vp": "1,1",
|
||||
"fi_st": "2022-06-17 17:00:00.0,2014-07-08 18:10:11.0",
|
||||
"fi_et": "2029-01-01 10:00:00.0,2014-07-08 18:10:11.0",
|
||||
"fi_add_vp": "20,5",
|
||||
"fi_mul_vp": "1,2",
|
||||
"fi_st": "2019-01-01 00:00:00.0,2019-01-01 00:00:00.0",
|
||||
"fi_et": "2029-01-01 00:00:00.0,2029-01-01 00:00:00.0",
|
||||
"fi_lut": "{self.time_lut}",
|
||||
}
|
||||
|
||||
@ -401,10 +402,10 @@ class DivaBase:
|
||||
response += f"&lv_pnt={profile['lv_pnt']}"
|
||||
response += f"&vcld_pts={profile['vcld_pts']}"
|
||||
response += f"&skn_eqp={profile['use_pv_skn_eqp']}"
|
||||
response += f"&btn_se_eqp={profile['use_pv_btn_se_eqp']}"
|
||||
response += f"&sld_se_eqp={profile['use_pv_sld_se_eqp']}"
|
||||
response += f"&chn_sld_se_eqp={profile['use_pv_chn_sld_se_eqp']}"
|
||||
response += f"&sldr_tch_se_eqp={profile['use_pv_sldr_tch_se_eqp']}"
|
||||
response += f"&btn_se_eqp={profile['btn_se_eqp']}"
|
||||
response += f"&sld_se_eqp={profile['sld_se_eqp']}"
|
||||
response += f"&chn_sld_se_eqp={profile['chn_sld_se_eqp']}"
|
||||
response += f"&sldr_tch_se_eqp={profile['sldr_tch_se_eqp']}"
|
||||
response += f"&passwd_stat={profile['passwd_stat']}"
|
||||
|
||||
# Store stuff to add to rework
|
||||
@ -478,6 +479,21 @@ class DivaBase:
|
||||
response += f"&dsp_clr_sts={profile['dsp_clr_sts']}"
|
||||
response += f"&rgo_sts={profile['rgo_sts']}"
|
||||
|
||||
# Contest progress
|
||||
response += f"&cv_cid=-1,-1,-1,-1"
|
||||
response += f"&cv_sc=-1,-1,-1,-1"
|
||||
response += f"&cv_bv=-1,-1,-1,-1"
|
||||
response += f"&cv_bv=-1,-1,-1,-1"
|
||||
response += f"&cv_bf=-1,-1,-1,-1"
|
||||
|
||||
# Contest now playing id, return -1 if no current playing contest
|
||||
response += f"&cnp_cid={profile['cnp_cid']}"
|
||||
response += f"&cnp_val={profile['cnp_val']}"
|
||||
# border can be 0=bronzem 1=silver, 2=gold
|
||||
response += f"&cnp_rr={profile['cnp_rr']}"
|
||||
# only show contest specifier if it is not empty
|
||||
response += f"&cnp_sp={profile['cnp_sp']}" if profile["cnp_sp"] != "" else ""
|
||||
|
||||
# To be fully fixed
|
||||
if "my_qst_id" not in profile:
|
||||
response += f"&my_qst_id=-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
|
||||
@ -488,7 +504,63 @@ class DivaBase:
|
||||
|
||||
response += f"&my_qst_prgrs=0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"
|
||||
response += f"&my_qst_et=2022-06-19%2010%3A28%3A52.0,2022-06-19%2010%3A28%3A52.0,2022-06-19%2010%3A28%3A52.0,2100-01-01%2008%3A59%3A59.0,2100-01-01%2008%3A59%3A59.0,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx,xxx"
|
||||
response += f"&clr_sts=0,0,0,0,0,0,0,0,56,52,35,6,6,3,1,0,0,0,0,0"
|
||||
|
||||
# define a helper class to store all counts for clear, great,
|
||||
# excellent and perfect
|
||||
class ClearSet:
|
||||
def __init__(self):
|
||||
self.clear = 0
|
||||
self.great = 0
|
||||
self.excellent = 0
|
||||
self.perfect = 0
|
||||
|
||||
# create a dict to store the ClearSets per difficulty
|
||||
clear_set_dict = {
|
||||
0: ClearSet(), # easy
|
||||
1: ClearSet(), # normal
|
||||
2: ClearSet(), # hard
|
||||
3: ClearSet(), # extreme
|
||||
4: ClearSet(), # exExtreme
|
||||
}
|
||||
|
||||
# get clear status from user scores
|
||||
pv_records = self.data.score.get_best_scores(data["pd_id"])
|
||||
clear_status = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||
|
||||
if pv_records is not None:
|
||||
for score in pv_records:
|
||||
if score["edition"] == 0:
|
||||
# cheap and standard both count to "clear"
|
||||
if score["clr_kind"] in {1, 2}:
|
||||
clear_set_dict[score["difficulty"]].clear += 1
|
||||
elif score["clr_kind"] == 3:
|
||||
clear_set_dict[score["difficulty"]].great += 1
|
||||
elif score["clr_kind"] == 4:
|
||||
clear_set_dict[score["difficulty"]].excellent += 1
|
||||
elif score["clr_kind"] == 5:
|
||||
clear_set_dict[score["difficulty"]].perfect += 1
|
||||
else:
|
||||
# 4=ExExtreme
|
||||
if score["clr_kind"] in {1, 2}:
|
||||
clear_set_dict[4].clear += 1
|
||||
elif score["clr_kind"] == 3:
|
||||
clear_set_dict[4].great += 1
|
||||
elif score["clr_kind"] == 4:
|
||||
clear_set_dict[4].excellent += 1
|
||||
elif score["clr_kind"] == 5:
|
||||
clear_set_dict[4].perfect += 1
|
||||
|
||||
# now add all values to a list
|
||||
clear_list = []
|
||||
for clear_set in clear_set_dict.values():
|
||||
clear_list.append(clear_set.clear)
|
||||
clear_list.append(clear_set.great)
|
||||
clear_list.append(clear_set.excellent)
|
||||
clear_list.append(clear_set.perfect)
|
||||
|
||||
clear_status = ",".join(map(str, clear_list))
|
||||
|
||||
response += f"&clr_sts={clear_status}"
|
||||
|
||||
# Store stuff to add to rework
|
||||
response += f"&mdl_eqp_tm={self.time_lut}"
|
||||
|
@ -34,9 +34,17 @@ profile = Table(
|
||||
Column("use_pv_sld_se_eqp", Boolean, nullable=False, server_default="0"),
|
||||
Column("use_pv_chn_sld_se_eqp", Boolean, nullable=False, server_default="0"),
|
||||
Column("use_pv_sldr_tch_se_eqp", Boolean, nullable=False, server_default="0"),
|
||||
Column("btn_se_eqp", Integer, nullable=False, server_default="-1"),
|
||||
Column("sld_se_eqp", Integer, nullable=False, server_default="-1"),
|
||||
Column("chn_sld_se_eqp", Integer, nullable=False, server_default="-1"),
|
||||
Column("sldr_tch_se_eqp", Integer, nullable=False, server_default="-1"),
|
||||
Column("nxt_pv_id", Integer, nullable=False, server_default="708"),
|
||||
Column("nxt_dffclty", Integer, nullable=False, server_default="2"),
|
||||
Column("nxt_edtn", Integer, nullable=False, server_default="0"),
|
||||
Column("cnp_cid", Integer, nullable=False, server_default="-1"),
|
||||
Column("cnp_val", Integer, nullable=False, server_default="-1"),
|
||||
Column("cnp_rr", Integer, nullable=False, server_default="-1"),
|
||||
Column("cnp_sp", String(255), nullable=False, server_default=""),
|
||||
Column("dsp_clr_brdr", Integer, nullable=False, server_default="7"),
|
||||
Column("dsp_intrm_rnk", Integer, nullable=False, server_default="1"),
|
||||
Column("dsp_clr_sts", Integer, nullable=False, server_default="1"),
|
||||
|
@ -3,6 +3,7 @@ from sqlalchemy.types import Integer, String, TIMESTAMP, JSON, Boolean
|
||||
from sqlalchemy.schema import ForeignKey
|
||||
from sqlalchemy.sql import func, select
|
||||
from sqlalchemy.dialects.mysql import insert
|
||||
from sqlalchemy.engine import Row
|
||||
from typing import Optional, List, Dict, Any
|
||||
|
||||
from core.data.schema import BaseData, metadata
|
||||
@ -167,7 +168,7 @@ class DivaScoreData(BaseData):
|
||||
|
||||
def get_best_user_score(
|
||||
self, user_id: int, pv_id: int, difficulty: int, edition: int
|
||||
) -> Optional[Dict]:
|
||||
) -> Optional[Row]:
|
||||
sql = score.select(
|
||||
and_(
|
||||
score.c.user == user_id,
|
||||
@ -184,7 +185,7 @@ class DivaScoreData(BaseData):
|
||||
|
||||
def get_top3_scores(
|
||||
self, pv_id: int, difficulty: int, edition: int
|
||||
) -> Optional[List[Dict]]:
|
||||
) -> Optional[List[Row]]:
|
||||
sql = (
|
||||
score.select(
|
||||
and_(
|
||||
@ -204,7 +205,7 @@ class DivaScoreData(BaseData):
|
||||
|
||||
def get_global_ranking(
|
||||
self, user_id: int, pv_id: int, difficulty: int, edition: int
|
||||
) -> Optional[List]:
|
||||
) -> Optional[List[Row]]:
|
||||
# get the subquery max score of a user with pv_id, difficulty and
|
||||
# edition
|
||||
sql_sub = (
|
||||
@ -231,7 +232,7 @@ class DivaScoreData(BaseData):
|
||||
return None
|
||||
return result.fetchone()
|
||||
|
||||
def get_best_scores(self, user_id: int) -> Optional[List]:
|
||||
def get_best_scores(self, user_id: int) -> Optional[List[Row]]:
|
||||
sql = score.select(score.c.user == user_id)
|
||||
|
||||
result = self.execute(sql)
|
||||
|
@ -17,7 +17,14 @@ class Mai2Base:
|
||||
self.data = Mai2Data(cfg)
|
||||
self.logger = logging.getLogger("mai2")
|
||||
|
||||
if self.core_config.server.is_develop and self.core_config.title.port > 0:
|
||||
self.old_server = f"http://{self.core_config.title.hostname}:{self.core_config.title.port}/SDEY/100/"
|
||||
|
||||
else:
|
||||
self.old_server = f"http://{self.core_config.title.hostname}/SDEY/100/"
|
||||
|
||||
def handle_get_game_setting_api_request(self, data: Dict):
|
||||
# TODO: See if making this epoch 0 breaks things
|
||||
reboot_start = date.strftime(
|
||||
datetime.now() + timedelta(hours=3), Mai2Constants.DATE_TIME_FORMAT
|
||||
)
|
||||
@ -34,7 +41,7 @@ class Mai2Base:
|
||||
"movieStatus": 0,
|
||||
"movieServerUri": "",
|
||||
"deliverServerUri": "",
|
||||
"oldServerUri": "",
|
||||
"oldServerUri": self.old_server,
|
||||
"usbDlServerUri": "",
|
||||
"rebootInterval": 0,
|
||||
},
|
||||
|
@ -82,13 +82,13 @@ class Mai2Servlet:
|
||||
return (
|
||||
True,
|
||||
f"http://{core_cfg.title.hostname}:{core_cfg.title.port}/{game_code}/$v/",
|
||||
f"{core_cfg.title.hostname}:{core_cfg.title.port}/",
|
||||
f"{core_cfg.title.hostname}:{core_cfg.title.port}",
|
||||
)
|
||||
|
||||
return (
|
||||
True,
|
||||
f"http://{core_cfg.title.hostname}/{game_code}/$v/",
|
||||
f"{core_cfg.title.hostname}/",
|
||||
f"{core_cfg.title.hostname}",
|
||||
)
|
||||
|
||||
def render_POST(self, request: Request, version: int, url_path: str) -> bytes:
|
||||
|
Loading…
Reference in New Issue
Block a user