Commit e6edd444 authored by nanahira's avatar nanahira

Merge branch 'master' into ai-play

parents 92c9fa5f 55f93dc3
Pipeline #5514 passed with stages
in 41 minutes and 42 seconds
...@@ -32,6 +32,7 @@ test* ...@@ -32,6 +32,7 @@ test*
*.tmp *.tmp
*.bak *.bak
*.log *.log
log.*
*.map *.map
......
stages: stages:
- build - build
- build2
- combine
- deploy - deploy
variables: variables:
GIT_DEPTH: "1" GIT_DEPTH: "1"
CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG CONTAINER_TEST_IMAGE_FULL: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-full
CONTAINER_TEST_IMAGE_LITE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-lite CONTAINER_TEST_IMAGE_LITE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-lite
CONTAINER_TEST_IMAGE_X86_FULL: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-x86-full
CONTAINER_TEST_IMAGE_X86_LITE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-x86-lite
CONTAINER_TEST_IMAGE_ARM_FULL: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-arm-full
CONTAINER_TEST_IMAGE_ARM_LITE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG-arm-lite
CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest
CONTAINER_RELEASE_IMAGE_FULL: $CI_REGISTRY_IMAGE:full
CONTAINER_RELEASE_IMAGE_LITE: $CI_REGISTRY_IMAGE:lite CONTAINER_RELEASE_IMAGE_LITE: $CI_REGISTRY_IMAGE:lite
build: build_lite_x86:
stage: build stage: build
tags: tags:
- docker - docker
script: script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_X86_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --pull --no-cache -t $CONTAINER_TEST_IMAGE . - docker build --pull --no-cache -f ./Dockerfile.lite -t $TARGET_IMAGE .
- docker push $CONTAINER_TEST_IMAGE - docker push $TARGET_IMAGE
build_lite_arm:
build_lite:
stage: build stage: build
tags: tags:
- docker-arm
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_ARM_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --pull --no-cache -f ./Dockerfile.lite -t $TARGET_IMAGE .
- docker push $TARGET_IMAGE
build_full_x86:
stage: build2
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_X86_FULL
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE_X86_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --build-arg BASE_IMAGE=$SOURCE_IMAGE --pull --no-cache -t
$TARGET_IMAGE .
- docker push $TARGET_IMAGE
build_full_arm:
stage: build2
tags:
- docker-arm
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_ARM_FULL
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE_ARM_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --build-arg BASE_IMAGE=$SOURCE_IMAGE --pull --no-cache -t
$TARGET_IMAGE .
- docker push $TARGET_IMAGE
combine_lite:
stage: build2
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_LITE
- SOURCE_IMAGE_2=$CONTAINER_TEST_IMAGE_ARM_LITE
- SOURCE_IMAGE_1=$CONTAINER_TEST_IMAGE_X86_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $SOURCE_IMAGE_1
- docker pull $SOURCE_IMAGE_2
- docker manifest create $TARGET_IMAGE --amend $SOURCE_IMAGE_1 --amend
$SOURCE_IMAGE_2
- docker manifest push $TARGET_IMAGE
combine_full:
stage: combine
tags:
- docker - docker
script: script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_FULL
- SOURCE_IMAGE_2=$CONTAINER_TEST_IMAGE_ARM_FULL
- SOURCE_IMAGE_1=$CONTAINER_TEST_IMAGE_X86_FULL
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --pull --no-cache -f ./Dockerfile.lite -t $CONTAINER_TEST_IMAGE_LITE . - docker pull $SOURCE_IMAGE_1
- docker push $CONTAINER_TEST_IMAGE_LITE - docker pull $SOURCE_IMAGE_2
- docker manifest create $TARGET_IMAGE --amend $SOURCE_IMAGE_1 --amend
$SOURCE_IMAGE_2
- docker manifest push $TARGET_IMAGE
#upload_stuff_to_minio: #upload_stuff_to_minio:
# stage: deploy # stage: deploy
# tags: # tags:
# - linux # - linux
# image: $CONTAINER_TEST_IMAGE # image: $CONTAINER_TEST_IMAGE_FULL
# script: # script:
# - apt update ; apt -y install python3-pip # - apt update ; apt -y install python3-pip
# - pip3 install -U -i https://mirrors.aliyun.com/pypi/simple/ awscli # - pip3 install -U -i https://mirrors.aliyun.com/pypi/simple/ awscli
...@@ -42,35 +102,61 @@ build_lite: ...@@ -42,35 +102,61 @@ build_lite:
# only: # only:
# - master # - master
deploy_latest: deploy_latest_full:
stage: deploy stage: deploy
tags: tags:
- docker - docker
script: script:
- TARGET_IMAGE_2=$CONTAINER_RELEASE_IMAGE
- TARGET_IMAGE=$CONTAINER_RELEASE_IMAGE_FULL
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE_FULL
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $CONTAINER_TEST_IMAGE - docker pull $SOURCE_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE - docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE - docker push $TARGET_IMAGE
- docker pull $CONTAINER_TEST_IMAGE_LITE - docker tag $SOURCE_IMAGE $TARGET_IMAGE_2
- docker tag $CONTAINER_TEST_IMAGE_LITE $CONTAINER_RELEASE_IMAGE_LITE - docker push $TARGET_IMAGE_2
- docker push $CONTAINER_RELEASE_IMAGE_LITE
only: only:
- master - master
deploy_latest_lite:
deploy_tag: stage: deploy
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_RELEASE_IMAGE_LITE
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
only:
- master
deploy_tag_full:
stage: deploy
tags:
- docker
script:
- TARGET_IMAGE_2=$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
- TARGET_IMAGE=$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG-full
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE_FULL
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE_2
- docker push $TARGET_IMAGE_2
only:
- tags
deploy_tag_lite:
stage: deploy stage: deploy
tags: tags:
- docker - docker
variables:
CONTAINER_TAG_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
CONTAINER_TAG_IMAGE_LITE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG-lite
script: script:
- TARGET_IMAGE=$CI_REGISTRY_IMAGE:$CI_COMMIT_TAG-lite
- SOURCE_IMAGE=$CONTAINER_TEST_IMAGE_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker pull $CONTAINER_TEST_IMAGE - docker pull $SOURCE_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_TAG_IMAGE - docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $CONTAINER_TAG_IMAGE - docker push $TARGET_IMAGE
- docker pull $CONTAINER_TEST_IMAGE_LITE
- docker tag $CONTAINER_TEST_IMAGE_LITE $CONTAINER_RELEASE_IMAGE_LITE
- docker push $CONTAINER_RELEASE_IMAGE_LITE
only: only:
- tags - tags
# Dockerfile for SRVPro ARG BASE_IMAGE=git-registry.mycard.moe/mycard/srvpro:lite
FROM node:14-buster-slim FROM $BASE_IMAGE
LABEL Author="Nanahira <nanahira@momobako.com>"
RUN npm install -g pm2
# apt
RUN apt update && \ RUN apt update && \
env DEBIAN_FRONTEND=noninteractive apt install -y wget git build-essential libevent-dev libsqlite3-dev mono-complete p7zip-full python3 liblua5.3-dev && \ apt -y install mono-complete && \
rm -rf /var/lib/apt/lists/* npm install -g pm2 && \
rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*
# srvpro
COPY . /ygopro-server
WORKDIR /ygopro-server
RUN npm ci && \
mkdir config decks replays logs /redis
# ygopro
RUN git clone --branch=server --recursive --depth=1 https://github.com/purerosefallen/ygopro && \
cd ygopro && \
git submodule foreach git checkout master && \
wget -O - https://github.com/premake/premake-core/releases/download/v5.0.0-alpha14/premake-5.0.0-alpha14-linux.tar.gz | tar zfx - && \
./premake5 gmake && \
cd build && \
make config=release -j$(nproc) && \
cd .. && \
mv ./bin/release/ygopro . && \
strip ygopro && \
mkdir replay expansions && \
rm -rf .git* bin obj build ocgcore cmake lua premake* sound textures .travis.yml *.txt appveyor.yml LICENSE README.md *.lua strings.conf system.conf && \
ls gframe | sed '/game.cpp/d' | xargs -I {} rm -rf gframe/{}
# windbot # windbot
RUN git clone --depth=1 https://github.com/purerosefallen/windbot /tmp/windbot && \ RUN git clone --depth=1 https://code.mycard.moe/nanahira/windbot /tmp/windbot && \
cd /tmp/windbot && \ cd /tmp/windbot && \
xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \ xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \
mv /tmp/windbot/bin/Release /ygopro-server/windbot && \ mv /tmp/windbot/bin/Release /ygopro-server/windbot && \
cp -rf /ygopro-server/ygopro/cards.cdb /ygopro-server/windbot/ && \ cp -rf /ygopro-server/ygopro/cards.cdb /ygopro-server/windbot/ && \
rm -rf /tmp/windbot rm -rf /tmp/windbot
# infos
WORKDIR /ygopro-server
EXPOSE 7911 7922 7933
# VOLUME [ /ygopro-server/config, /ygopro-server/decks, /ygopro-server/replays, /redis ]
CMD [ "pm2-docker", "start", "/ygopro-server/data/pm2-docker.json" ] CMD [ "pm2-docker", "start", "/ygopro-server/data/pm2-docker.json" ]
# Dockerfile for SRVPro Lite # Dockerfile for SRVPro Lite
FROM node:14-buster-slim FROM debian:bullseye as premake-builder
RUN apt update && \
env DEBIAN_FRONTEND=noninteractive apt install -y wget build-essential p7zip-full && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /usr/src
RUN wget -O premake.zip https://github.com/premake/premake-core/releases/download/v5.0.0-alpha14/premake-5.0.0-alpha14-src.zip && \
7z x -y premake.zip && \
mv premake-5.0.0-alpha14 premake && \
cd premake/build/gmake.unix && \
make -j$(nproc)
FROM node:16-bullseye-slim
LABEL Author="Nanahira <nanahira@momobako.com>"
# apt # apt
RUN apt update && \ RUN apt update && \
env DEBIAN_FRONTEND=noninteractive apt install -y wget git build-essential libsqlite3-dev libevent-dev p7zip-full python3 liblua5.3-dev && \ env DEBIAN_FRONTEND=noninteractive apt install -y wget git build-essential libevent-dev libsqlite3-dev p7zip-full python3 python-is-python3 liblua5.3-dev && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# srvpro # srvpro
COPY . /ygopro-server COPY . /ygopro-server
...@@ -12,11 +26,12 @@ WORKDIR /ygopro-server ...@@ -12,11 +26,12 @@ WORKDIR /ygopro-server
RUN npm ci && \ RUN npm ci && \
mkdir config decks replays logs mkdir config decks replays logs
RUN git clone --branch=server --recursive --depth=1 https://github.com/purerosefallen/ygopro && \ COPY --from=premake-builder /usr/src/premake/bin/release/premake5 /usr/bin/premake5
RUN git clone --branch=server --recursive --depth=1 https://code.mycard.moe/nanahira/ygopro && \
cd ygopro && \ cd ygopro && \
git submodule foreach git checkout master && \ git submodule foreach git checkout master && \
wget -O - https://github.com/premake/premake-core/releases/download/v5.0.0-alpha13/premake-5.0.0-alpha13-linux.tar.gz | tar zfx - && \ premake5 gmake && \
./premake5 gmake && \
cd build && \ cd build && \
make config=release -j$(nproc) && \ make config=release -j$(nproc) && \
cd .. && \ cd .. && \
...@@ -31,4 +46,4 @@ WORKDIR /ygopro-server ...@@ -31,4 +46,4 @@ WORKDIR /ygopro-server
EXPOSE 7911 7922 7933 EXPOSE 7911 7922 7933
# VOLUME [ /ygopro-server/config, /ygopro-server/decks, /ygopro-server/replays ] # VOLUME [ /ygopro-server/config, /ygopro-server/decks, /ygopro-server/replays ]
CMD [ "node", "ygopro-server.js" ] CMD [ "npm", "start" ]
...@@ -122,9 +122,10 @@ class Replay ...@@ -122,9 +122,10 @@ class Replay
@fromBuffer: (buffer) -> @fromBuffer: (buffer) ->
reader = new ReplayReader buffer reader = new ReplayReader buffer
header = Replay.readHeader reader header = Replay.readHeader reader
lzmaBuffer = Buffer.concat [header.getLzmaHeader(), reader.readAll()] restBuffer = reader.readAll()
lzmaBuffer = Buffer.concat [header.getLzmaHeader(), restBuffer]
if header.isCompressed if header.isCompressed
decompressed = lzmaBuffer decompressed = restBuffer
else else
decompressed = Buffer.from lzma.decompress lzmaBuffer decompressed = Buffer.from lzma.decompress lzmaBuffer
reader = new ReplayReader decompressed reader = new ReplayReader decompressed
......
...@@ -180,12 +180,13 @@ ...@@ -180,12 +180,13 @@
} }
static fromBuffer(buffer) { static fromBuffer(buffer) {
var decompressed, header, lzmaBuffer, reader, replay; var decompressed, header, lzmaBuffer, reader, replay, restBuffer;
reader = new ReplayReader(buffer); reader = new ReplayReader(buffer);
header = Replay.readHeader(reader); header = Replay.readHeader(reader);
lzmaBuffer = Buffer.concat([header.getLzmaHeader(), reader.readAll()]); restBuffer = reader.readAll();
lzmaBuffer = Buffer.concat([header.getLzmaHeader(), restBuffer]);
if (header.isCompressed) { if (header.isCompressed) {
decompressed = lzmaBuffer; decompressed = restBuffer;
} else { } else {
decompressed = Buffer.from(lzma.decompress(lzmaBuffer)); decompressed = Buffer.from(lzma.decompress(lzmaBuffer));
} }
......
...@@ -8,7 +8,7 @@ import net from "net"; ...@@ -8,7 +8,7 @@ import net from "net";
class Handler { class Handler {
handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>; private handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>;
synchronous: boolean; synchronous: boolean;
constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean) { constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean) {
this.handler = handler; this.handler = handler;
...@@ -46,14 +46,32 @@ export interface HandleResult { ...@@ -46,14 +46,32 @@ export interface HandleResult {
feedback: Feedback; feedback: Feedback;
} }
export interface Constants {
TYPES: Record<string, number>;
RACES: Record<string, number>;
ATTRIBUTES: Record<string, number>;
LINK_MARKERS: Record<string, number>;
DUEL_STAGE: Record<string, number>;
COLORS: Record<string, number>;
TIMING: Record<string, string>;
NETWORK: Record<string, string>;
NETPLAYER: Record<string, string>;
CTOS: Record<string, string>;
STOC: Record<string, string>;
PLAYERCHANGE: Record<string, string>;
ERRMSG: Record<string, string>;
MODE: Record<string, string>;
MSG: Record<string, string>;
}
export class YGOProMessagesHelper { export class YGOProMessagesHelper {
handlers: HandlerList; handlers: HandlerList;
structs: Map<string, Struct>; structs: Map<string, Struct>;
structs_declaration: any; structs_declaration: Record<string, Struct>;
typedefs: any; typedefs: Record<string, string>;
proto_structs: any; proto_structs: Record<'CTOS' | 'STOC', Record<string, string>>;
constants: any; constants: Constants;
singleHandleLimit: number; singleHandleLimit: number;
constructor(singleHandleLimit?: number) { constructor(singleHandleLimit?: number) {
......
...@@ -268,8 +268,8 @@ class DataManager { ...@@ -268,8 +268,8 @@ class DataManager {
const queryBuilder = repo.createQueryBuilder("duelLog") const queryBuilder = repo.createQueryBuilder("duelLog")
.where("1"); .where("1");
if (roomName != null && roomName.length) { if (roomName != null && roomName.length) {
const escapedRoomName = this.getEscapedString(roomName); //const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name like :escapedRoomName", { escapedRoomName }); queryBuilder.andWhere("duelLog.name = :roomName", { roomName });
} }
if (duelCount != null && !isNaN(duelCount)) { if (duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount }); queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
...@@ -278,9 +278,9 @@ class DataManager { ...@@ -278,9 +278,9 @@ class DataManager {
let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id"; let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams = {}; const innerQueryParams = {};
if (playerName != null && playerName.length) { if (playerName != null && playerName.length) {
const escapedPlayerName = this.getEscapedString(playerName); //const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName like :escapedPlayerName"; innerQuery += " and duel_log_player.realName = :playerName";
innerQueryParams.escapedPlayerName = escapedPlayerName; innerQueryParams.playerName = playerName;
} }
if (playerScore != null && !isNaN(playerScore)) { if (playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore"; innerQuery += " and duel_log_player.score = :playerScore";
...@@ -710,16 +710,25 @@ class DataManager { ...@@ -710,16 +710,25 @@ class DataManager {
} }
async randomDuelPlayerWin(name) { async randomDuelPlayerWin(name) {
const score = await this.getOrCreateRandomDuelScore(name); const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.win(); score.win();
await this.saveRandomDuelScore(score); await this.saveRandomDuelScore(score);
} }
async randomDuelPlayerLose(name) { async randomDuelPlayerLose(name) {
const score = await this.getOrCreateRandomDuelScore(name); const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.lose(); score.lose();
await this.saveRandomDuelScore(score); await this.saveRandomDuelScore(score);
} }
async randomDuelPlayerFlee(name) { async randomDuelPlayerFlee(name) {
const score = await this.getOrCreateRandomDuelScore(name); const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.flee(); score.flee();
await this.saveRandomDuelScore(score); await this.saveRandomDuelScore(score);
} }
......
...@@ -276,8 +276,8 @@ export class DataManager { ...@@ -276,8 +276,8 @@ export class DataManager {
const queryBuilder = repo.createQueryBuilder("duelLog") const queryBuilder = repo.createQueryBuilder("duelLog")
.where("1"); .where("1");
if(roomName != null && roomName.length) { if(roomName != null && roomName.length) {
const escapedRoomName = this.getEscapedString(roomName); //const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name like :escapedRoomName", { escapedRoomName }); queryBuilder.andWhere("duelLog.name = :roomName", { roomName });
} }
if(duelCount != null && !isNaN(duelCount)) { if(duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount }); queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
...@@ -286,9 +286,9 @@ export class DataManager { ...@@ -286,9 +286,9 @@ export class DataManager {
let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id"; let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams: any = {}; const innerQueryParams: any = {};
if(playerName != null && playerName.length) { if(playerName != null && playerName.length) {
const escapedPlayerName = this.getEscapedString(playerName); //const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName like :escapedPlayerName"; innerQuery += " and duel_log_player.realName = :playerName";
innerQueryParams.escapedPlayerName = escapedPlayerName; innerQueryParams.playerName = playerName;
} }
if(playerScore != null && !isNaN(playerScore)) { if(playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore"; innerQuery += " and duel_log_player.score = :playerScore";
...@@ -714,16 +714,25 @@ export class DataManager { ...@@ -714,16 +714,25 @@ export class DataManager {
} }
async randomDuelPlayerWin(name: string) { async randomDuelPlayerWin(name: string) {
const score = await this.getOrCreateRandomDuelScore(name); const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.win(); score.win();
await this.saveRandomDuelScore(score); await this.saveRandomDuelScore(score);
} }
async randomDuelPlayerLose(name: string) { async randomDuelPlayerLose(name: string) {
const score = await this.getOrCreateRandomDuelScore(name); const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.lose(); score.lose();
await this.saveRandomDuelScore(score); await this.saveRandomDuelScore(score);
} }
async randomDuelPlayerFlee(name: string) { async randomDuelPlayerFlee(name: string) {
const score = await this.getOrCreateRandomDuelScore(name); const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.flee(); score.flee();
await this.saveRandomDuelScore(score); await this.saveRandomDuelScore(score);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"lflist": 0, "lflist": 0,
"rule": 0, "rule": 0,
"mode": 0, "mode": 0,
"comment": "rule: 0=OCGONLY, 1=TCGONLY, 2=OT; mode: 0=SINGLE, 1=MATCH, 2=TAG", "comment": "rule: 0=OCG-ONLY, 1=TCG-ONLY, 2=SC-ONLY, 3=CUSTOM-ONLY, 4=NO-UNIQUE, 5=ALL; mode: 0=SINGLE, 1=MATCH, 2=TAG",
"duel_rule": 5, "duel_rule": 5,
"no_check_deck": false, "no_check_deck": false,
"no_shuffle_deck": false, "no_shuffle_deck": false,
...@@ -20,8 +20,11 @@ ...@@ -20,8 +20,11 @@
}, },
"modules": { "modules": {
"welcome": "MyCard YGOPro Server", "welcome": "MyCard YGOPro Server",
"update": "请更新游戏版本", "update": "请更新你的客户端版本",
"wait_update": "你的客户端版本高于服务器版本,请等待服务器更新",
"stop": false, "stop": false,
"full": "服务器已爆满",
"max_rooms_count": 0,
"side_timeout": false, "side_timeout": false,
"tag_duel_surrender": true, "tag_duel_surrender": true,
"replay_delay": true, "replay_delay": true,
...@@ -89,7 +92,17 @@ ...@@ -89,7 +92,17 @@
"blank_pass_modes": { "blank_pass_modes": {
"S": true, "S": true,
"M": true, "M": true,
"T": false "T": false,
"OOR": true,
"TOR": false,
"OR": true,
"TR": true,
"CR": false,
"OOMR": true,
"TOMR": false,
"OMR": true,
"CMR": false,
"TMR": true
}, },
"ready_time": 20, "ready_time": 20,
"hang_timeout": 90 "hang_timeout": 90
...@@ -137,9 +150,9 @@ ...@@ -137,9 +150,9 @@
}, },
"mycard": { "mycard": {
"enabled": false, "enabled": false,
"auth_base_url": "https://ygobbs.com", "auth_base_url": "https://sapi.moecube.com:444/accounts",
"auth_database": "postgres://233@233.mycard.moe/233", "auth_database": "postgres://233@233.mycard.moe/233",
"ban_get": "https://api.mycard.moe/ygopro/big-brother/ban", "ban_get": "https://sapi.moecube.com:444/ygopro/big-brother/ban",
"auth_key": "233333" "auth_key": "233333"
}, },
"challonge": { "challonge": {
...@@ -147,6 +160,7 @@ ...@@ -147,6 +160,7 @@
"post_detailed_score": true, "post_detailed_score": true,
"post_score_midduel": true, "post_score_midduel": true,
"cache_ttl": 60000, "cache_ttl": 60000,
"no_match_mode": false,
"options": { "options": {
"apiKey": "123" "apiKey": "123"
}, },
...@@ -157,13 +171,13 @@ ...@@ -157,13 +171,13 @@
"enabled": false, "enabled": false,
"accesskey": "233", "accesskey": "233",
"local": "./deck_log/", "local": "./deck_log/",
"post": "https://api.mycard.moe/ygopro/analytics/deck/text", "post": "https://sapi.moecube.com:444/ygopro/analytics/deck/text",
"arena": "233" "arena": "233"
}, },
"big_brother": { "big_brother": {
"enabled": false, "enabled": false,
"accesskey": "233", "accesskey": "233",
"post": "https://api.mycard.moe/ygopro/big-brother" "post": "https://sapi.moecube.com:444/ygopro/big-brother"
}, },
"arena_mode": { "arena_mode": {
"enabled": false, "enabled": false,
...@@ -171,13 +185,13 @@ ...@@ -171,13 +185,13 @@
"comment": "mode: athletic / entertain", "comment": "mode: athletic / entertain",
"accesskey": "233", "accesskey": "233",
"ready_time": 30, "ready_time": 30,
"check_permit": "https://api.mycard.moe/ygopro/match/permit", "check_permit": "https://sapi.moecube.com:444/ygopro/match/permit",
"post_score": false, "post_score": false,
"get_score": false, "get_score": false,
"punish_quit_before_match": false, "punish_quit_before_match": false,
"init_post": { "init_post": {
"enabled": false, "enabled": false,
"url": "https://api.mycard.moe/ygopro/match/clear", "url": "https://sapi.moecube.com:444/ygopro/match/clear",
"accesskey": "momobako" "accesskey": "momobako"
} }
}, },
...@@ -197,8 +211,8 @@ ...@@ -197,8 +211,8 @@
}, },
"athletic_check": { "athletic_check": {
"enabled": false, "enabled": false,
"rankURL": "https://api.mycard.moe/ygopro/analytics/deck/type", "rankURL": "https://sapi.moecube.com:444/ygopro/analytics/deck/type",
"identifierURL": "https://api.mycard.moe/ygopro/identifier/production", "identifierURL": "https://sapi.moecube.com:444/ygopro/identifier/production",
"athleticFetchParams": { "athleticFetchParams": {
"type": "week", "type": "week",
"source": "mycard-athletic" "source": "mycard-athletic"
......
...@@ -6,10 +6,10 @@ server = null ...@@ -6,10 +6,10 @@ server = null
room_data = (room)-> room_data = (room)->
id: room.name, id: room.name,
title: room.title, title: room.title || room.name,
user: {username: room.username} user: {username: room.username}
users: ({username: client.name, position: client.pos} for client in room.players), users: ({username: client.name, position: client.pos} for client in room.players),
options: room.get_old_hostinfo(), # Should be updated when MyCard client updates options: room.get_roomlist_hostinfo(), # Should be updated when MyCard client updates
arena: settings.modules.arena_mode.enabled && room.arena && settings.modules.arena_mode.mode arena: settings.modules.arena_mode.enabled && room.arena && settings.modules.arena_mode.mode
init = (http_server, ROOM_all)-> init = (http_server, ROOM_all)->
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
var client; var client;
return { return {
id: room.name, id: room.name,
title: room.title, title: room.title || room.name,
user: { user: {
username: room.username username: room.username
}, },
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
} }
return results; return results;
})(), })(),
options: room.get_old_hostinfo(), // Should be updated when MyCard client updates options: room.get_roomlist_hostinfo(), // Should be updated when MyCard client updates
arena: settings.modules.arena_mode.enabled && room.arena && settings.modules.arena_mode.mode arena: settings.modules.arena_mode.enabled && room.arena && settings.modules.arena_mode.mode
}; };
}; };
......
This diff is collapsed.
This diff is collapsed.
...@@ -7,8 +7,20 @@ loadJSON = require('load-json-file').sync ...@@ -7,8 +7,20 @@ loadJSON = require('load-json-file').sync
@i18ns = loadJSON './data/i18n.json' @i18ns = loadJSON './data/i18n.json'
@i18nR = {}
@reloadI18nR = () ->
for lang, data of @i18ns
@i18nR[lang]={}
for key, text of data
@i18nR[lang][key]={
regex: new RegExp("\\$\\{"+key+"\\}",'g'),
text: text
}
@reloadI18nR()
YGOProMessagesHelper = require("./YGOProMessages.js").YGOProMessagesHelper # 为 SRVPro2 准备的库,这里拿这个库只用来测试,SRVPro1 对异步支持不是特别完善,因此不会有很多异步优化 YGOProMessagesHelper = require("./YGOProMessages.js").YGOProMessagesHelper # 为 SRVPro2 准备的库,这里拿这个库只用来测试,SRVPro1 对异步支持不是特别完善,因此不会有很多异步优化
@helper = new YGOProMessagesHelper() @helper = new YGOProMessagesHelper(9000)
@structs = @helper.structs @structs = @helper.structs
@structs_declaration = @helper.structs_declaration @structs_declaration = @helper.structs_declaration
...@@ -54,9 +66,8 @@ translateHandler = (handler) -> ...@@ -54,9 +66,8 @@ translateHandler = (handler) ->
for line in _.lines(msg) for line in _.lines(msg)
if player>=10 if player>=10
line="[Server]: "+line line="[Server]: "+line
for o,r of @i18ns[client.lang] for o,r of @i18nR[client.lang]
re=new RegExp("\\$\\{"+o+"\\}",'g') line=line.replace(r.regex, r.text)
line=line.replace(re,r)
@stoc_send client, 'CHAT', { @stoc_send client, 'CHAT', {
player: player player: player
msg: line msg: line
......
...@@ -14,9 +14,36 @@ ...@@ -14,9 +14,36 @@
this.i18ns = loadJSON('./data/i18n.json'); this.i18ns = loadJSON('./data/i18n.json');
this.i18nR = {};
this.reloadI18nR = function() {
var data, key, lang, ref, results, text;
ref = this.i18ns;
results = [];
for (lang in ref) {
data = ref[lang];
this.i18nR[lang] = {};
results.push((function() {
var results1;
results1 = [];
for (key in data) {
text = data[key];
results1.push(this.i18nR[lang][key] = {
regex: new RegExp("\\$\\{" + key + "\\}", 'g'),
text: text
});
}
return results1;
}).call(this));
}
return results;
};
this.reloadI18nR();
YGOProMessagesHelper = require("./YGOProMessages.js").YGOProMessagesHelper; // 为 SRVPro2 准备的库,这里拿这个库只用来测试,SRVPro1 对异步支持不是特别完善,因此不会有很多异步优化 YGOProMessagesHelper = require("./YGOProMessages.js").YGOProMessagesHelper; // 为 SRVPro2 准备的库,这里拿这个库只用来测试,SRVPro1 对异步支持不是特别完善,因此不会有很多异步优化
this.helper = new YGOProMessagesHelper(); this.helper = new YGOProMessagesHelper(9000);
this.structs = this.helper.structs; this.structs = this.helper.structs;
...@@ -69,7 +96,7 @@ ...@@ -69,7 +96,7 @@
//util //util
this.stoc_send_chat = function(client, msg, player = 8) { this.stoc_send_chat = function(client, msg, player = 8) {
var i, len, line, o, r, re, ref, ref1; var i, len, line, o, r, ref, ref1;
if (!client) { if (!client) {
console.log("err stoc_send_chat"); console.log("err stoc_send_chat");
return; return;
...@@ -80,11 +107,10 @@ ...@@ -80,11 +107,10 @@
if (player >= 10) { if (player >= 10) {
line = "[Server]: " + line; line = "[Server]: " + line;
} }
ref1 = this.i18ns[client.lang]; ref1 = this.i18nR[client.lang];
for (o in ref1) { for (o in ref1) {
r = ref1[o]; r = ref1[o];
re = new RegExp("\\$\\{" + o + "\\}", 'g'); line = line.replace(r.regex, r.text);
line = line.replace(re, r);
} }
this.stoc_send(client, 'CHAT', { this.stoc_send(client, 'CHAT', {
player: player, player: player,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment