This commit is contained in:
Becod 2023-12-23 23:16:38 +08:00
commit 5b80f7a340
9 changed files with 413 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
test
MaiMaiDXNet/MaiMaiDXNet

34
ARTEMiS/Dockerfile Normal file
View File

@ -0,0 +1,34 @@
FROM alpine/git AS git
COPY ./bud.patch /bud.patch
RUN git clone --depth 1 -b develop https://gitea.tendokyu.moe/Hay1tsme/artemis /app/ \
&& cd /app/ \
&& git apply ../bud.patch \
&& mv example_config config \
&& rm -rf /app/.git
FROM python:3.9-slim-bookworm
COPY --from=git /app/requirements.txt /requirements.txt
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=cache,target=/var/cache/apt \
--mount=type=cache,target=/var/lib/apt/lists \
rm -f /etc/apt/apt.conf.d/docker-clean \
&& apt update \
&& apt --no-install-recommends -yqq install \
default-libmysqlclient-dev build-essential pkg-config \
&& mkdir -p /root/.config/pip/ \
&& echo "[global]\nbreak-system-packages = true" > /root/.config/pip/pip.conf \
&& pip install -r /requirements.txt \
&& apt autoremove -y default-libmysqlclient-dev build-essential pkg-config \
&& apt --no-install-recommends -yqq install libmariadb3 \
&& rm -rf /tmp/*
COPY --from=git /app/ /app/
WORKDIR /app
EXPOSE 80
EXPOSE 8443
EXPOSE 22345
EXPOSE 8080
EXPOSE 8090
ENTRYPOINT ["python3"]
CMD ["index.py"]

260
ARTEMiS/bud.patch Normal file
View File

@ -0,0 +1,260 @@
diff --git a/core/data/schema/versions/SDEZ_8_rollback.sql b/core/data/schema/versions/SDEZ_8_rollback.sql
new file mode 100644
index 0000000..cfc5d4c
--- /dev/null
+++ b/core/data/schema/versions/SDEZ_8_rollback.sql
@@ -0,0 +1,8 @@
+ALTER TABLE mai2_profile_detail
+ DROP COLUMN currentPlayCount,
+ DROP COLUMN renameCredit;
+
+ALTER TABLE mai2_playlog
+ DROP COLUMN extBool1;
+
+DROP TABLE IF EXISTS `mai2_playlog_2p`;
diff --git a/core/data/schema/versions/SDEZ_9_upgrade.sql b/core/data/schema/versions/SDEZ_9_upgrade.sql
new file mode 100644
index 0000000..4481075
--- /dev/null
+++ b/core/data/schema/versions/SDEZ_9_upgrade.sql
@@ -0,0 +1,20 @@
+ALTER TABLE mai2_profile_detail
+ ADD currentPlayCount INT NULL AFTER playCount,
+ ADD renameCredit INT NULL AFTER banState;
+
+ALTER TABLE mai2_playlog
+ ADD extBool1 BOOLEAN NULL AFTER extNum4;
+
+CREATE TABLE `mai2_playlog_2p` (
+ `id` INT NOT NULL AUTO_INCREMENT,
+ `user` INT NOT NULL,
+ `userId1` BIGINT,
+ `userId2` BIGINT,
+ `userName1` VARCHAR(255),
+ `userName2` VARCHAR(255),
+ `regionId` INT,
+ `placeId` INT,
+ `user2pPlaylogDetailList` JSON,
+ PRIMARY KEY (`id`),
+ FOREIGN KEY (`user`) REFERENCES `aime_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
diff --git a/docs/game_specific_info.md b/docs/game_specific_info.md
index 5810ff8..0bdc572 100644
--- a/docs/game_specific_info.md
+++ b/docs/game_specific_info.md
@@ -201,6 +201,7 @@ Config file is located in `config/cxb.yaml`.
| SDEZ | 18 | maimai DX UNiVERSE PLUS |
| SDEZ | 19 | maimai DX FESTiVAL |
| SDEZ | 20 | maimai DX FESTiVAL PLUS |
+| SDEZ | 21 | maimai DX BUDDiES |
### Importer
diff --git a/readme.md b/readme.md
index cbd89c9..8d0e04e 100644
--- a/readme.md
+++ b/readme.md
@@ -11,7 +11,7 @@ Games listed below have been tested and confirmed working. Only game versions ol
+ All versions + omnimix
+ maimai DX
- + All versions up to FESTiVAL PLUS
+ + All versions up to BUDDiES
+ Hatsune Miku: Project DIVA Arcade
+ All versions
diff --git a/titles/cm/read.py b/titles/cm/read.py
index 376789d..80684bd 100644
--- a/titles/cm/read.py
+++ b/titles/cm/read.py
@@ -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):
diff --git a/titles/mai2/__init__.py b/titles/mai2/__init__.py
index 4857644..a3c178e 100644
--- a/titles/mai2/__init__.py
+++ b/titles/mai2/__init__.py
@@ -16,4 +16,4 @@ game_codes = [
Mai2Constants.GAME_CODE_GREEN,
Mai2Constants.GAME_CODE,
]
-current_schema_version = 8
+current_schema_version = 9
diff --git a/titles/mai2/buddies.py b/titles/mai2/buddies.py
new file mode 100644
index 0000000..ccc73bb
--- /dev/null
+++ b/titles/mai2/buddies.py
@@ -0,0 +1,19 @@
+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
+
+ 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
+ user_data["lastDataVersion"] = "1.40.00"
+ return user_data
diff --git a/titles/mai2/const.py b/titles/mai2/const.py
index a4c29db..ce70d70 100644
--- a/titles/mai2/const.py
+++ b/titles/mai2/const.py
@@ -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
diff --git a/titles/mai2/dx.py b/titles/mai2/dx.py
index 508cebb..56489dc 100644
--- a/titles/mai2/dx.py
+++ b/titles/mai2/dx.py
@@ -213,6 +213,9 @@ class Mai2DX(Mai2Base):
)
self.data.item.put_friend_season_ranking(user_id, fsr)
+ if "user2pPlaylog" in upsert:
+ self.data.score.put_2p_playlog(user_id, upsert["user2pPlaylog"])
+
return {"returnCode": 1, "apiName": "UpsertUserAllApi"}
def handle_get_user_data_api_request(self, data: Dict) -> Dict:
diff --git a/titles/mai2/index.py b/titles/mai2/index.py
index 793aaef..b4cb228 100644
--- a/titles/mai2/index.py
+++ b/titles/mai2/index.py
@@ -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")
@@ -252,8 +254,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.getHeader("Mai-Encoding") is not None
diff --git a/titles/mai2/schema/profile.py b/titles/mai2/schema/profile.py
index 211440d..bcb4997 100644
--- a/titles/mai2/schema/profile.py
+++ b/titles/mai2/schema/profile.py
@@ -40,6 +40,7 @@ detail = Table(
Column("charaLockSlot", JSON),
Column("contentBit", BigInteger),
Column("playCount", Integer),
+ Column("currentPlayCount", Integer), # new with buddies
Column("mapStock", Integer), # new with fes+
Column("eventWatchedDate", String(25)),
Column("lastGameId", String(25)),
@@ -96,6 +97,7 @@ detail = Table(
Column("playerNewRating", BigInteger),
Column("dateTime", BigInteger),
Column("banState", Integer), # new with uni+
+ Column("renameCredit", Integer), # new with buddies
UniqueConstraint("user", "version", name="mai2_profile_detail_uk"),
mysql_charset="utf8mb4",
)
@@ -217,7 +219,7 @@ extend = Table(
Column("isPhotoAgree", Boolean),
Column("isGotoCodeRead", Boolean),
Column("selectResultDetails", Boolean),
- Column("selectResultScoreViewType", Integer), # new with fes+
+ Column("selectResultScoreViewType", Integer), # new with fes+
Column("sortCategorySetting", Integer),
Column("sortMusicSetting", Integer),
Column("selectedCardList", JSON),
diff --git a/titles/mai2/schema/score.py b/titles/mai2/schema/score.py
index 181a895..7f29b2b 100644
--- a/titles/mai2/schema/score.py
+++ b/titles/mai2/schema/score.py
@@ -146,10 +146,29 @@ playlog = Table(
Column("extNum1", Integer),
Column("extNum2", Integer),
Column("extNum4", Integer, server_default="0"),
+ Column("extBool1", Boolean), # new with buddies
Column("trialPlayAchievement", Integer),
mysql_charset="utf8mb4",
)
+playlog_2p = Table( # new with buddies, the in-game name is 2pPlaylog
+ "mai2_playlog_2p",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("userId1", BigInteger),
+ Column("userId2", BigInteger),
+ Column("userName1", String(255)),
+ Column("userName2", String(255)),
+ Column("regionId", Integer),
+ Column("placeId", Integer),
+ Column("user2pPlaylogDetailList", JSON),
+)
+
course = Table(
"mai2_score_course",
metadata,
@@ -344,6 +363,18 @@ class Mai2ScoreData(BaseData):
return None
return result.lastrowid
+ def put_2p_playlog(self, user_id: int, playlog_data: Dict) -> Optional[int]:
+ if not playlog_data["user2pPlaylogDetailList"]:
+ self.logger.info("1P play, ignoring.")
+ return None
+ playlog_data["user"] = user_id
+ sql = insert(playlog_2p).values(**playlog_data)
+ conflict = sql.on_duplicate_key_update(**playlog_data)
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(f"put_2p_playlog: Failed to insert! user_id {user_id}")
+ return None
+
def put_course(self, user_id: int, course_data: Dict) -> Optional[int]:
course_data["user"] = user_id
sql = insert(course).values(**course_data)

46
CozyNet/Dockerfile Normal file
View File

@ -0,0 +1,46 @@
FROM alpine/git AS git
RUN git clone --depth 1 -b develop https://gitea.tendokyu.moe/PolarisPyra/cozynet /app/web
RUN git clone --depth 1 -b main https://gitea.tendokyu.moe/PolarisPyra/artemisapi /app/api
RUN rm -rf /app/web/.git && rm -rf /app/api/.git
FROM node:20-alpine AS webCache
WORKDIR /app/web
ENV NEXT_PUBLIC_ARTEMIS_API_URL=api/data \
NEXT_PUBLIC_CDN=/public/
COPY --from=git /app/web/package.json /app/web/package.json
RUN sed -i "s#\"@vercel/analytics\":.*##g" -i package.json
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn
COPY --from=git /app/web /app/web
RUN sed -i '/module\.exports = {/a \
output: '"'"'standalone'"'"',' next.config.js \
&& sed -i 's#\${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}#http://127.0.0.1:4000#g' src/app/api/auth/signup/route.ts \
&& sed -i 's#\${process.env.NEXT_PUBLIC_ARTEMIS_API_URL}#http://127.0.0.1:4000#g' src/app/api/auth/login/route.ts \
&& sed -i 's#00001.wav#00034.wav#g' src/components/SystemVoiceUserBox/page.tsx \
&& sed -i 's#\"https://dean.nyc3.cdn.digitaloceanspaces.com/mapIcon/CHU_UI_MapIcon_00000001.png\"#`${process.env.NEXT_PUBLIC_CDN}/mapIcon/CHU_UI_MapIcon_00000001.png`#g' src/components/PlayerMapIcon/page.tsx \
&& yarn build
FROM node:20-alpine AS apiCache
WORKDIR /app/api
COPY --from=git /app/api/package.json /app/api/package.json
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn
COPY --from=git /app/api /app/api
RUN sed -i 's/app.listen(PORT, () => {/app.listen(PORT, "0.0.0.0", () => {/g' app.js
FROM node:20-alpine
ENV NODE_ENV=production \
host=aime \
user=aime \
password=dbpassword \
database=aime \
port=3306 \
JWT_SECRET=Please_Change_Me \
NEXT_PUBLIC_ARTEMIS_API_URL=http://localhost:4000 \
NEXT_PUBLIC_CDN=cdn
RUN apk add --no-cache --purge --clean-protected s6-overlay
COPY --from=apiCache /app/api/ /app/api/
COPY --from=webCache /app/web/.next/standalone/ /app/web/
COPY --from=webCache /app/web/.next/static/ /app/web/.next/static/
COPY etc /etc
EXPOSE 4000
ENTRYPOINT ["/init"]

4
CozyNet/etc/services.d/api/run Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/with-contenv sh
cd /app/api
node server.js

4
CozyNet/etc/services.d/web/run Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/with-contenv sh
cd /app/web
node server.js

23
MaiMaiDXNet/Dockerfile Normal file
View File

@ -0,0 +1,23 @@
FROM alpine/git AS git
COPY ./MaiMaiDXNet /app
#RUN git clone --depth 1 -b master https://dev.s-ul.net/Galexion/MaiMaiDXNet /app/
RUN rm -rf /app/.git
FROM node:20-alpine AS build
COPY --from=git /app/package.json /app/package.json
WORKDIR /app/
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn
COPY --from=git /app/ /app/
ENV serverType=0 \
aquaSrvDir=false \
ArtImageImport=false \
ArtImageDirectory=/data/artemis/image \
connectionLimit=2 \
host=database \
user=aime \
pass=aSecurePassword \
imageFolder=/data/public/MaiMaiDXNet/images \
hostPort=8000
COPY entrypoint.sh /entrypoint.sh
EXPOSE 8000
ENTRYPOINT ["/entrypoint.sh"]

37
MaiMaiDXNet/entrypoint.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
if [ "$serverType" == "0" ]; then
cat > /app/config.json <<EOF
{
"serverType": $serverType,
"aquaSrvDir": "$aquaSrvDir",
"ArtConnSettings": {
"host": "$host",
"user": "$user",
"password": "$pass"
},
"imageFolder": "$imageFolder",
"hostPort": "$hostPort"
}
EOF
elif [ "$serverType" == "1" ]; then
cat > /app/config.json <<EOF
{
"serverType": $serverType,
"ArtImageImport": $ArtImageImport,
"ArtImageDirectory": "$ArtImageDirectory",
"ArtConnSettings": {
"connectionLimit": "$connectionLimit",
"host": "$host",
"user": "$user",
"pass": "$pass"
},
"imageFolder": "$imageFolder",
"hostPort": "$hostPort"
}
EOF
else
echo "Unsupported serverType"
fi
node index.js

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# Hello
## To be updated