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*
*.tmp
*.bak
*.log
log.*
*.map
......
stages:
- build
- build2
- combine
- deploy
variables:
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_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_FULL: $CI_REGISTRY_IMAGE:full
CONTAINER_RELEASE_IMAGE_LITE: $CI_REGISTRY_IMAGE:lite
build:
build_lite_x86:
stage: build
tags:
tags:
- docker
script:
- TARGET_IMAGE=$CONTAINER_TEST_IMAGE_X86_LITE
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --pull --no-cache -t $CONTAINER_TEST_IMAGE .
- docker push $CONTAINER_TEST_IMAGE
build_lite:
- docker build --pull --no-cache -f ./Dockerfile.lite -t $TARGET_IMAGE .
- docker push $TARGET_IMAGE
build_lite_arm:
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
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 build --pull --no-cache -f ./Dockerfile.lite -t $CONTAINER_TEST_IMAGE_LITE .
- docker push $CONTAINER_TEST_IMAGE_LITE
- 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
#upload_stuff_to_minio:
# stage: deploy
# tags:
# - linux
# image: $CONTAINER_TEST_IMAGE
# image: $CONTAINER_TEST_IMAGE_FULL
# script:
# - apt update ; apt -y install python3-pip
# - pip3 install -U -i https://mirrors.aliyun.com/pypi/simple/ awscli
......@@ -42,35 +102,61 @@ build_lite:
# only:
# - master
deploy_latest:
deploy_latest_full:
stage: deploy
tags:
tags:
- docker
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 pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
- docker push $CONTAINER_RELEASE_IMAGE
- docker pull $CONTAINER_TEST_IMAGE_LITE
- docker tag $CONTAINER_TEST_IMAGE_LITE $CONTAINER_RELEASE_IMAGE_LITE
- docker push $CONTAINER_RELEASE_IMAGE_LITE
- 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:
- master
deploy_tag:
deploy_latest_lite:
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
tags:
tags:
- docker
variables:
CONTAINER_TAG_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
CONTAINER_TAG_IMAGE_LITE: $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG-lite
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 pull $CONTAINER_TEST_IMAGE
- docker tag $CONTAINER_TEST_IMAGE $CONTAINER_TAG_IMAGE
- docker push $CONTAINER_TAG_IMAGE
- docker pull $CONTAINER_TEST_IMAGE_LITE
- docker tag $CONTAINER_TEST_IMAGE_LITE $CONTAINER_RELEASE_IMAGE_LITE
- docker push $CONTAINER_RELEASE_IMAGE_LITE
- docker pull $SOURCE_IMAGE
- docker tag $SOURCE_IMAGE $TARGET_IMAGE
- docker push $TARGET_IMAGE
only:
- tags
# Dockerfile for SRVPro
FROM node:14-buster-slim
ARG BASE_IMAGE=git-registry.mycard.moe/mycard/srvpro:lite
FROM $BASE_IMAGE
LABEL Author="Nanahira <nanahira@momobako.com>"
RUN npm install -g pm2
# apt
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 && \
rm -rf /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/{}
apt -y install mono-complete && \
npm install -g pm2 && \
rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*
# 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 && \
xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \
mv /tmp/windbot/bin/Release /ygopro-server/windbot && \
cp -rf /ygopro-server/ygopro/cards.cdb /ygopro-server/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" ]
# 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
RUN apt update && \
env DEBIAN_FRONTEND=noninteractive apt install -y wget git build-essential libsqlite3-dev libevent-dev p7zip-full python3 liblua5.3-dev && \
rm -rf /var/lib/apt/lists/*
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/* /tmp/* /var/tmp/*
# srvpro
COPY . /ygopro-server
......@@ -12,11 +26,12 @@ WORKDIR /ygopro-server
RUN npm ci && \
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 && \
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 && \
make config=release -j$(nproc) && \
cd .. && \
......@@ -31,4 +46,4 @@ WORKDIR /ygopro-server
EXPOSE 7911 7922 7933
# VOLUME [ /ygopro-server/config, /ygopro-server/decks, /ygopro-server/replays ]
CMD [ "node", "ygopro-server.js" ]
CMD [ "npm", "start" ]
......@@ -122,9 +122,10 @@ class Replay
@fromBuffer: (buffer) ->
reader = new ReplayReader buffer
header = Replay.readHeader reader
lzmaBuffer = Buffer.concat [header.getLzmaHeader(), reader.readAll()]
restBuffer = reader.readAll()
lzmaBuffer = Buffer.concat [header.getLzmaHeader(), restBuffer]
if header.isCompressed
decompressed = lzmaBuffer
decompressed = restBuffer
else
decompressed = Buffer.from lzma.decompress lzmaBuffer
reader = new ReplayReader decompressed
......
......@@ -180,12 +180,13 @@
}
static fromBuffer(buffer) {
var decompressed, header, lzmaBuffer, reader, replay;
var decompressed, header, lzmaBuffer, reader, replay, restBuffer;
reader = new ReplayReader(buffer);
header = Replay.readHeader(reader);
lzmaBuffer = Buffer.concat([header.getLzmaHeader(), reader.readAll()]);
restBuffer = reader.readAll();
lzmaBuffer = Buffer.concat([header.getLzmaHeader(), restBuffer]);
if (header.isCompressed) {
decompressed = lzmaBuffer;
decompressed = restBuffer;
} else {
decompressed = Buffer.from(lzma.decompress(lzmaBuffer));
}
......
......@@ -8,7 +8,7 @@ import net from "net";
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;
constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean) {
this.handler = handler;
......@@ -46,14 +46,32 @@ export interface HandleResult {
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 {
handlers: HandlerList;
structs: Map<string, Struct>;
structs_declaration: any;
typedefs: any;
proto_structs: any;
constants: any;
structs_declaration: Record<string, Struct>;
typedefs: Record<string, string>;
proto_structs: Record<'CTOS' | 'STOC', Record<string, string>>;
constants: Constants;
singleHandleLimit: number;
constructor(singleHandleLimit?: number) {
......
......@@ -268,8 +268,8 @@ class DataManager {
const queryBuilder = repo.createQueryBuilder("duelLog")
.where("1");
if (roomName != null && roomName.length) {
const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name like :escapedRoomName", { escapedRoomName });
//const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name = :roomName", { roomName });
}
if (duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
......@@ -278,9 +278,9 @@ class DataManager {
let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams = {};
if (playerName != null && playerName.length) {
const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName like :escapedPlayerName";
innerQueryParams.escapedPlayerName = escapedPlayerName;
//const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName = :playerName";
innerQueryParams.playerName = playerName;
}
if (playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore";
......@@ -710,16 +710,25 @@ class DataManager {
}
async randomDuelPlayerWin(name) {
const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.win();
await this.saveRandomDuelScore(score);
}
async randomDuelPlayerLose(name) {
const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.lose();
await this.saveRandomDuelScore(score);
}
async randomDuelPlayerFlee(name) {
const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.flee();
await this.saveRandomDuelScore(score);
}
......
......@@ -276,8 +276,8 @@ export class DataManager {
const queryBuilder = repo.createQueryBuilder("duelLog")
.where("1");
if(roomName != null && roomName.length) {
const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name like :escapedRoomName", { escapedRoomName });
//const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name = :roomName", { roomName });
}
if(duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
......@@ -286,9 +286,9 @@ export class DataManager {
let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams: any = {};
if(playerName != null && playerName.length) {
const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName like :escapedPlayerName";
innerQueryParams.escapedPlayerName = escapedPlayerName;
//const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName = :playerName";
innerQueryParams.playerName = playerName;
}
if(playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore";
......@@ -714,16 +714,25 @@ export class DataManager {
}
async randomDuelPlayerWin(name: string) {
const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.win();
await this.saveRandomDuelScore(score);
}
async randomDuelPlayerLose(name: string) {
const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.lose();
await this.saveRandomDuelScore(score);
}
async randomDuelPlayerFlee(name: string) {
const score = await this.getOrCreateRandomDuelScore(name);
if (!score) {
return;
}
score.flee();
await this.saveRandomDuelScore(score);
}
......
......@@ -7,7 +7,7 @@
"lflist": 0,
"rule": 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,
"no_check_deck": false,
"no_shuffle_deck": false,
......@@ -20,8 +20,11 @@
},
"modules": {
"welcome": "MyCard YGOPro Server",
"update": "请更新游戏版本",
"update": "请更新你的客户端版本",
"wait_update": "你的客户端版本高于服务器版本,请等待服务器更新",
"stop": false,
"full": "服务器已爆满",
"max_rooms_count": 0,
"side_timeout": false,
"tag_duel_surrender": true,
"replay_delay": true,
......@@ -89,7 +92,17 @@
"blank_pass_modes": {
"S": 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,
"hang_timeout": 90
......@@ -137,9 +150,9 @@
},
"mycard": {
"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",
"ban_get": "https://api.mycard.moe/ygopro/big-brother/ban",
"ban_get": "https://sapi.moecube.com:444/ygopro/big-brother/ban",
"auth_key": "233333"
},
"challonge": {
......@@ -147,6 +160,7 @@
"post_detailed_score": true,
"post_score_midduel": true,
"cache_ttl": 60000,
"no_match_mode": false,
"options": {
"apiKey": "123"
},
......@@ -157,13 +171,13 @@
"enabled": false,
"accesskey": "233",
"local": "./deck_log/",
"post": "https://api.mycard.moe/ygopro/analytics/deck/text",
"post": "https://sapi.moecube.com:444/ygopro/analytics/deck/text",
"arena": "233"
},
"big_brother": {
"enabled": false,
"accesskey": "233",
"post": "https://api.mycard.moe/ygopro/big-brother"
"post": "https://sapi.moecube.com:444/ygopro/big-brother"
},
"arena_mode": {
"enabled": false,
......@@ -171,13 +185,13 @@
"comment": "mode: athletic / entertain",
"accesskey": "233",
"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,
"get_score": false,
"punish_quit_before_match": false,
"init_post": {
"enabled": false,
"url": "https://api.mycard.moe/ygopro/match/clear",
"url": "https://sapi.moecube.com:444/ygopro/match/clear",
"accesskey": "momobako"
}
},
......@@ -197,8 +211,8 @@
},
"athletic_check": {
"enabled": false,
"rankURL": "https://api.mycard.moe/ygopro/analytics/deck/type",
"identifierURL": "https://api.mycard.moe/ygopro/identifier/production",
"rankURL": "https://sapi.moecube.com:444/ygopro/analytics/deck/type",
"identifierURL": "https://sapi.moecube.com:444/ygopro/identifier/production",
"athleticFetchParams": {
"type": "week",
"source": "mycard-athletic"
......
......@@ -6,10 +6,10 @@ server = null
room_data = (room)->
id: room.name,
title: room.title,
title: room.title || room.name,
user: {username: room.username}
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
init = (http_server, ROOM_all)->
......
......@@ -14,7 +14,7 @@
var client;
return {
id: room.name,
title: room.title,
title: room.title || room.name,
user: {
username: room.username
},
......@@ -31,7 +31,7 @@
}
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
};
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -7,8 +7,20 @@ loadJSON = require('load-json-file').sync
@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 对异步支持不是特别完善,因此不会有很多异步优化
@helper = new YGOProMessagesHelper()
@helper = new YGOProMessagesHelper(9000)
@structs = @helper.structs
@structs_declaration = @helper.structs_declaration
......@@ -54,9 +66,8 @@ translateHandler = (handler) ->
for line in _.lines(msg)
if player>=10
line="[Server]: "+line
for o,r of @i18ns[client.lang]
re=new RegExp("\\$\\{"+o+"\\}",'g')
line=line.replace(re,r)
for o,r of @i18nR[client.lang]
line=line.replace(r.regex, r.text)
@stoc_send client, 'CHAT', {
player: player
msg: line
......
......@@ -14,9 +14,36 @@
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 对异步支持不是特别完善,因此不会有很多异步优化
this.helper = new YGOProMessagesHelper();
this.helper = new YGOProMessagesHelper(9000);
this.structs = this.helper.structs;
......@@ -69,7 +96,7 @@
//util
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) {
console.log("err stoc_send_chat");
return;
......@@ -80,11 +107,10 @@
if (player >= 10) {
line = "[Server]: " + line;
}
ref1 = this.i18ns[client.lang];
ref1 = this.i18nR[client.lang];
for (o in ref1) {
r = ref1[o];
re = new RegExp("\\$\\{" + o + "\\}", 'g');
line = line.replace(re, r);
line = line.replace(r.regex, r.text);
}
this.stoc_send(client, 'CHAT', {
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