Commit 70ef0ba3 authored by nanahira's avatar nanahira

Merge branch 'master' into databasen

parents 693361fd d6690872
......@@ -8,12 +8,17 @@ password.json
config.*.json
config.user.bak
ygopro-7210srv
ygopro-222DIY
ygopro-2pick
/bak
/config
/ygopro
/windbot
/decks
/decks_save*
/deck_log*
/replays
/node_modules
/ssl
......@@ -35,3 +40,8 @@ ehthumbs.db
Desktop.ini
$RECYCLE.BIN/
.DS_Store
*.csv
/lflist.conf
config.user.bak
......@@ -27,20 +27,20 @@ build_lite:
- docker build --pull --no-cache -f ./Dockerfile.lite -t $CONTAINER_TEST_IMAGE_LITE .
- docker push $CONTAINER_TEST_IMAGE_LITE
upload_stuff_to_minio:
stage: deploy
tags:
- linux
image: $CONTAINER_TEST_IMAGE
script:
- apt update ; apt -y install python3-pip
- pip3 install -U -i https://mirrors.aliyun.com/pypi/simple/ awscli
- cd /ygopro-server
- mkdir /dist
- tar zcfv /dist/ygopro-server.tar.gz ./*
- aws s3 --endpoint=https://minio.mycard.moe:9000 cp /dist/ygopro-server.tar.gz s3://mycard/srvpro/ygopro-server.tar.gz
only:
- master
#upload_stuff_to_minio:
# stage: deploy
# tags:
# - linux
# image: $CONTAINER_TEST_IMAGE
# script:
# - apt update ; apt -y install python3-pip
# - pip3 install -U -i https://mirrors.aliyun.com/pypi/simple/ awscli
# - cd /ygopro-server
# - mkdir /dist
# - tar zcfv /dist/ygopro-server.tar.gz ./*
# - aws s3 --endpoint=https://minio.mycard.moe:9000 cp /dist/ygopro-server.tar.gz s3://mycard/srvpro/ygopro-server.tar.gz
# only:
# - master
deploy_latest:
stage: deploy
......
......@@ -15,7 +15,7 @@ RUN npm ci && \
mkdir config decks replays logs /redis
# ygopro
RUN git clone --branch=server --recursive --depth=1 https://github.com/moecube/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 - && \
......@@ -30,7 +30,7 @@ RUN git clone --branch=server --recursive --depth=1 https://github.com/moecube/y
ls gframe | sed '/game.cpp/d' | xargs -I {} rm -rf gframe/{}
# windbot
RUN git clone --depth=1 https://github.com/moecube/windbot /tmp/windbot && \
RUN git clone --depth=1 https://github.com/purerosefallen/windbot /tmp/windbot && \
cd /tmp/windbot && \
xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \
mv /tmp/windbot/bin/Release /ygopro-server/windbot && \
......
......@@ -12,7 +12,7 @@ WORKDIR /ygopro-server
RUN npm ci && \
mkdir config decks replays logs
RUN git clone --branch=server --recursive --depth=1 https://github.com/moecube/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-alpha13/premake-5.0.0-alpha13-linux.tar.gz | tar zfx - && \
......
......@@ -35,11 +35,11 @@
* 安装修改后的YGOPro服务端:https://github.com/moecube/ygopro/tree/server
* `node ygopro-server.js`即可运行
* 简易的控制台在 http://srvpro.ygo233.com/dashboard.html 或 http://srvpro-cn.ygo233.com/dashboard.html
* 使用本项目的Docker镜像: https://hub.docker.com/r/mycard/ygopro-server/
* 使用本项目的Docker镜像: https://hub.docker.com/r/nanahira/ygopro-server/
* 镜像标签
* `mycard/ygopro-server:latest`: 完整镜像
* `mycard/ygopro-server:lite`: 基本镜像,云录像和人机对战功能需要配合`redis``nanahira/windbot`这两个镜像使用。
* `nanahira/ygopro-server:latest`: 完整镜像
* `nanahira/ygopro-server:lite`: 基本镜像,云录像和人机对战功能需要配合`redis``nanahira/windbot`这两个镜像使用。
* 端口
* `7911`: YGOPro端口
......
......@@ -23,6 +23,7 @@
"update": "请更新游戏版本",
"stop": false,
"side_timeout": false,
"tag_duel_surrender": true,
"replay_delay": true,
"hide_name": false,
"display_watchers": false,
......@@ -61,12 +62,23 @@
},
"tips": {
"enabled": true,
"get": false
"split_zh": false,
"get": false,
"get_zh": false
},
"dialogues": {
"enabled": true,
"get_custom": "http://purerosefallen.github.io/ygopro-tips/dialogues-222.json",
"get": "http://mercury233.me/ygosrv233/dialogues.json"
},
"words": {
"enabled": true,
"get": false
},
"vip": {
"enabled": false,
"generate_count": 500
},
"random_duel": {
"enabled": true,
"default_type": "S",
......@@ -105,7 +117,8 @@
"my_ip": "127.0.0.1"
},
"chat_color": {
"enabled": false
"enabled": false,
"restrict_to_vip": false
},
"retry_handle": {
"enabled": true,
......
......@@ -11,7 +11,19 @@
"tips": [
"欢迎来到本服务器",
"本服务器使用萌卡代码搭建"
]
],
"tips_zh": []
},
"words": {
"file": "./config/words.json",
"words": {
"test1": [
"test_word_1"
],
"test2": [
"test_word_2"
]
}
},
"dialogues": {
"file": "./config/dialogues.json",
......@@ -22,6 +34,14 @@
"58481572": [
"我们来做朋友吧!"
]
},
"dialogues_custom": {
"37564303": [
"泡沫君のようだ\n触れて壊さぬように\n刹那哀のまほろば\n見守るよ"
],
"37564765": [
"キラキラひかる空\n二つ並ぶ白い雲\nスカートなびかせて\n裾を掴む影ぼうし"
]
}
},
"duel_log": {
......@@ -32,6 +52,20 @@
"file": "./config/chat_color.json",
"save_list": {}
},
"vip_info": {
"file": "./config/vip_info.json",
"cdkeys": {
"365": [],
"180": [],
"90": [],
"30": [],
"15": [],
"7": [],
"3": [],
"1": []
},
"players": {}
},
"users": {
"file": "./config/admin_user.json",
"permission_examples": {
......@@ -49,7 +83,8 @@
"kick_user": true,
"start_death": true,
"pre_dashboard": true,
"update_dashboard": true
"update_dashboard": true,
"vip": true
},
"judge": {
"get_rooms": true,
......
......@@ -89,6 +89,14 @@
"chat_order_tip": "/tip show a tip",
"chat_order_chatcolor_1": "/color show the current chat color, /color colorname set the chat color",
"chat_order_chatcolor_2": "/color default restore the default chat color, /color help list all available color",
"chat_order_vip": "/vip to view your supporter info, /vip help to view the help of supporter",
"chat_order_vip_help": "/vip help to show this list",
"chat_order_vip_status": "/vip status to view your supporter info",
"chat_order_vip_buy": "/vip buy YOUR_KEY to become a supporter",
"chat_order_vip_password": "/vip password NEW_PASSWORD to change password",
"chat_order_vip_dialogues": "/vip dialogues CARD_CODE DIALOGUE to set a dialogue for a specific card",
"chat_order_vip_words": "/vip words WORD to set your word when joining in the server",
"chat_order_vip_victory": "/vip victory WORD to set your word when you win a duel",
"room_name": "Room name is",
"banned_chat_tip": "You are banned from chatting.",
"banned_duel_tip": "You are banned from the random duel system for sending inappropriate messages.",
......@@ -106,6 +114,8 @@
"afk_warn_part1": "no opreation too long, will be disconnected after ",
"afk_warn_part2": " seconds",
"surrender_confirm": "Are you sure? Enter /surrender again to confirm.",
"surrender_confirm_tag": "Your partner started a surrender request, click Surrender Button or type /surrender to confirm.",
"surrender_confirm_sent": "Surrender request sent, waiting for partner to confirm.",
"surrender_canceled": "Surrender canceled.",
"surrender_denied": "Please don't surrender in the first 2 turns.",
"unwelcome_warn_part1": "If you keep doing ",
......@@ -161,6 +171,28 @@
"challonge_match_already_finished": "Your current match was already finished. Please call the judge for any help.",
"challonge_match_created": "A room for match only is created. Your opponent will join in automatically.",
"challonge_player_already_in": "Please do not enter the room you are already in.",
"vip_remain_part1": "Your supporter identity will be expired at ",
"vip_remain_part2": ". Thanks for your support.",
"vip_remain": "You have already been a supporter. Welcome back!",
"vip_not_bought": "You are not a supporter yet. enter /vip buy KEY to become one.",
"vip_expired_part1": "Your supporter identity have been expired at ",
"vip_expired_part2": ". Welcome to support again.",
"vip_account_existed": "Your username has already taken by other players. Please use another username to support.",
"vip_key_not_found": "Key not found.",
"vip_success_new_part1": "Support success. Use ",
"vip_success_new_part2": " as your name to get the supporter goodies. Thanks for your support.",
"vip_success_renew": "Support success. Thanks again for your support.",
"vip_invalid_card_code": "Invalid card code.",
"vip_cleared_dialogues_part1": "Deleted the dialogue for ",
"vip_cleared_dialogues_part2": ".",
"vip_set_dialogues_part1": "Dialogue for ",
"vip_set_dialogues_part2": " have been set.",
"vip_cleared_words": "Your join word have been deleted.",
"vip_set_words": "Your join word have been set.",
"vip_cleared_victory": "Your victory word have been deleted.",
"vip_set_victory": "Your victory word have been set.",
"vip_password_changed": "Password changed.",
"vip_player_name_too_long": "Your username or password is too long to log in. Please change your username and try again.",
"replay_hint_part1": "Sending the replay of the duel number ",
"replay_hint_part2": ".",
"arena_wait_hint": "If you opponent does not appear within 25 seconds, you may quit without any penalty.",
......@@ -407,6 +439,14 @@
"chat_order_tip": "/tip 显示一条提示",
"chat_order_chatcolor_1": "/color 查看自己的聊天文字颜色,/color 颜色名 设定自己的聊天文字颜色",
"chat_order_chatcolor_2": "/color default 恢复默认聊天字体颜色,/color help 查看所有可用的颜色",
"chat_order_vip": "/vip 查看捐助信息,/vip help 显示捐助指令帮助",
"chat_order_vip_help": "/vip help 显示此帮助",
"chat_order_vip_status": "/vip status 查看自己的捐助信息",
"chat_order_vip_buy": "/vip buy 卡密 获取捐助特权",
"chat_order_vip_password": "/vip password 新密码 修改自己的密码",
"chat_order_vip_dialogues": "/vip dialogues 卡号 台词 设置特定卡的召唤台词",
"chat_order_vip_words": "/vip words 台词 设置自己的进场台词",
"chat_order_vip_victory": "/vip victory 台词 设置自己的胜利台词",
"room_name": "您当前的房间名是",
"banned_chat_tip": "您已被禁言!",
"banned_duel_tip": "您的发言存在严重不适当的内容,禁止您使用随机对战功能!",
......@@ -424,6 +464,8 @@
"afk_warn_part1": "已经很久没有操作了,若继续挂机,将于",
"afk_warn_part2": "秒后被请出房间",
"surrender_confirm": "确实要投降吗?再次输入 /投降 以确认。",
"surrender_confirm_tag": "您的队友发起了投降请求,点击投降按钮或输入 /投降 以确认。",
"surrender_confirm_sent": "已发起投降请求,请等待队友确认。",
"surrender_canceled": "已取消投降,加油!",
"surrender_denied": "为保证双方玩家的游戏体验,随机对战中3回合后才能投降。",
"unwelcome_warn_part1": "如果您经常",
......@@ -479,6 +521,28 @@
"challonge_match_already_finished": "你在当前轮次的比赛已经结束,如需重赛,请联系裁判。",
"challonge_match_created": "已建立比赛专用房间,将会自动匹配你的对手。",
"challonge_player_already_in": "请不要重复加入比赛房间。",
"vip_remain_part1": "你的捐助者特权将在 ",
"vip_remain_part2": " 时到期。感谢您的支持。",
"vip_remain": "尊敬的捐助者,欢迎回来。",
"vip_not_bought": "你还未成为捐助者。输入 /vip buy 卡密 进行捐助。",
"vip_expired_part1": "你的捐助者特权已在 ",
"vip_expired_part2": " 时到期。欢迎再次捐助。",
"vip_account_existed": "你的用户名已被其他人使用,请更换用户名进行捐助。",
"vip_key_not_found": "卡密不存在。",
"vip_success_new_part1": "捐助成功。进房时输入 ",
"vip_success_new_part2": " 即可享受捐助特权。感谢您对服务器的支持。",
"vip_success_renew": "续费成功。感谢您对服务器的再次支持。",
"vip_invalid_card_code": "非法卡号。",
"vip_cleared_dialogues_part1": "已删除 ",
"vip_cleared_dialogues_part2": " 的召唤台词。",
"vip_set_dialogues_part1": "已为 ",
"vip_set_dialogues_part2": " 设置召唤台词。",
"vip_cleared_words": "已删除进场台词。",
"vip_set_words": "已设置进场台词。",
"vip_cleared_victory": "已删除胜利台词。",
"vip_set_victory": "已设置胜利台词。",
"vip_password_changed": "密码修改成功。",
"vip_player_name_too_long": "你的用户名或设置的密码太长,使用此用户名可能会无法登陆。请更换用户名重试。",
"replay_hint_part1": "正在发送第",
"replay_hint_part2": "局决斗的录像。",
"arena_wait_hint": "若对手在25秒内不进入游戏,您退房时不会进行扣分。",
......
/*
ygopro-draw.js
get card usage from decks
Author: Nanahira
License: MIT
generate a lflist.conf for drafts.
the config file is at ./config/draw.json, which should be:
{
"dbfile": "ygopro/cards.cdb",
"lflist": "ygopro/lflist.conf",
"list": "2018.7",
"main": 600,
"extra": 300,
"output": "./lflist.conf"
"output_plain": "./pool_plain.txt"
}
*/
var sqlite3 = require('sqlite3').verbose();
var fs = require('fs');
var loadJSON = require('load-json-file').sync;
var config = loadJSON('./config/draw.json');
var constants = loadJSON('./data/constants.json');
var ALL_MAIN_CARDS={};
var ALL_EXTRA_CARDS={};
var CARD_RESULT={};
var CARD_RESULT_PLAIN=[[], [], [], []];
var LFLIST={"unknown": []};
var MAIN_POOL=[];
var EXTRA_POOL=[];
function load_database(callback) {
var db=new sqlite3.Database(config.dbfile);
db.each("select * from datas,texts where datas.id=texts.id", function (err,result) {
if (err) {
console.log(config.dbfile + ":" + err);
return;
}
else {
if ((result.type & constants.TYPES.TYPE_TOKEN) || result.alias) {
return;
}
CARD_RESULT[result.id] = 0;
if((result.type & constants.TYPES.TYPE_FUSION) || (result.type & constants.TYPES.TYPE_SYNCHRO) || (result.type & constants.TYPES.TYPE_XYZ) || (result.type & constants.TYPES.TYPE_LINK)) {
ALL_EXTRA_CARDS[result.id] = 3;
} else {
ALL_MAIN_CARDS[result.id] = 3;
}
}
}, callback);
}
function load_lflist() {
var raw = fs.readFileSync(config.lflist, 'utf8').split(/\n/g);
var current_list = "unknown";
for(var i in raw) {
var line = raw[i];
if(line.match(/!(.+)/)) {
current_list = line.match(/!(.+)/)[1];
if (!LFLIST[current_list]) {
LFLIST[current_list] = {};
}
} else if (line.match(/(\d+) 0/)) {
LFLIST[current_list][parseInt(line.match(/(\d+) 0/)[1])] = 0;
} else if (line.match(/(\d+) 1/)) {
LFLIST[current_list][parseInt(line.match(/(\d+) 1/)[1])] = 1;
} else if (line.match(/(\d+) 2/)) {
LFLIST[current_list][parseInt(line.match(/(\d+) 2/)[1])] = 2;
}
}
if (LFLIST[config.list]) {
for(var code in LFLIST[config.list]) {
count = LFLIST[config.list][code];
if(ALL_MAIN_CARDS[code] === 3) {
ALL_MAIN_CARDS[code] = count;
} else if (ALL_EXTRA_CARDS[code] === 3) {
ALL_EXTRA_CARDS[code] = count;
}
}
}
generate_pool();
}
function generate_pool() {
for (var code in ALL_MAIN_CARDS) {
var count = ALL_MAIN_CARDS[code];
for (var i = 0; i < count; ++i) {
MAIN_POOL.push(code);
}
}
for (var code in ALL_EXTRA_CARDS) {
var count = ALL_EXTRA_CARDS[code];
for (var i = 0; i < count; ++i) {
EXTRA_POOL.push(code);
}
}
pick_cards();
}
function pick_cards() {
for (var i = 0; i < config.main; ++i) {
var l = MAIN_POOL.length;
if (!l) {break;}
var index = Math.floor(Math.random() * l);
var code = MAIN_POOL[index];
if(CARD_RESULT[code] < 3) {
CARD_RESULT[code]++;
}
MAIN_POOL.splice(index, 1);
}
for (var i = 0; i < config.extra; ++i) {
var l = EXTRA_POOL.length;
if (!l) {break;}
var index = Math.floor(Math.random() * l);
var code = EXTRA_POOL[index];
if(CARD_RESULT[code] < 3) {
CARD_RESULT[code]++;
}
EXTRA_POOL.splice(index, 1);
}
output();
}
function output() {
var op = "#[Random]\n\n!Random\n";
var op_plain = "";
for (var code in CARD_RESULT) {
op = op + code + " " + CARD_RESULT[code] + "\n";
if(CARD_RESULT[code] > 0) {
CARD_RESULT_PLAIN[CARD_RESULT[code]].push(code);
}
}
for (var i = 1; i < 4; ++i) {
for (var j in CARD_RESULT_PLAIN[i]) {
const code = CARD_RESULT_PLAIN[i][j];
op_plain = op_plain + code + " " + i + "\n";
}
}
fs.writeFile(config.output, op, 'utf-8', function(err) {
if (err) {
console.log(err);
}
});
console.log(op_plain);
}
load_database(load_lflist);
\ No newline at end of file
/*
ygopro-generate-result.js
ygopro tournament result generator
Author: Yuzurisa
License: MIT
Will generate the tournament result in a specific format.
*/
var output_path = "./config"
if (process.argv[2])
output_path = process.argv[2];
const loadJSON = require('load-json-file').sync;
const fs = require('fs');
const settings = loadJSON('./config/config.json');
const challonge_config = settings.modules.challonge;
if (challonge_config.enabled) {
challonge = require('challonge').createClient({
apiKey: challonge_config.api_key
});
} else {
console.error("Challonge is not enabled.");
return 1;
}
var name_list = {};
var results = {};
console.log("Requesting player datas from Challonge.");
challonge.participants.index({
id: challonge_config.tournament_id,
callback: (error, data) => {
if (error || !data) {
console.error(error);
return;
}
for (var k in data) {
const player = data[k];
if (!player || !player.participant) {
continue;
}
const player_info = player.participant;
const name = player_info.name;
const id = player_info.id;
name_list[id] = name;
}
console.log("Requesting match datas from Challonge.");
//for (var i = 1; i <=)
challonge.matches.index({
id: challonge_config.tournament_id,
callback: (error, data) => {
if (error || !data) {
console.error(error);
return;
}
for (var k in data) {
const match = data[k];
if (!match || !match.match) {
continue;
}
const match_info = match.match;
if (match_info.state != "complete") {
continue;
}
const sign = match_info.identifier;
const round = match_info.round;
const scores = match_info.scoresCsv;
const scores_data = scores.split("-")
if (!scores_data || scores_data.length != 2)
continue;
const player1 = match_info.player1Id;
const player2 = match_info.player2Id;
const match_txt = "[" + sign + "]组:\n [1号]" + name_list[player1] + " " + scores_data[0] + "\n [2号]" + name_list[player2] + " " + scores_data[1] + "\n";
if (!results[round])
results[round] = [];
results[round].push(match_txt);
}
console.log("Request completed. Outputing data.")
var player_text = "";
for (var k in name_list) {
player_text = player_text + name_list[k] + "\n";
}
fs.writeFileSync(output_path + "/player_list.txt", player_text);
for (var k in results) {
const round_data = results[k];
var text = "";
for (var k1 in round_data) {
text = text + round_data[k1];
}
fs.writeFileSync(output_path + "/match_" + k + ".txt", text);
}
console.log("Finished.")
}
})
}
})
......@@ -217,14 +217,14 @@ var writeToFile = function(message, callback) {
_async.auto({
write: (done) => {
fs.writeFile(config.html_path + config.html_filename, fileContent, done)
},
}/*,
copy: ["write", (results, done) => {
if (!config.cdn.enabled) {
copyImages(done);
} else {
done();
}
}]
}]*/
}, (err) => {
if (!err) {
sendResponse("列表更新完成。");
......@@ -300,7 +300,10 @@ var pushDatas = function(callback) {
pushHTMLs(done);
}]
}, callback);
} else {
pushHTMLs(callback);
}
}
var pushHTMLs = function(callback) {
......
......@@ -47,6 +47,7 @@ moment.updateLocale('zh-cn', {
import_datas = global.import_datas = [
"abuse_count",
"ban_mc",
"vip",
"vpass",
"rag",
"rid",
......@@ -99,12 +100,20 @@ try
oldtips = {}
oldtips.file = './config/tips.json'
oldtips.tips = oldconfig.tips
oldtips.tips_zh = []
fs.writeFileSync(oldtips.file, JSON.stringify(oldtips, null, 2))
delete oldconfig.tips
if oldconfig.words
oldwords = {}
oldwords.file = './config/words.json'
oldwords.words = oldconfig.words
fs.writeFileSync(oldwords.file, JSON.stringify(oldwords, null, 2))
delete oldconfig.words
if oldconfig.dialogues
olddialogues = {}
olddialogues.file = './config/dialogues.json'
olddialogues.dialogues = oldconfig.dialogues
olddialogues.dialogues_custom = {}
fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2))
delete oldconfig.dialogues
if oldconfig.modules
......@@ -163,6 +172,85 @@ setting_change = global.setting_change = (settings, path, val, callback) ->
setting_save(settings, callback)
return
VIP_generate_cdkeys = global.VIP_generate_cdkeys = (key_type, count) ->
return false unless settings.modules.vip.enabled and vip_info.cdkeys[key_type]
for i in [0...count]
key = Math.floor(Math.random() * 10000000000000000).toString()
vip_info.cdkeys[key_type].push(key)
setting_save(vip_info)
log.info("keys generated", key_type, count, vip_info.cdkeys[key_type].length)
return true
CLIENT_use_cdkey = global.CLIENT_use_cdkey = (client, pkey) ->
return 0 unless settings.modules.vip.enabled and pkey
found_type = null
for type,keys of vip_info.cdkeys
for key in keys when pkey == key or pkey == (type + "D" + settings.port + ":" + key) # support web given format
found_type = parseInt(type)
index = _.indexOf(keys, key)
keys.splice(index, 1) unless index == -1
break
if found_type
break
if !found_type
return 0
if !vip_info.cdkeys[found_type].length
VIP_generate_cdkeys(found_type, settings.modules.vip.generate_count)
client.vip = true
new_vip = false
if vip_info.players[client.name]
current_date = moment()
if current_date.isSameOrBefore(vip_info.players[client.name].expire_date)
current_date = moment(vip_info.players[client.name].expire_date, 'YYYY-MM-DD HH:mm:ss')
vip_info.players[client.name].expire_date = current_date.add(found_type, 'd').format('YYYY-MM-DD HH:mm:ss')
else
if !client.vpass
client.vpass = Math.floor(Math.random() * 100000).toString()
vip_info.players[client.name] = {
password: client.vpass,
expire_date: moment().add(found_type, 'd').format('YYYY-MM-DD HH:mm:ss'),
dialogues: {}
}
new_vip = true
setting_save(vip_info)
return (if new_vip then 1 else 2)
CLIENT_check_vip = global.CLIENT_check_vip = (client) ->
if !settings.modules.vip.enabled
return false
if !vip_info.players[client.name]
return false
if vip_info.players[client.name].password != client.vpass
return false
return moment().isSameOrBefore(vip_info.players[client.name].expire_date)
CLIENT_send_vip_status = global.CLIENT_send_vip_status = (client, display) ->
if !settings.modules.vip.enabled
return false
if client.vip
if display
ygopro.stoc_send_chat(client, "${vip_remain_part1}" + vip_info.players[client.name].expire_date + "${vip_remain_part2}", ygopro.constants.COLORS.BABYBLUE)
else
ygopro.stoc_send_chat(client,"${vip_remain}" , ygopro.constants.COLORS.BABYBLUE)
else if !vip_info.players[client.name] or vip_info.players[client.name].password != client.vpass
ygopro.stoc_send_chat(client,"${vip_not_bought}" , ygopro.constants.COLORS.RED)
else
ygopro.stoc_send_chat(client, "${vip_expired_part1}" + vip_info.players[client.name].expire_date + "${vip_expired_part2}", ygopro.constants.COLORS.RED)
concat_name = global.concat_name = (name, num) ->
if !name[num]
return null
res = name[num]
temp = null
count = num + 1
while true
temp = name[count]
if !temp
break
res = res + " " + temp
count++
return res
# 读取配置
default_config = loadJSON('./data/default_config.json')
if fs.existsSync('./config/config.json')
......@@ -249,11 +337,22 @@ if imported
default_data = loadJSON('./data/default_data.json')
try
tips = global.tips = loadJSON('./config/tips.json')
if !tips.tips_zh
tips.tips_zh = []
setting_save(tips);
catch
tips = global.tips = default_data.tips
setting_save(tips)
try
words = global.words = loadJSON('./config/words.json')
catch
words = global.words = default_data.words
setting_save(words)
try
dialogues = global.dialogues = loadJSON('./config/dialogues.json')
if !dialogues.dialogues_custom
dialogues.dialogues_custom = {}
setting_save(dialogues);
catch
dialogues = global.dialogues = default_data.dialogues
setting_save(dialogues)
......@@ -272,6 +371,11 @@ try
catch
chat_color = global.chat_color = default_data.chat_color
setting_save(chat_color)
try
vip_info = global.vip_info = loadJSON('./config/vip_info.json')
catch
vip_info = global.vip_info = default_data.vip_info
setting_save(vip_info)
try
cppversion = parseInt(fs.readFileSync('ygopro/gframe/game.cpp', 'utf8').match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16')
......@@ -455,6 +559,10 @@ if settings.modules.challonge.enabled
if settings.modules.challonge.cache_ttl
setInterval(refresh_challonge_cache, settings.modules.challonge.cache_ttl)
if settings.modules.vip.enabled
for k,v of vip_info.cdkeys when v.length == 0
VIP_generate_cdkeys(k, settings.modules.vip.generate_count)
# 获取可用内存
memory_usage = global.memory_usage = 0
get_memory_usage = get_memory_usage = ()->
......@@ -1016,6 +1124,24 @@ CLIENT_heartbeat_register = global.CLIENT_heartbeat_register = (client, send) ->
CLIENT_is_banned_by_mc = global.CLIENT_is_banned_by_mc = (client) ->
return client.ban_mc and client.ban_mc.banned and moment().isBefore(client.ban_mc.until)
CLIENT_get_absolute_pos = global.CLIENT_get_absolute_pos = (client) ->
room = ROOM_all[client.rid]
if room.hostinfo.mode != 2 or client.pos > 3
return client.pos
else if client.pos < 2
return 0
else
return 1
CLIENT_get_partner = global.CLIENT_get_partner = (client) ->
room = ROOM_all[client.rid]
if room.hostinfo.mode != 2 or client.pos > 3
return client
if client.pos < 2
return room.dueling_players[1 - client.pos]
else
return room.dueling_players[5 - client.pos]
CLIENT_send_replays = global.CLIENT_send_replays = (client, room) ->
return false unless settings.modules.replay_delay and not (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) and room.replays.length and room.hostinfo.mode == 1 and !client.replays_sent and !client.closed
client.replays_sent = true
......@@ -1095,7 +1221,8 @@ class Room
else if name[0...3] == 'AI#'
@hostinfo.rule = 2
@hostinfo.lflist = -1
@hostinfo.time_limit = 999
@hostinfo.time_limit = 0
@hostinfo.no_check_deck = true
else if (param = name.match /^(\d)(\d)(T|F)(T|F)(T|F)(\d+),(\d+),(\d+)/i)
@hostinfo.rule = parseInt(param[1])
......@@ -1820,6 +1947,9 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server, datas)->
client.name = name
client.vpass = vpass
client.name_vpass = if vpass then name + "$" + vpass else name
#console.log client.name, client.vpass
if settings.modules.vip.enabled and CLIENT_check_vip(client)
client.vip = true
if not settings.modules.i18n.auto_pick or client.is_local
client.lang=settings.modules.i18n.default
......@@ -2030,6 +2160,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
client.setTimeout(300000) #连接后超时5分钟
client.rid = _.indexOf(ROOM_all, room)
client.is_post_watcher = true
if settings.modules.vip.enabled and client.vip and vip_info.players[client.name].words
for line in _.lines vip_info.players[client.name].words
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
else if settings.modules.words.enabled and words.words[client.name]
for line in _.lines words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
ygopro.stoc_send_chat_to_room(room, "#{client.name} ${watch_join}")
room.watchers.push client
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE)
......@@ -2213,6 +2349,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
#client.setTimeout(300000) #连接后超时5分钟
client.rid = _.indexOf(ROOM_all, room)
client.is_post_watcher = true
if settings.modules.vip.enabled and client.vip and vip_info.players[client.name].words
for line in _.lines vip_info.players[client.name].words
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
else if settings.modules.words.enabled and words.words[client.name]
for line in _.lines words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
ygopro.stoc_send_chat_to_room(room, "#{client.name} ${watch_join}")
room.watchers.push client
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE)
......@@ -2295,6 +2437,12 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
client.setTimeout(300000) #连接后超时5分钟
client.rid = _.indexOf(ROOM_all, room)
client.is_post_watcher = true
if settings.modules.vip.enabled and client.vip and vip_info.players[client.name].words
for line in _.lines vip_info.players[client.name].words
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
else if settings.modules.words.enabled and words.words[client.name]
for line in _.lines words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
ygopro.stoc_send_chat_to_room(room, "#{client.name} ${watch_join}")
room.watchers.push client
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE)
......@@ -2316,6 +2464,12 @@ ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server, datas)->
return unless room and !client.reconnecting
if !room.join_game_buffer
room.join_game_buffer = buffer
if settings.modules.vip.enabled and client.vip and vip_info.players[client.name].words
for line in _.lines vip_info.players[client.name].words
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
else if settings.modules.words.enabled and words.words[client.name]
for line in _.lines words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
if settings.modules.welcome
ygopro.stoc_send_chat(client, settings.modules.welcome, ygopro.constants.COLORS.GREEN)
if room.welcome
......@@ -2388,6 +2542,26 @@ ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server, datas)->
await return
# 登场台词
load_words = global.load_words = (callback) ->
request
url: settings.modules.words.get
json: true
, (error, response, body)->
if _.isString body
log.warn "words bad json", body
else if error or !body
log.warn 'words error', error, response
else
setting_change(words, "words", body)
log.info "words loaded", _.size words.words
if callback
callback(error, body)
return
return
if settings.modules.words.get
load_words()
load_dialogues = global.load_dialogues = (callback) ->
request
url: settings.modules.dialogues.get
......@@ -2405,9 +2579,29 @@ load_dialogues = global.load_dialogues = (callback) ->
return
await return
if settings.modules.dialogues.get
load_dialogues_custom = global.load_dialogues_custom = (callback) ->
request
url: settings.modules.dialogues.get_custom
json: true
, (error, response, body)->
if _.isString body
log.warn "custom dialogues bad json", body
else if error or !body
log.warn 'custom dialogues error', error, response
else
setting_change(dialogues, "dialogues_custom", body)
log.info "custom dialogues loaded", _.size dialogues.dialogues_custom
if callback
callback(error, body)
return
return
if settings.modules.dialogues.enabled and settings.modules.dialogues.get
load_dialogues()
if settings.modules.dialogues.enabled and settings.modules.dialogues.get_custom
load_dialogues_custom()
ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
room=ROOM_all[client.rid]
return unless room and !client.reconnecting
......@@ -2488,7 +2682,8 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
client.last_hint_msg = buffer
if ygopro.constants.MSG[msg] == 'NEW_TURN'
if client.pos == 0
r_player = buffer.readUInt8(1)
if client.pos == 0 and (r_player & 0x2) == 0
room.turn++
if room.recovering and room.recover_from_turn <= room.turn
room.finish_recover()
......@@ -2498,15 +2693,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
if room.dueling_players[0].lp != room.dueling_players[oppo_pos].lp and room.turn > 1
win_pos = if room.dueling_players[0].lp > room.dueling_players[oppo_pos].lp then 0 else oppo_pos
ygopro.stoc_send_chat_to_room(room, "${death_finish_part1}" + room.dueling_players[win_pos].name + "${death_finish_part2}", ygopro.constants.COLORS.BABYBLUE)
if room.hostinfo.mode == 2
room.finished_by_death = true
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END')
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END')
room.scores[room.dueling_players[oppo_pos - win_pos].name_vpass] = -1
CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1])
else
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
else
room.death = -1
ygopro.stoc_send_chat_to_room(room, "${death_remain_final}", ygopro.constants.COLORS.BABYBLUE)
......@@ -2523,15 +2710,7 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
if room.dueling_players[0].lp != room.dueling_players[oppo_pos].lp
win_pos = if room.dueling_players[0].lp > room.dueling_players[oppo_pos].lp then 0 else oppo_pos
ygopro.stoc_send_chat_to_room(room, "${death_finish_part1}" + room.dueling_players[win_pos].name + "${death_finish_part2}", ygopro.constants.COLORS.BABYBLUE)
if room.hostinfo.mode == 2
room.finished_by_death = true
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END')
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END')
room.scores[room.dueling_players[oppo_pos - win_pos].name_vpass] = -1
CLIENT_kick(room.dueling_players[oppo_pos - win_pos])
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1])
else
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER')
else
room.death = -1
ygopro.stoc_send_chat_to_room(room, "${death_remain_final}", ygopro.constants.COLORS.BABYBLUE)
......@@ -2561,6 +2740,12 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
if room.match_kill
room.match_kill = false
room.scores[room.winner_name] = 99
if settings.modules.vip.enabled and room.dueling_players[pos].vip and vip_info.players[room.dueling_players[pos].name].victory
for line in _.lines vip_info.players[room.dueling_players[pos].name].victory
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
else if room.hostinfo.mode == 2 and settings.modules.vip.enabled and room.dueling_players[pos + 1].vip and vip_info.players[room.dueling_players[pos + 1].name].victory
for line in _.lines vip_info.players[room.dueling_players[pos + 1].name].victory
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK)
if room.death
if settings.modules.http.quick_death_rule == 1 or settings.modules.http.quick_death_rule == 3
room.death = -1
......@@ -2680,13 +2865,28 @@ ygopro.stoc_follow 'GAME_MSG', true, (buffer, info, client, server, datas)->
delete room.long_resolve_chain
#登场台词
if settings.modules.dialogues.enabled and !room.recovering
if (settings.modules.dialogues.enabled or settings.modules.vip.enabled) and !room.recovering
if ygopro.constants.MSG[msg] == 'SUMMONING' or ygopro.constants.MSG[msg] == 'SPSUMMONING' or ygopro.constants.MSG[msg] == 'CHAINING'
card = buffer.readUInt32LE(1)
trigger_location = buffer.readUInt8(6)
if dialogues.dialogues[card] and (ygopro.constants.MSG[msg] != 'CHAINING' or (trigger_location & 0x8) and client.ready_trap)
for line in _.lines dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK)
act_pos = buffer.readUInt8(if ygopro.constants.MSG[msg] == 'CHAINING' then 9 else 5)
if !room.dueling_players[0].is_first
act_pos = 1 - act_pos
if room.hostinfo.mode == 2
act_pos = act_pos * 2
if ygopro.constants.MSG[msg] != 'CHAINING' or (trigger_location & 0x8) and client.ready_trap
if settings.modules.vip.enabled and room.dueling_players[act_pos].vip and vip_info.players[room.dueling_players[act_pos].name].dialogues[card]
for line in _.lines vip_info.players[room.dueling_players[act_pos].name].dialogues[card]
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK)
else if settings.modules.vip.enabled and room.hostinfo.mode == 2 and room.dueling_players[act_pos + 1].vip and vip_info.players[room.dueling_players[act_pos + 1].name].dialogues[card]
for line in _.lines vip_info.players[room.dueling_players[act_pos + 1].name].dialogues[card]
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK)
else if settings.modules.dialogues.enabled and dialogues.dialogues[card]
for line in _.lines dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK)
else if settings.modules.dialogues.enabled and dialogues.dialogues_custom[card]
for line in _.lines dialogues.dialogues_custom[card][Math.floor(Math.random() * dialogues.dialogues_custom[card].length)]
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK)
if ygopro.constants.MSG[msg] == 'POS_CHANGE'
loc = buffer.readUInt8(6)
ppos = buffer.readUInt8(8)
......@@ -2867,12 +3067,18 @@ wait_room_start_arena = (room)->
#tip
ygopro.stoc_send_random_tip = (client)->
if settings.modules.tips.enabled && tips.tips.length
ygopro.stoc_send_chat(client, "Tip: " + tips.tips[Math.floor(Math.random() * tips.tips.length)])
tip_type = "tips"
if settings.modules.tips.split_zh and tips.tips_zh.length and client.lang == "zh-cn"
tip_type = "tips_zh"
if settings.modules.tips.enabled && tips.tips.length && !client.is_local && !client.closed
ygopro.stoc_send_chat(client, "Tip: " + tips[tip_type][Math.floor(Math.random() * tips[tip_type].length)])
await return
ygopro.stoc_send_random_tip_to_room = (room)->
if settings.modules.tips.enabled && tips.tips.length
ygopro.stoc_send_chat_to_room(room, "Tip: " + tips.tips[Math.floor(Math.random() * tips.tips.length)])
for player in room.players when player and !player.is_local and !player.closed
ygopro.stoc_send_random_tip(player)
for player in room.watchers when player and !player.is_local and !player.closed
ygopro.stoc_send_random_tip(player)
await return
load_tips = global.load_tips = (callback)->
......@@ -2892,8 +3098,28 @@ load_tips = global.load_tips = (callback)->
return
await return
if settings.modules.tips.get
load_tips_zh = global.load_tips_zh = (callback)->
request
url: settings.modules.tips.get_zh
json: true
, (error, response, body)->
if _.isString body
log.warn "zh tips bad json", body
else if error or !body
log.warn 'zh tips error', error, response
else
setting_change(tips, "tips_zh", body)
log.info "zh tips loaded", tips.tips_zh.length
if callback
callback(error, body)
return
await return
if settings.modules.tips.enabled and settings.modules.tips.get
load_tips()
if settings.modules.tips.enabled and settings.modules.tips.get_zh
load_tips_zh()
if settings.modules.tips.enabled
setInterval ()->
for room in ROOM_all when room and room.established
ygopro.stoc_send_random_tip_to_room(room) if room.duel_stage == ygopro.constants.DUEL_STAGE.SIDING or room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN
......@@ -2976,11 +3202,20 @@ ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server, datas)->
ygopro.ctos_follow 'SURRENDER', true, (buffer, info, client, server, datas)->
room=ROOM_all[client.rid]
return unless room
if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN or room.hostinfo.mode == 2
if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN
return true
if room.random_type and room.turn < 3 and not client.flee_free and not settings.modules.test_mode.surrender_anytime and not (room.random_type=='M' and settings.modules.random_duel.record_match_scores)
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE)
return true
if room.hostinfo.mode == 2
if !settings.modules.tag_duel_surrender
return true
else if !client.surrend_confirm and !CLIENT_get_partner(client).closed and !CLIENT_get_partner(client).is_local
sur_player = CLIENT_get_partner(client)
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE)
sur_player.surrend_confirm = true
return true
await return false
report_to_big_brother = global.report_to_big_brother = (roomname, sender, ip, level, content, match) ->
......@@ -3013,16 +3248,23 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
cmd = msg.split(' ')
switch cmd[0]
when '/投降', '/surrender'
if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN or room.hostinfo.mode == 2
if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN or (room.hostinfo.mode==2 and !settings.modules.tag_duel_surrender)
return cancel
if room.random_type and room.turn < 3
if room.random_type and room.turn < 3 and !client.flee_free
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE)
return cancel
if client.surrend_confirm
ygopro.ctos_send(client.server, 'SURRENDER')
else
ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE)
client.surrend_confirm = true
sur_player = CLIENT_get_partner(client)
if sur_player.closed or sur_player.is_local
sur_player = client
if room.hostinfo.mode==2 and sur_player != client
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE)
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE)
else
ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE)
sur_player.surrend_confirm = true
when '/help'
ygopro.stoc_send_chat(client, "${chat_order_main}")
......@@ -3030,8 +3272,9 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
ygopro.stoc_send_chat(client, "${chat_order_roomname}") if !settings.modules.mycard.enabled
ygopro.stoc_send_chat(client, "${chat_order_windbot}") if settings.modules.windbot.enabled
ygopro.stoc_send_chat(client, "${chat_order_tip}") if settings.modules.tips.enabled
ygopro.stoc_send_chat(client, "${chat_order_chatcolor_1}") if settings.modules.chat_color.enabled
ygopro.stoc_send_chat(client, "${chat_order_chatcolor_2}") if settings.modules.chat_color.enabled
ygopro.stoc_send_chat(client, "${chat_order_chatcolor_1}") if settings.modules.chat_color.enabled and (!(settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip) or client.vip)
ygopro.stoc_send_chat(client, "${chat_order_chatcolor_2}") if settings.modules.chat_color.enabled and (!(settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip) or client.vip)
ygopro.stoc_send_chat(client, "${chat_order_vip}") if settings.modules.vip.enabled
when '/tip'
ygopro.stoc_send_random_tip(client) if settings.modules.tips.enabled
......@@ -3058,28 +3301,122 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
when '/color'
if settings.modules.chat_color.enabled
cip = CLIENT_get_authorize_key(client)
if cmsg = cmd[1]
if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip and !client.vip
CLIENT_send_vip_status(client)
else if cmsg = cmd[1]
if cmsg.toLowerCase() == "help"
ygopro.stoc_send_chat(client, "${show_color_list}", ygopro.constants.COLORS.BABYBLUE)
for cname,cvalue of ygopro.constants.COLORS when cvalue > 10
ygopro.stoc_send_chat(client, cname, cvalue)
else if cmsg.toLowerCase() == "default"
chat_color.save_list[cip] = false
if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip
delete vip_info.players[client.name].chat_color
setting_save(vip_info)
else
delete chat_color.save_list[cip]
setting_save(chat_color)
ygopro.stoc_send_chat(client, "${set_chat_color_default}", ygopro.constants.COLORS.BABYBLUE)
else
ccolor = cmsg.toUpperCase()
if ygopro.constants.COLORS[ccolor] and ygopro.constants.COLORS[ccolor] > 10 and ygopro.constants.COLORS[ccolor] < 20
chat_color.save_list[cip] = ccolor
if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip
vip_info.players[client.name].chat_color = ccolor
setting_save(vip_info)
else
chat_color.save_list[cip] = ccolor
setting_save(chat_color)
ygopro.stoc_send_chat(client, "${set_chat_color_part1}" + ccolor + "${set_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE)
else
ygopro.stoc_send_chat(client, "${color_not_found_part1}" + ccolor + "${color_not_found_part2}", ygopro.constants.COLORS.RED)
else
if color = chat_color.save_list[cip]
if color = (if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip then vip_info.players[client.name].chat_color else chat_color.save_list[cip])
ygopro.stoc_send_chat(client, "${get_chat_color_part1}" + color + "${get_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE)
else
ygopro.stoc_send_chat(client, "${get_chat_color_default}", ygopro.constants.COLORS.BABYBLUE)
when '/vip'
if settings.modules.vip.enabled
if name = cmd[1]
uname = name.toLowerCase()
switch uname
when 'help'
ygopro.stoc_send_chat(client, "${chat_order_vip_help}")
ygopro.stoc_send_chat(client, "${chat_order_vip_status}")
ygopro.stoc_send_chat(client, "${chat_order_vip_buy}")
ygopro.stoc_send_chat(client, "${chat_order_vip_password}")
ygopro.stoc_send_chat(client, "${chat_order_vip_dialogues}")
ygopro.stoc_send_chat(client, "${chat_order_vip_words}")
ygopro.stoc_send_chat(client, "${chat_order_vip_victory}")
when 'status'
CLIENT_send_vip_status(client, true)
when 'buy'
if vip_info.players[client.name] and vip_info.players[client.name].password != client.vpass
ygopro.stoc_send_chat(client, "${vip_account_existed}", ygopro.constants.COLORS.RED)
else if (!client.vpass and client.name.length > 13) or (client.vpass and (client.name.length + client.vpass.length) > 18)
ygopro.stoc_send_chat(client, "${vip_player_name_too_long}", ygopro.constants.COLORS.RED)
else
key = cmd[2]
buy_result = CLIENT_use_cdkey(client, key)
switch buy_result
when 0
ygopro.stoc_send_chat(client, "${vip_key_not_found}", ygopro.constants.COLORS.RED)
when 1
ygopro.stoc_send_chat(client, "${vip_success_new_part1}" + client.name + "$" + client.vpass + "${vip_success_new_part2}", ygopro.constants.COLORS.BABYBLUE)
when 2
ygopro.stoc_send_chat(client, "${vip_success_renew}", ygopro.constants.COLORS.BABYBLUE)
when 'dialogues'
if !client.vip
CLIENT_send_vip_status(client)
else
code = cmd[2]
word = concat_name(cmd, 3)
if !code or !parseInt(code)
ygopro.stoc_send_chat(client, "${vip_invalid_card_code}", ygopro.constants.COLORS.RED)
else if !word
delete vip_info.players[client.name].dialogues[parseInt(code)]
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_cleared_dialogues_part1}" + code + "${vip_cleared_dialogues_part2}", ygopro.constants.COLORS.BABYBLUE)
else
vip_info.players[client.name].dialogues[parseInt(code)] = word
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_set_dialogues_part1}" + code + "${vip_set_dialogues_part2}", ygopro.constants.COLORS.BABYBLUE)
when 'words'
if !client.vip
CLIENT_send_vip_status(client)
else
word = concat_name(cmd, 2)
if !word
delete vip_info.players[client.name].words
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_cleared_words}", ygopro.constants.COLORS.BABYBLUE)
else
vip_info.players[client.name].words = word
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_set_words}", ygopro.constants.COLORS.BABYBLUE)
when 'victory'
if !client.vip
CLIENT_send_vip_status(client)
else
word = concat_name(cmd, 2)
if !word
delete vip_info.players[client.name].victory
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_cleared_victory}", ygopro.constants.COLORS.BABYBLUE)
else
vip_info.players[client.name].victory = word
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_set_victory}", ygopro.constants.COLORS.BABYBLUE)
when 'password'
if !client.vip
CLIENT_send_vip_status(client)
else
word = cmd[2]
if word and (client.name.length + word.length) <= 18
vip_info.players[client.name].password = word
client.vpass = word
setting_save(vip_info)
ygopro.stoc_send_chat(client, "${vip_password_changed}", ygopro.constants.COLORS.BABYBLUE)
else
CLIENT_send_vip_status(client)
#when '/test'
# ygopro.stoc_send_hint_card_to_room(room, 2333365)
......@@ -3232,7 +3569,7 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)->
struct.set("sidec", 1)
struct.set("deckbuf", [4392470, 4392470])
ygopro.stoc_send_chat(client, "${deck_incorrect_reconnect}", ygopro.constants.COLORS.RED)
else if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.hostinfo.mode == 1 and settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.deck_check and fs.readdirSync(settings.modules.tournament_mode.deck_path).length
else if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.deck_check and fs.readdirSync(settings.modules.tournament_mode.deck_path).length
struct.set("mainc", 1)
struct.set("sidec", 1)
struct.set("deckbuf", [4392470, 4392470])
......@@ -3369,8 +3706,8 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server, datas)->
pid = 1 - pid
for player in room.players when player and player.pos == pid
tplayer = player
return unless tplayer
tcolor = chat_color.save_list[CLIENT_get_authorize_key(tplayer)]
return unless tplayer and (!(settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip) or tplayer.vip)
tcolor = if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip then vip_info.players[tplayer.name].chat_color else chat_color.save_list[CLIENT_get_authorize_key(tplayer)]
if tcolor
ygopro.stoc_send client, 'CHAT', {
player: ygopro.constants.COLORS[tcolor]
......@@ -3681,6 +4018,22 @@ if settings.modules.http
duellog = JSON.stringify duel_log.duel_log, null, 2
response.end(addCallback(u.query.callback, duellog))
else if u.pathname == '/api/getkeys' and settings.modules.vip.enabled
if !auth.auth(u.query.username, u.query.pass, "vip", "get_keys")
response.writeHead(200)
response.end(addCallback(u.query.callback, "Unauthorized."))
return
else if !u.query.keytype or !vip_info.cdkeys[u.query.keytype]
response.writeHead(200)
response.end(addCallback(u.query.callback, "Key type not found."))
return
else
response.writeHead(200)
ret_keys = ""
for key in vip_info.cdkeys[u.query.keytype]
ret_keys = ret_keys + u.query.keytype + "D" + settings.port + ":" + key + "\n"
response.end(addCallback(u.query.callback, ret_keys))
else if u.pathname == '/api/archive.zip' and settings.modules.tournament_mode.enabled
if !await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay_archive")
response.writeHead(403)
......@@ -3820,7 +4173,12 @@ if settings.modules.http
response.writeHead(200)
response.end(addCallback(u.query.callback, "['密码错误', 0]"))
return
load_tips((err)->
tasks = {
tips: load_tips
}
if settings.modules.tips.get_zh
tasks.tips_zh = load_tips_zh
_async.auto(tasks, (err)->
response.writeHead(200)
if(err)
response.end(addCallback(u.query.callback, "['tip fail', '" + settings.modules.tips.get + "']"))
......@@ -3833,7 +4191,12 @@ if settings.modules.http
response.writeHead(200)
response.end(addCallback(u.query.callback, "['密码错误', 0]"))
return
load_dialogues((err)->
tasks = {
dialogues: load_dialogues
}
if settings.modules.dialogues.get_custom
tasks.dialogues_custom = load_dialogues_custom
_async.auto(tasks, (err)->
response.writeHead(200)
if(err)
response.end(addCallback(u.query.callback, "['dialogues fail', '" + settings.modules.dialogues.get + "']"))
......@@ -3930,6 +4293,15 @@ if settings.modules.http
)
else if u.query.generatekey and settings.modules.vip.enabled
if !auth.auth(u.query.username, u.query.pass, "vip", "generate_keys")
response.writeHead(200)
response.end(addCallback(u.query.callback, "['密码错误', 0]"))
return
VIP_generate_cdkeys(u.query.generatekey, settings.modules.vip.generate_count)
response.writeHead(200)
response.end(addCallback(u.query.callback, "['Keys generated', '" + u.query.generatekey + "']"))
else
response.writeHead(400)
response.end()
......
// Generated by CoffeeScript 2.5.1
(function() {
// 标准库
var AthleticChecker, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, DataManager, Q, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, ROOM_connected_ip, ROOM_find_by_name, ROOM_find_by_pid, ROOM_find_by_port, ROOM_find_by_title, ROOM_find_or_create_ai, ROOM_find_or_create_by_name, ROOM_find_or_create_random, ROOM_kick, ROOM_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_oppentlist, ROOM_players_scores, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, _, _async, addCallback, athleticChecker, auth, axios, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_module_name, challonge_queue_callbacks, challonge_type, chat_color, config, cppversion, crypto, dataManager, date, deck_name_match, default_config, default_data, dialogues, disconnect_list, dns, duel_log, e, exec, execFile, fs, geoip, getSeedTimet, get_callback, get_memory_usage, http, http_server, https, https_server, import_datas, imported, is_challonge_requesting, j, l, len, len1, len2, len3, lflists, list, loadJSON, load_dialogues, load_tips, log, long_resolve_cards, m, memory_usage, merge, moment, n, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, options, os, path, pgClient, pg_client, pg_query, plugin_filename, plugin_list, plugin_path, qs, real_windbot_server_ip, ref, ref1, ref2, refresh_challonge_cache, release_disconnect, replaced_index, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, ygopro, zlib;
var AthleticChecker, CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, CLIENT_send_vip_status, CLIENT_use_cdkey, DataManager, Q, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_clear_disconnect, ROOM_connected_ip, ROOM_find_by_name, ROOM_find_by_pid, ROOM_find_by_port, ROOM_find_by_title, ROOM_find_or_create_ai, ROOM_find_or_create_by_name, ROOM_find_or_create_random, ROOM_kick, ROOM_player_flee, ROOM_player_get_score, ROOM_player_lose, ROOM_player_win, ROOM_players_oppentlist, ROOM_players_scores, ROOM_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, athleticChecker, auth, axios, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_module_name, challonge_queue_callbacks, challonge_type, chat_color, concat_name, config, cppversion, crypto, dataManager, date, deck_name_match, default_config, default_data, dialogues, disconnect_list, dns, duel_log, e, exec, execFile, fs, geoip, getSeedTimet, get_callback, get_memory_usage, http, http_server, https, https_server, import_datas, imported, is_challonge_requesting, j, k, l, len, len1, len2, len3, lflists, list, loadJSON, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, m, memory_usage, merge, moment, n, net, oldbadwords, oldconfig, olddialogues, oldduellog, oldtips, oldwords, options, os, path, pgClient, pg_client, pg_query, plugin_filename, plugin_list, plugin_path, qs, real_windbot_server_ip, ref, ref1, ref2, ref3, refresh_challonge_cache, release_disconnect, replaced_index, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, spawn_windbot, tips, url, users_cache, util, v, vip_info, wait_room_start, wait_room_start_arena, windbot_looplimit, windbot_process, windbots, words, ygopro, zlib;
net = require('net');
......@@ -68,7 +68,7 @@
}
});
import_datas = global.import_datas = ["abuse_count", "ban_mc", "vpass", "rag", "rid", "is_post_watcher", "retry_count", "name", "pass", "name_vpass", "is_first", "lp", "card_count", "is_host", "pos", "surrend_confirm", "kick_count", "deck_saved", "main", "side", "side_interval", "side_tcount", "selected_preduel", "last_game_msg", "last_game_msg_title", "last_hint_msg", "start_deckbuf", "challonge_info", "ready_trap", "join_time", "arena_quit_free", "replays_sent"];
import_datas = global.import_datas = ["abuse_count", "ban_mc", "vip", "vpass", "rag", "rid", "is_post_watcher", "retry_count", "name", "pass", "name_vpass", "is_first", "lp", "card_count", "is_host", "pos", "surrend_confirm", "kick_count", "deck_saved", "main", "side", "side_interval", "side_tcount", "selected_preduel", "last_game_msg", "last_game_msg_title", "last_hint_msg", "start_deckbuf", "challonge_info", "ready_trap", "join_time", "arena_quit_free", "replays_sent"];
merge = require('deepmerge');
......@@ -92,13 +92,22 @@
oldtips = {};
oldtips.file = './config/tips.json';
oldtips.tips = oldconfig.tips;
oldtips.tips_zh = [];
fs.writeFileSync(oldtips.file, JSON.stringify(oldtips, null, 2));
delete oldconfig.tips;
}
if (oldconfig.words) {
oldwords = {};
oldwords.file = './config/words.json';
oldwords.words = oldconfig.words;
fs.writeFileSync(oldwords.file, JSON.stringify(oldwords, null, 2));
delete oldconfig.words;
}
if (oldconfig.dialogues) {
olddialogues = {};
olddialogues.file = './config/dialogues.json';
olddialogues.dialogues = oldconfig.dialogues;
olddialogues.dialogues_custom = {};
fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2));
delete oldconfig.dialogues;
}
......@@ -179,6 +188,124 @@
setting_save(settings, callback);
};
VIP_generate_cdkeys = global.VIP_generate_cdkeys = function(key_type, count) {
var i, j, key, ref;
if (!(settings.modules.vip.enabled && vip_info.cdkeys[key_type])) {
return false;
}
for (i = j = 0, ref = count; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) {
key = Math.floor(Math.random() * 10000000000000000).toString();
vip_info.cdkeys[key_type].push(key);
}
setting_save(vip_info);
log.info("keys generated", key_type, count, vip_info.cdkeys[key_type].length);
return true;
};
CLIENT_use_cdkey = global.CLIENT_use_cdkey = function(client, pkey) {
var current_date, found_type, index, j, key, keys, len, new_vip, ref, type;
if (!(settings.modules.vip.enabled && pkey)) {
return 0;
}
found_type = null;
ref = vip_info.cdkeys;
for (type in ref) {
keys = ref[type];
// support web given format
for (j = 0, len = keys.length; j < len; j++) {
key = keys[j];
if (!(pkey === key || pkey === (type + "D" + settings.port + ":" + key))) {
continue;
}
found_type = parseInt(type);
index = _.indexOf(keys, key);
if (index !== -1) {
keys.splice(index, 1);
}
break;
}
if (found_type) {
break;
}
}
if (!found_type) {
return 0;
}
if (!vip_info.cdkeys[found_type].length) {
VIP_generate_cdkeys(found_type, settings.modules.vip.generate_count);
}
client.vip = true;
new_vip = false;
if (vip_info.players[client.name]) {
current_date = moment();
if (current_date.isSameOrBefore(vip_info.players[client.name].expire_date)) {
current_date = moment(vip_info.players[client.name].expire_date, 'YYYY-MM-DD HH:mm:ss');
}
vip_info.players[client.name].expire_date = current_date.add(found_type, 'd').format('YYYY-MM-DD HH:mm:ss');
} else {
if (!client.vpass) {
client.vpass = Math.floor(Math.random() * 100000).toString();
}
vip_info.players[client.name] = {
password: client.vpass,
expire_date: moment().add(found_type, 'd').format('YYYY-MM-DD HH:mm:ss'),
dialogues: {}
};
new_vip = true;
}
setting_save(vip_info);
return (new_vip ? 1 : 2);
};
CLIENT_check_vip = global.CLIENT_check_vip = function(client) {
if (!settings.modules.vip.enabled) {
return false;
}
if (!vip_info.players[client.name]) {
return false;
}
if (vip_info.players[client.name].password !== client.vpass) {
return false;
}
return moment().isSameOrBefore(vip_info.players[client.name].expire_date);
};
CLIENT_send_vip_status = global.CLIENT_send_vip_status = function(client, display) {
if (!settings.modules.vip.enabled) {
return false;
}
if (client.vip) {
if (display) {
return ygopro.stoc_send_chat(client, "${vip_remain_part1}" + vip_info.players[client.name].expire_date + "${vip_remain_part2}", ygopro.constants.COLORS.BABYBLUE);
} else {
return ygopro.stoc_send_chat(client, "${vip_remain}", ygopro.constants.COLORS.BABYBLUE);
}
} else if (!vip_info.players[client.name] || vip_info.players[client.name].password !== client.vpass) {
return ygopro.stoc_send_chat(client, "${vip_not_bought}", ygopro.constants.COLORS.RED);
} else {
return ygopro.stoc_send_chat(client, "${vip_expired_part1}" + vip_info.players[client.name].expire_date + "${vip_expired_part2}", ygopro.constants.COLORS.RED);
}
};
concat_name = global.concat_name = function(name, num) {
var count, res, temp;
if (!name[num]) {
return null;
}
res = name[num];
temp = null;
count = num + 1;
while (true) {
temp = name[count];
if (!temp) {
break;
}
res = res + " " + temp;
count++;
}
return res;
};
// 读取配置
default_config = loadJSON('./data/default_config.json');
......@@ -303,13 +430,28 @@
try {
tips = global.tips = loadJSON('./config/tips.json');
if (!tips.tips_zh) {
tips.tips_zh = [];
setting_save(tips);
}
} catch (error1) {
tips = global.tips = default_data.tips;
setting_save(tips);
}
try {
words = global.words = loadJSON('./config/words.json');
} catch (error1) {
words = global.words = default_data.words;
setting_save(words);
}
try {
dialogues = global.dialogues = loadJSON('./config/dialogues.json');
if (!dialogues.dialogues_custom) {
dialogues.dialogues_custom = {};
setting_save(dialogues);
}
} catch (error1) {
dialogues = global.dialogues = default_data.dialogues;
setting_save(dialogues);
......@@ -336,6 +478,13 @@
setting_save(chat_color);
}
try {
vip_info = global.vip_info = loadJSON('./config/vip_info.json');
} catch (error1) {
vip_info = global.vip_info = default_data.vip_info;
setting_save(vip_info);
}
try {
cppversion = parseInt(fs.readFileSync('ygopro/gframe/game.cpp', 'utf8').match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16');
setting_change(settings, "version", cppversion);
......@@ -594,6 +743,16 @@
}
}
if (settings.modules.vip.enabled) {
ref3 = vip_info.cdkeys;
for (k in ref3) {
v = ref3[k];
if (v.length === 0) {
VIP_generate_cdkeys(k, settings.modules.vip.generate_count);
}
}
}
// 获取可用内存
memory_usage = global.memory_usage = 0;
......@@ -636,7 +795,7 @@
// ban a user manually and permanently
ban_user = global.ban_user = async function(name) {
var ban, bans, len3, len4, len5, len6, n, o, p, player, playerType, q, ref3, ref4, room;
var ban, bans, len3, len4, len5, len6, n, o, p, player, playerType, q, ref4, ref5, room;
if (!settings.modules.mysql.enabled) {
throw "MySQL is not enabled";
}
......@@ -644,12 +803,12 @@
for (n = 0, len3 = ROOM_all.length; n < len3; n++) {
room = ROOM_all[n];
if (room && room.established) {
ref3 = ["players", "watchers"];
for (o = 0, len4 = ref3.length; o < len4; o++) {
playerType = ref3[o];
ref4 = room[playerType];
for (p = 0, len5 = ref4.length; p < len5; p++) {
player = ref4[p];
ref4 = ["players", "watchers"];
for (o = 0, len4 = ref4.length; o < len4; o++) {
playerType = ref4[o];
ref5 = room[playerType];
for (p = 0, len5 = ref5.length; p < len5; p++) {
player = ref5[p];
if (!(player.name === name || bans.find(ban(() => {
return player.ip === ban.ip;
})))) {
......@@ -954,13 +1113,13 @@
};
ROOM_unwelcome = global.ROOM_unwelcome = function(room, bad_player, reason) {
var len3, n, player, ref3;
var len3, n, player, ref4;
if (!room) {
return;
}
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player && player === bad_player) {
ygopro.stoc_send_chat(player, `\${unwelcome_warn_part1}${reason}\${unwelcome_warn_part2}`, ygopro.constants.COLORS.RED);
} else if (player && player.pos !== 7 && player !== bad_player) {
......@@ -1072,10 +1231,10 @@
};
CLIENT_import_data = global.CLIENT_import_data = function(client, old_client, room) {
var index, key, len3, len4, n, o, player, ref3;
ref3 = room.players;
for (index = n = 0, len3 = ref3.length; n < len3; index = ++n) {
player = ref3[index];
var index, key, len3, len4, n, o, player, ref4;
ref4 = room.players;
for (index = n = 0, len3 = ref4.length; n < len3; index = ++n) {
player = ref4[index];
if (player === old_client) {
room.players[index] = client;
break;
......@@ -1102,7 +1261,6 @@
};
SERVER_clear_disconnect = global.SERVER_clear_disconnect = function(server) {
var k, v;
if (!settings.modules.reconnect.enabled) {
return false;
}
......@@ -1118,7 +1276,6 @@
};
ROOM_clear_disconnect = global.ROOM_clear_disconnect = function(room_id) {
var k, v;
if (!settings.modules.reconnect.enabled) {
return false;
}
......@@ -1134,11 +1291,11 @@
};
CLIENT_is_player = global.CLIENT_is_player = function(client, room) {
var is_player, len3, n, player, ref3;
var is_player, len3, n, player, ref4;
is_player = false;
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (client === player) {
is_player = true;
break;
......@@ -1171,13 +1328,13 @@
};
CLIENT_get_kick_reconnect_target = global.CLIENT_get_kick_reconnect_target = function(client, deckbuf) {
var len3, len4, n, o, player, ref3, room;
var len3, len4, n, o, player, ref4, room;
for (n = 0, len3 = ROOM_all.length; n < len3; n++) {
room = ROOM_all[n];
if (room && room.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN && !room.windbot) {
ref3 = room.get_playing_player();
for (o = 0, len4 = ref3.length; o < len4; o++) {
player = ref3[o];
ref4 = room.get_playing_player();
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
if (!player.closed && player.name === client.name && (settings.modules.challonge.enabled || player.pass === client.pass) && (settings.modules.mycard.enabled || settings.modules.tournament_mode.enabled || player.ip === client.ip || (client.vpass && client.vpass === player.vpass)) && (!deckbuf || _.isEqual(player.start_deckbuf, deckbuf))) {
return player;
}
......@@ -1198,7 +1355,7 @@
};
CLIENT_send_pre_reconnect_info = global.CLIENT_send_pre_reconnect_info = function(client, room, old_client) {
var len3, n, player, ref3, req_pos;
var len3, n, player, ref4, req_pos;
ygopro.stoc_send_chat(client, "${pre_reconnecting_to_room}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send(client, 'JOIN_GAME', room.join_game_buffer);
req_pos = old_client.pos;
......@@ -1208,9 +1365,9 @@
ygopro.stoc_send(client, 'TYPE_CHANGE', {
type: req_pos
});
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
ygopro.stoc_send(client, 'HS_PLAYER_ENTER', {
name: player.name,
pos: player.pos
......@@ -1373,16 +1530,41 @@
return client.ban_mc && client.ban_mc.banned && moment().isBefore(client.ban_mc.until);
};
CLIENT_get_absolute_pos = global.CLIENT_get_absolute_pos = function(client) {
var room;
room = ROOM_all[client.rid];
if (room.hostinfo.mode !== 2 || client.pos > 3) {
return client.pos;
} else if (client.pos < 2) {
return 0;
} else {
return 1;
}
};
CLIENT_get_partner = global.CLIENT_get_partner = function(client) {
var room;
room = ROOM_all[client.rid];
if (room.hostinfo.mode !== 2 || client.pos > 3) {
return client;
}
if (client.pos < 2) {
return room.dueling_players[1 - client.pos];
} else {
return room.dueling_players[5 - client.pos];
}
};
CLIENT_send_replays = global.CLIENT_send_replays = function(client, room) {
var buffer, i, len3, n, ref3;
var buffer, i, len3, n, ref4;
if (!(settings.modules.replay_delay && !(settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) && room.replays.length && room.hostinfo.mode === 1 && !client.replays_sent && !client.closed)) {
return false;
}
client.replays_sent = true;
i = 0;
ref3 = room.replays;
for (n = 0, len3 = ref3.length; n < len3; n++) {
buffer = ref3[n];
ref4 = room.replays;
for (n = 0, len3 = ref4.length; n < len3; n++) {
buffer = ref4[n];
++i;
if (buffer) {
ygopro.stoc_send_chat(client, "${replay_hint_part1}" + i + "${replay_hint_part2}", ygopro.constants.COLORS.BABYBLUE);
......@@ -1406,9 +1588,9 @@
};
getSeedTimet = global.getSeedTimet = function(count) {
var curTime, i, n, offset, ref3, ret;
var curTime, i, n, offset, ref4, ret;
ret = [];
for (i = n = 0, ref3 = count; (0 <= ref3 ? n < ref3 : n > ref3); i = 0 <= ref3 ? ++n : --n) {
for (i = n = 0, ref4 = count; (0 <= ref4 ? n < ref4 : n > ref4); i = 0 <= ref4 ? ++n : --n) {
curTime = null;
while (!curTime || _.any(ret, function(time) {
return time === curTime.unix();
......@@ -1474,7 +1656,8 @@
} else if (name.slice(0, 3) === 'AI#') {
this.hostinfo.rule = 2;
this.hostinfo.lflist = -1;
this.hostinfo.time_limit = 999;
this.hostinfo.time_limit = 0;
this.hostinfo.no_check_deck = true;
} else if ((param = name.match(/^(\d)(\d)(T|F)(T|F)(T|F)(\d+),(\d+),(\d+)/i))) {
this.hostinfo.rule = parseInt(param[1]);
this.hostinfo.mode = parseInt(param[2]);
......@@ -1645,10 +1828,10 @@
this.port = parseInt(data);
_.each(this.players, (player) => {
player.server.connect(this.port, '127.0.0.1', function() {
var buffer, len3, p, ref3;
ref3 = player.pre_establish_buffers;
for (p = 0, len3 = ref3.length; p < len3; p++) {
buffer = ref3[p];
var buffer, len3, p, ref4;
ref4 = player.pre_establish_buffers;
for (p = 0, len3 = ref4.length; p < len3; p++) {
buffer = ref4[p];
player.server.write(buffer);
}
player.established = true;
......@@ -1679,15 +1862,15 @@
}
delete() {
var end_time, formatted_replays, index, len3, log_rep_id, n, name, player_datas, recorder_buffer, ref3, ref4, repbuf, replay_id, room_name, score, score_array, score_form;
var end_time, formatted_replays, index, len3, log_rep_id, n, name, player_datas, recorder_buffer, ref4, ref5, repbuf, replay_id, room_name, score, score_array, score_form;
if (this.deleted) {
return;
}
//log.info 'room-delete', this.name, ROOM_all.length
score_array = [];
ref3 = this.scores;
for (name in ref3) {
score = ref3[name];
ref4 = this.scores;
for (name in ref4) {
score = ref4[name];
score_form = {
name: name.split('$')[0],
score: score,
......@@ -1742,9 +1925,9 @@
score_array[1].score = -5;
}
formatted_replays = [];
ref4 = this.replays;
for (n = 0, len3 = ref4.length; n < len3; n++) {
repbuf = ref4[n];
ref5 = this.replays;
for (n = 0, len3 = ref5.length; n < len3; n++) {
repbuf = ref5[n];
if (repbuf) {
formatted_replays.push(repbuf.toString("base64"));
}
......@@ -1854,14 +2037,14 @@
}
get_disconnected_count() {
var found, len3, n, player, ref3;
var found, len3, n, player, ref4;
if (!settings.modules.reconnect.enabled) {
return 0;
}
found = 0;
ref3 = this.get_playing_player();
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = this.get_playing_player();
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player.closed) {
found++;
}
......@@ -1911,20 +2094,20 @@
}
send_replays() {
var len3, len4, n, o, player, ref3, ref4;
var len3, len4, n, o, player, ref4, ref5;
if (!(settings.modules.replay_delay && this.replays.length && this.hostinfo.mode === 1)) {
return false;
}
ref3 = this.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = this.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player) {
CLIENT_send_replays(player, this);
}
}
ref4 = this.watchers;
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
ref5 = this.watchers;
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player) {
CLIENT_send_replays(player, this);
}
......@@ -1967,10 +2150,10 @@
roomlist.update(this);
}
client.server.connect(this.port, '127.0.0.1', function() {
var buffer, len3, n, ref3;
ref3 = client.pre_establish_buffers;
for (n = 0, len3 = ref3.length; n < len3; n++) {
buffer = ref3[n];
var buffer, len3, n, ref4;
ref4 = client.pre_establish_buffers;
for (n = 0, len3 = ref4.length; n < len3; n++) {
buffer = ref4[n];
client.server.write(buffer);
}
client.established = true;
......@@ -1980,7 +2163,7 @@
}
disconnect(client, error) {
var index, left_name, len3, len4, n, o, player, ref3, ref4;
var index, left_name, len3, len4, n, o, player, ref4, ref5;
if (client.had_new_reconnection) {
return;
}
......@@ -1996,18 +2179,18 @@
//log.info(client.name, @duel_stage != ygopro.constants.DUEL_STAGE.BEGIN, @disconnector, @random_type, @players.length)
if (this.arena && this.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && this.disconnector !== 'server' && !this.arena_score_handled) {
if (settings.modules.arena_mode.punish_quit_before_match && this.players.length === 2 && !client.arena_quit_free) {
ref3 = this.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = this.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player.pos !== 7) {
this.scores[player.name_vpass] = 0;
}
}
this.scores[client.name_vpass] = -9;
} else {
ref4 = this.players;
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
ref5 = this.players;
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player.pos !== 7) {
this.scores[player.name_vpass] = -5;
}
......@@ -2132,23 +2315,23 @@
}
finish_recover(fail) {
var buffer, len3, n, player, ref3, results;
var buffer, len3, n, player, ref4, results;
if (fail) {
ygopro.stoc_send_chat_to_room(this, "${recover_fail}", ygopro.constants.COLORS.RED);
return this.termiate();
} else {
ygopro.stoc_send_chat_to_room(this, "${recover_success}", ygopro.constants.COLORS.BABYBLUE);
this.recovering = false;
ref3 = this.get_playing_player();
ref4 = this.get_playing_player();
results = [];
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
results.push((function() {
var len4, o, ref4, results1;
ref4 = this.recover_buffers[player.pos];
var len4, o, ref5, results1;
ref5 = this.recover_buffers[player.pos];
results1 = [];
for (o = 0, len4 = ref4.length; o < len4; o++) {
buffer = ref4[o];
for (o = 0, len4 = ref5.length; o < len4; o++) {
buffer = ref5[o];
results1.push(ygopro.stoc_send(player, "GAME_MSG", buffer));
}
return results1;
......@@ -2323,7 +2506,7 @@
// 客户端到服务端(ctos)协议分析
client.pre_establish_buffers = new Array();
client.on('data', async function(ctos_buffer) {
var bad_ip_count, buffer, ctos_filter, handle_data, len3, len4, len5, n, o, p, ref3, ref4, ref5, room;
var bad_ip_count, buffer, ctos_filter, handle_data, len3, len4, len5, n, o, p, ref4, ref5, ref6, room;
if (client.is_post_watcher) {
room = ROOM_all[client.rid];
if (room) {
......@@ -2344,9 +2527,9 @@
return;
}
}
ref3 = handle_data.datas;
for (n = 0, len3 = ref3.length; n < len3; n++) {
buffer = ref3[n];
ref4 = handle_data.datas;
for (n = 0, len3 = ref4.length; n < len3; n++) {
buffer = ref4[n];
room.watcher.write(buffer);
}
}
......@@ -2373,15 +2556,15 @@
return;
}
if (client.established) {
ref4 = handle_data.datas;
for (o = 0, len4 = ref4.length; o < len4; o++) {
buffer = ref4[o];
ref5 = handle_data.datas;
for (o = 0, len4 = ref5.length; o < len4; o++) {
buffer = ref5[o];
client.server.write(buffer);
}
} else {
ref5 = handle_data.datas;
for (p = 0, len5 = ref5.length; p < len5; p++) {
buffer = ref5[p];
ref6 = handle_data.datas;
for (p = 0, len5 = ref6.length; p < len5; p++) {
buffer = ref6[p];
client.pre_establish_buffers.push(buffer);
}
}
......@@ -2389,7 +2572,7 @@
});
// 服务端到客户端(stoc)
server.on('data', async function(stoc_buffer) {
var buffer, handle_data, len3, n, ref3;
var buffer, handle_data, len3, n, ref4;
handle_data = (await ygopro.helper.handleBuffer(stoc_buffer, "STOC", null, {
client: server.client,
server: server
......@@ -2402,9 +2585,9 @@
}
}
if (server.client && !server.client.closed) {
ref3 = handle_data.datas;
for (n = 0, len3 = ref3.length; n < len3; n++) {
buffer = ref3[n];
ref4 = handle_data.datas;
for (n = 0, len3 = ref4.length; n < len3; n++) {
buffer = ref4[n];
server.client.write(buffer);
}
}
......@@ -2475,6 +2658,10 @@
client.name = name;
client.vpass = vpass;
client.name_vpass = vpass ? name + "$" + vpass : name;
//console.log client.name, client.vpass
if (settings.modules.vip.enabled && CLIENT_check_vip(client)) {
client.vip = true;
}
if (!settings.modules.i18n.auto_pick || client.is_local) {
client.lang = settings.modules.i18n.default;
} else {
......@@ -2495,7 +2682,7 @@
});
ygopro.ctos_follow('JOIN_GAME', true, async function(buffer, info, client, server, datas) {
var available_logs, check_buffer_indentity, create_room_with_action, exactBan, index, len3, len4, len5, n, name, o, p, pre_room, recover_match, ref3, ref4, replay, replay_id, replays, room, struct;
var available_logs, check_buffer_indentity, create_room_with_action, exactBan, index, len3, len4, len5, len6, len7, line, n, name, o, p, pre_room, q, r, recover_match, ref4, ref5, ref6, ref7, replay, replay_id, replays, room, struct;
//log.info info
info.pass = info.pass.trim();
client.pass = info.pass;
......@@ -2573,15 +2760,15 @@
return;
}
check_buffer_indentity = function(buf) {
var checksum, i, o, ref3;
var checksum, i, o, ref4;
checksum = 0;
for (i = o = 0, ref3 = buf.length; (0 <= ref3 ? o < ref3 : o > ref3); i = 0 <= ref3 ? ++o : --o) {
for (i = o = 0, ref4 = buf.length; (0 <= ref4 ? o < ref4 : o > ref4); i = 0 <= ref4 ? ++o : --o) {
checksum += buf.readUInt8(i);
}
return (checksum & 0xFF) === 0;
};
create_room_with_action = async function(buffer, decrypted_buffer, match_permit) {
var action, len4, len5, name, o, opt1, opt2, opt3, options, p, player, ref3, ref4, room, room_title, title;
var action, len4, len5, len6, len7, line, name, o, opt1, opt2, opt3, options, p, player, q, r, ref4, ref5, ref6, ref7, room, room_title, title;
if (client.closed) {
return;
}
......@@ -2670,9 +2857,9 @@
}
room = (await ROOM_find_or_create_by_name('M#' + info.pass.slice(8)));
if (room) {
ref3 = room.get_playing_player();
for (o = 0, len4 = ref3.length; o < len4; o++) {
player = ref3[o];
ref4 = room.get_playing_player();
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
if (!(player && player.name === client.name)) {
continue;
}
......@@ -2708,12 +2895,25 @@
client.setTimeout(300000); //连接后超时5分钟
client.rid = _.indexOf(ROOM_all, room);
client.is_post_watcher = true;
if (settings.modules.vip.enabled && client.vip && vip_info.players[client.name].words) {
ref5 = _.lines(vip_info.players[client.name].words);
for (p = 0, len5 = ref5.length; p < len5; p++) {
line = ref5[p];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.words.enabled && words.words[client.name]) {
ref6 = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]);
for (q = 0, len6 = ref6.length; q < len6; q++) {
line = ref6[q];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
}
ygopro.stoc_send_chat_to_room(room, `${client.name} \${watch_join}`);
room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref4 = room.watcher_buffers;
for (p = 0, len5 = ref4.length; p < len5; p++) {
buffer = ref4[p];
ref7 = room.watcher_buffers;
for (r = 0, len7 = ref7.length; r < len7; r++) {
buffer = ref7[r];
client.write(buffer);
}
} else {
......@@ -2760,7 +2960,7 @@
});
},
get_user: function(done) {
var decrypted_buffer, i, id, len4, o, ref3, secret;
var decrypted_buffer, i, id, len4, o, ref4, secret;
if (client.closed) {
done();
return;
......@@ -2768,9 +2968,9 @@
if (id = users_cache[client.name]) {
secret = id % 65535 + 1;
decrypted_buffer = Buffer.allocUnsafe(6);
ref3 = [0, 2, 4];
for (o = 0, len4 = ref3.length; o < len4; o++) {
i = ref3[o];
ref4 = [0, 2, 4];
for (o = 0, len4 = ref4.length; o < len4; o++) {
i = ref4[o];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
}
if (check_buffer_indentity(decrypted_buffer)) {
......@@ -2792,14 +2992,14 @@
},
json: true
}, function(error, response, body) {
var len5, p, ref4;
var len5, p, ref5;
if (!error && body && body.user) {
users_cache[client.name] = body.user.id;
secret = body.user.id % 65535 + 1;
decrypted_buffer = Buffer.allocUnsafe(6);
ref4 = [0, 2, 4];
for (p = 0, len5 = ref4.length; p < len5; p++) {
i = ref4[p];
ref5 = [0, 2, 4];
for (p = 0, len5 = ref5.length; p < len5; p++) {
i = ref5[p];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
}
if (check_buffer_indentity(decrypted_buffer)) {
......@@ -2847,9 +3047,9 @@
ygopro.stoc_send_chat_to_room(room, `${client.name} \${watch_join}`);
room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref3 = room.watcher_buffers;
for (o = 0, len4 = ref3.length; o < len4; o++) {
buffer = ref3[o];
ref4 = room.watcher_buffers;
for (o = 0, len4 = ref4.length; o < len4; o++) {
buffer = ref4[o];
client.write(buffer);
}
} else {
......@@ -2871,7 +3071,7 @@
});
}
}, async function(err, datas) {
var create_room_name, found, k, len5, len6, match, p, player, q, ref4, ref5, ref6, ref7, user;
var create_room_name, found, len5, len6, len7, len8, line, match, p, player, q, r, ref10, ref5, ref6, ref7, ref8, ref9, s, user;
if (client.closed) {
return;
}
......@@ -2881,9 +3081,9 @@
return;
}
found = false;
ref4 = datas.participant_data;
for (k in ref4) {
user = ref4[k];
ref5 = datas.participant_data;
for (k in ref5) {
user = ref5[k];
if (user.participant && user.participant.name && deck_name_match(user.participant.name, client.name)) {
found = user.participant;
break;
......@@ -2895,9 +3095,9 @@
}
client.challonge_info = found;
found = false;
ref5 = datas.match_data;
for (k in ref5) {
match = ref5[k];
ref6 = datas.match_data;
for (k in ref6) {
match = ref6[k];
if (match && match.match && !match.match.winnerId && match.match.state !== "complete" && match.match.player1Id && match.match.player2Id && (match.match.player1Id === client.challonge_info.id || match.match.player2Id === client.challonge_info.id)) {
found = match.match;
break;
......@@ -2929,12 +3129,25 @@
//client.setTimeout(300000) #连接后超时5分钟
client.rid = _.indexOf(ROOM_all, room);
client.is_post_watcher = true;
if (settings.modules.vip.enabled && client.vip && vip_info.players[client.name].words) {
ref7 = _.lines(vip_info.players[client.name].words);
for (p = 0, len5 = ref7.length; p < len5; p++) {
line = ref7[p];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.words.enabled && words.words[client.name]) {
ref8 = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]);
for (q = 0, len6 = ref8.length; q < len6; q++) {
line = ref8[q];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
}
ygopro.stoc_send_chat_to_room(room, `${client.name} \${watch_join}`);
room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref6 = room.watcher_buffers;
for (p = 0, len5 = ref6.length; p < len5; p++) {
buffer = ref6[p];
ref9 = room.watcher_buffers;
for (r = 0, len7 = ref9.length; r < len7; r++) {
buffer = ref9[r];
client.write(buffer);
}
} else {
......@@ -2943,9 +3156,9 @@
} else if (room.hostinfo.no_watch && room.players.length >= (room.hostinfo.mode === 2 ? 4 : 2)) {
ygopro.stoc_die(client, "${watch_denied_room}");
} else {
ref7 = room.get_playing_player();
for (q = 0, len6 = ref7.length; q < len6; q++) {
player = ref7[q];
ref10 = room.get_playing_player();
for (s = 0, len8 = ref10.length; s < len8; s++) {
player = ref10[s];
if (!(player && player !== client && player.challonge_info.id === client.challonge_info.id)) {
continue;
}
......@@ -3017,12 +3230,25 @@
client.setTimeout(300000); //连接后超时5分钟
client.rid = _.indexOf(ROOM_all, room);
client.is_post_watcher = true;
if (settings.modules.vip.enabled && client.vip && vip_info.players[client.name].words) {
ref5 = _.lines(vip_info.players[client.name].words);
for (p = 0, len5 = ref5.length; p < len5; p++) {
line = ref5[p];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.words.enabled && words.words[client.name]) {
ref6 = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]);
for (q = 0, len6 = ref6.length; q < len6; q++) {
line = ref6[q];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
}
ygopro.stoc_send_chat_to_room(room, `${client.name} \${watch_join}`);
room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref4 = room.watcher_buffers;
for (p = 0, len5 = ref4.length; p < len5; p++) {
buffer = ref4[p];
ref7 = room.watcher_buffers;
for (r = 0, len7 = ref7.length; r < len7; r++) {
buffer = ref7[r];
client.write(buffer);
}
} else {
......@@ -3039,7 +3265,7 @@
});
ygopro.stoc_follow('JOIN_GAME', false, async function(buffer, info, client, server, datas) {
var len3, n, player, recorder, ref3, room, watcher;
var len3, len4, len5, line, n, o, p, player, recorder, ref4, ref5, ref6, room, watcher;
//欢迎信息
room = ROOM_all[client.rid];
if (!(room && !client.reconnecting)) {
......@@ -3048,6 +3274,19 @@
if (!room.join_game_buffer) {
room.join_game_buffer = buffer;
}
if (settings.modules.vip.enabled && client.vip && vip_info.players[client.name].words) {
ref4 = _.lines(vip_info.players[client.name].words);
for (n = 0, len3 = ref4.length; n < len3; n++) {
line = ref4[n];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.words.enabled && words.words[client.name]) {
ref5 = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]);
for (o = 0, len4 = ref5.length; o < len4; o++) {
line = ref5[o];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
}
if (settings.modules.welcome) {
ygopro.stoc_send_chat(client, settings.modules.welcome, ygopro.constants.COLORS.GREEN);
}
......@@ -3077,9 +3316,9 @@
//client.score_shown = true
if (settings.modules.random_duel.record_match_scores && room.random_type === 'M') {
ygopro.stoc_send_chat_to_room(room, ROOM_player_get_score(client), ygopro.constants.COLORS.GREEN);
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref6 = room.players;
for (p = 0, len5 = ref6.length; p < len5; p++) {
player = ref6[p];
if (player.pos !== 7 && player !== client) {
ygopro.stoc_send_chat(client, ROOM_player_get_score(player), ygopro.constants.COLORS.GREEN);
}
......@@ -3117,15 +3356,15 @@
ygopro.ctos_send(watcher, 'HS_TOOBSERVER');
});
watcher.on('data', function(data) {
var len4, o, ref4, w;
var len6, q, ref7, w;
room = ROOM_all[client.rid];
if (!room) {
return;
}
room.watcher_buffers.push(data);
ref4 = room.watchers;
for (o = 0, len4 = ref4.length; o < len4; o++) {
w = ref4[o];
ref7 = room.watchers;
for (q = 0, len6 = ref7.length; q < len6; q++) {
w = ref7[q];
if (w) { //a WTF fix
w.write(data);
}
......@@ -3138,6 +3377,29 @@
});
// 登场台词
load_words = global.load_words = function(callback) {
request({
url: settings.modules.words.get,
json: true
}, function(error, response, body) {
if (_.isString(body)) {
log.warn("words bad json", body);
} else if (error || !body) {
log.warn('words error', error, response);
} else {
setting_change(words, "words", body);
log.info("words loaded", _.size(words.words));
}
if (callback) {
callback(error, body);
}
});
};
if (settings.modules.words.get) {
load_words();
}
load_dialogues = global.load_dialogues = async function(callback) {
request({
url: settings.modules.dialogues.get,
......@@ -3157,12 +3419,35 @@
});
};
if (settings.modules.dialogues.get) {
load_dialogues_custom = global.load_dialogues_custom = function(callback) {
request({
url: settings.modules.dialogues.get_custom,
json: true
}, function(error, response, body) {
if (_.isString(body)) {
log.warn("custom dialogues bad json", body);
} else if (error || !body) {
log.warn('custom dialogues error', error, response);
} else {
setting_change(dialogues, "dialogues_custom", body);
log.info("custom dialogues loaded", _.size(dialogues.dialogues_custom));
}
if (callback) {
callback(error, body);
}
});
};
if (settings.modules.dialogues.enabled && settings.modules.dialogues.get) {
load_dialogues();
}
if (settings.modules.dialogues.enabled && settings.modules.dialogues.get_custom) {
load_dialogues_custom();
}
ygopro.stoc_follow('GAME_MSG', true, async function(buffer, info, client, server, datas) {
var card, chain, check, count, cpos, deck_found, found, hint_type, i, id, len3, len4, len5, len6, limbo_found, line, loc, max_loop, msg, n, o, oppo_pos, p, phase, player, playertype, pos, ppos, q, r, reason, ref3, ref4, ref5, ref6, ref7, ref8, room, trigger_location, val, win_pos;
var act_pos, card, chain, check, count, cpos, deck_found, found, hint_type, i, id, len10, len11, len3, len4, len5, len6, len7, len8, len9, limbo_found, line, loc, max_loop, msg, n, o, oppo_pos, p, phase, player, playertype, pos, ppos, q, r, r_player, reason, ref10, ref11, ref12, ref13, ref14, ref4, ref5, ref6, ref7, ref8, ref9, room, s, t, trigger_location, val, win_pos, x, y, z;
room = ROOM_all[client.rid];
if (!(room && !client.reconnecting)) {
return;
......@@ -3262,7 +3547,8 @@
}
}
if (ygopro.constants.MSG[msg] === 'NEW_TURN') {
if (client.pos === 0) {
r_player = buffer.readUInt8(1);
if (client.pos === 0 && (r_player & 0x2) === 0) {
room.turn++;
if (room.recovering && room.recover_from_turn <= room.turn) {
room.finish_recover();
......@@ -3273,16 +3559,7 @@
if (room.dueling_players[0].lp !== room.dueling_players[oppo_pos].lp && room.turn > 1) {
win_pos = room.dueling_players[0].lp > room.dueling_players[oppo_pos].lp ? 0 : oppo_pos;
ygopro.stoc_send_chat_to_room(room, "${death_finish_part1}" + room.dueling_players[win_pos].name + "${death_finish_part2}", ygopro.constants.COLORS.BABYBLUE);
if (room.hostinfo.mode === 2) {
room.finished_by_death = true;
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END');
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END');
room.scores[room.dueling_players[oppo_pos - win_pos].name_vpass] = -1;
CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
} else {
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
}
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
} else {
room.death = -1;
ygopro.stoc_send_chat_to_room(room, "${death_remain_final}", ygopro.constants.COLORS.BABYBLUE);
......@@ -3304,16 +3581,7 @@
if (room.dueling_players[0].lp !== room.dueling_players[oppo_pos].lp) {
win_pos = room.dueling_players[0].lp > room.dueling_players[oppo_pos].lp ? 0 : oppo_pos;
ygopro.stoc_send_chat_to_room(room, "${death_finish_part1}" + room.dueling_players[win_pos].name + "${death_finish_part2}", ygopro.constants.COLORS.BABYBLUE);
if (room.hostinfo.mode === 2) {
room.finished_by_death = true;
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos], 'DUEL_END');
ygopro.stoc_send(room.dueling_players[oppo_pos - win_pos + 1], 'DUEL_END');
room.scores[room.dueling_players[oppo_pos - win_pos].name_vpass] = -1;
CLIENT_kick(room.dueling_players[oppo_pos - win_pos]);
CLIENT_kick(room.dueling_players[oppo_pos - win_pos + 1]);
} else {
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
}
ygopro.ctos_send(room.dueling_players[oppo_pos - win_pos].server, 'SURRENDER');
} else {
room.death = -1;
ygopro.stoc_send_chat_to_room(room, "${death_remain_final}", ygopro.constants.COLORS.BABYBLUE);
......@@ -3339,9 +3607,9 @@
room.turn = 0;
room.duel_stage = ygopro.constants.DUEL_STAGE.END;
if (settings.modules.heartbeat_detection.enabled) {
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
player.heartbeat_protected = false;
}
delete room.long_resolve_card;
......@@ -3355,6 +3623,19 @@
room.match_kill = false;
room.scores[room.winner_name] = 99;
}
if (settings.modules.vip.enabled && room.dueling_players[pos].vip && vip_info.players[room.dueling_players[pos].name].victory) {
ref5 = _.lines(vip_info.players[room.dueling_players[pos].name].victory);
for (o = 0, len4 = ref5.length; o < len4; o++) {
line = ref5[o];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
} else if (room.hostinfo.mode === 2 && settings.modules.vip.enabled && room.dueling_players[pos + 1].vip && vip_info.players[room.dueling_players[pos + 1].name].victory) {
ref6 = _.lines(vip_info.players[room.dueling_players[pos + 1].name].victory);
for (p = 0, len5 = ref6.length; p < len5; p++) {
line = ref6[p];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
}
}
}
if (room.death) {
if (settings.modules.http.quick_death_rule === 1 || settings.modules.http.quick_death_rule === 3) {
......@@ -3381,7 +3662,7 @@
if (room.dueling_players[pos].lp < 0) {
room.dueling_players[pos].lp = 0;
}
if ((0 < (ref4 = room.dueling_players[pos].lp) && ref4 <= 100)) {
if ((0 < (ref7 = room.dueling_players[pos].lp) && ref7 <= 100)) {
ygopro.stoc_send_chat_to_room(room, "${lp_low_opponent}", ygopro.constants.COLORS.PINK);
}
}
......@@ -3420,7 +3701,7 @@
if (room.dueling_players[pos].lp < 0) {
room.dueling_players[pos].lp = 0;
}
if ((0 < (ref5 = room.dueling_players[pos].lp) && ref5 <= 100)) {
if ((0 < (ref8 = room.dueling_players[pos].lp) && ref8 <= 100)) {
ygopro.stoc_send_chat_to_room(room, "${lp_low_self}", ygopro.constants.COLORS.PINK);
}
}
......@@ -3461,7 +3742,7 @@
max_loop = 3 + (count - 1) * 7;
deck_found = 0;
limbo_found = 0; // support custom cards which may be in location 0 in KoishiPro or EdoPro
for (i = o = 3, ref6 = max_loop; o <= ref6; i = o += 7) {
for (i = q = 3, ref9 = max_loop; q <= ref9; i = q += 7) {
loc = buffer.readInt8(i + 5);
if ((loc & 0x41) > 0) {
deck_found++;
......@@ -3483,8 +3764,8 @@
if (ygopro.constants.MSG[msg] === 'CHAINING') {
card = buffer.readUInt32LE(1);
found = false;
for (p = 0, len4 = long_resolve_cards.length; p < len4; p++) {
id = long_resolve_cards[p];
for (r = 0, len6 = long_resolve_cards.length; r < len6; r++) {
id = long_resolve_cards[r];
if (!(id === card)) {
continue;
}
......@@ -3509,9 +3790,9 @@
chain = buffer.readInt8(1);
// console.log(2,chain)
if (room.long_resolve_chain[chain]) {
ref7 = room.get_playing_player();
for (q = 0, len5 = ref7.length; q < len5; q++) {
player = ref7[q];
ref10 = room.get_playing_player();
for (s = 0, len7 = ref10.length; s < len7; s++) {
player = ref10[s];
player.heartbeat_protected = true;
}
}
......@@ -3526,15 +3807,42 @@
}
}
//登场台词
if (settings.modules.dialogues.enabled && !room.recovering) {
if ((settings.modules.dialogues.enabled || settings.modules.vip.enabled) && !room.recovering) {
if (ygopro.constants.MSG[msg] === 'SUMMONING' || ygopro.constants.MSG[msg] === 'SPSUMMONING' || ygopro.constants.MSG[msg] === 'CHAINING') {
card = buffer.readUInt32LE(1);
trigger_location = buffer.readUInt8(6);
if (dialogues.dialogues[card] && (ygopro.constants.MSG[msg] !== 'CHAINING' || (trigger_location & 0x8) && client.ready_trap)) {
ref8 = _.lines(dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]);
for (r = 0, len6 = ref8.length; r < len6; r++) {
line = ref8[r];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
act_pos = buffer.readUInt8(ygopro.constants.MSG[msg] === 'CHAINING' ? 9 : 5);
if (!room.dueling_players[0].is_first) {
act_pos = 1 - act_pos;
}
if (room.hostinfo.mode === 2) {
act_pos = act_pos * 2;
}
if (ygopro.constants.MSG[msg] !== 'CHAINING' || (trigger_location & 0x8) && client.ready_trap) {
if (settings.modules.vip.enabled && room.dueling_players[act_pos].vip && vip_info.players[room.dueling_players[act_pos].name].dialogues[card]) {
ref11 = _.lines(vip_info.players[room.dueling_players[act_pos].name].dialogues[card]);
for (t = 0, len8 = ref11.length; t < len8; t++) {
line = ref11[t];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.vip.enabled && room.hostinfo.mode === 2 && room.dueling_players[act_pos + 1].vip && vip_info.players[room.dueling_players[act_pos + 1].name].dialogues[card]) {
ref12 = _.lines(vip_info.players[room.dueling_players[act_pos + 1].name].dialogues[card]);
for (x = 0, len9 = ref12.length; x < len9; x++) {
line = ref12[x];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.dialogues.enabled && dialogues.dialogues[card]) {
ref13 = _.lines(dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]);
for (y = 0, len10 = ref13.length; y < len10; y++) {
line = ref13[y];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
}
} else if (settings.modules.dialogues.enabled && dialogues.dialogues_custom[card]) {
ref14 = _.lines(dialogues.dialogues_custom[card][Math.floor(Math.random() * dialogues.dialogues_custom[card].length)]);
for (z = 0, len11 = ref14.length; z < len11; z++) {
line = ref14[z];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
}
}
}
}
......@@ -3558,7 +3866,7 @@
//房间管理
ygopro.ctos_follow('HS_TOOBSERVER', true, async function(buffer, info, client, server, datas) {
var len3, n, player, ref3, room;
var len3, n, player, ref4, room;
room = ROOM_all[client.rid];
if (!room) {
return;
......@@ -3570,9 +3878,9 @@
if ((!room.arena && !settings.modules.challonge.enabled) || client.is_local) {
return false;
}
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player === client) {
ygopro.stoc_send_chat(client, "${cannot_to_observer}", ygopro.constants.COLORS.BABYBLUE);
return true;
......@@ -3582,14 +3890,14 @@
});
ygopro.ctos_follow('HS_KICK', true, async function(buffer, info, client, server, datas) {
var len3, n, player, ref3, room;
var len3, n, player, ref4, room;
room = ROOM_all[client.rid];
if (!room) {
return;
}
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player && player.pos === info.pos && player !== client) {
if (room.arena === "athletic" || settings.modules.challonge.enabled) {
ygopro.stoc_send_chat_to_room(room, `${client.name} \${kicked_by_system}`, ygopro.constants.COLORS.RED);
......@@ -3639,7 +3947,7 @@
});
ygopro.stoc_follow('HS_PLAYER_CHANGE', true, async function(buffer, info, client, server, datas) {
var is_ready, len3, n, p1, p2, player, pos, possibly_max_player, ref3, room;
var is_ready, len3, n, p1, p2, player, pos, possibly_max_player, ref4, room;
room = ROOM_all[client.rid];
if (!(room && client.pos === 0)) {
return;
......@@ -3648,9 +3956,9 @@
is_ready = (info.status & 0xf) === 9;
room.ready_player_count = 0;
room.ready_player_count_without_host = 0;
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player.pos === pos) {
player.is_ready = is_ready;
}
......@@ -3734,7 +4042,7 @@
});
ygopro.stoc_follow('DUEL_END', false, async function(buffer, info, client, server, datas) {
var len3, len4, n, o, player, ref3, ref4, room;
var len3, len4, n, o, player, ref4, ref5, room;
room = ROOM_all[client.rid];
if (!(room && settings.modules.replay_delay && room.hostinfo.mode === 1)) {
return;
......@@ -3743,16 +4051,16 @@
CLIENT_send_replays(client, room);
if (!room.replays_sent_to_watchers) {
room.replays_sent_to_watchers = true;
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player && player.pos > 3) {
CLIENT_send_replays(player, room);
}
}
ref4 = room.watchers;
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
ref5 = room.watchers;
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player) {
CLIENT_send_replays(player, room);
}
......@@ -3761,7 +4069,7 @@
});
wait_room_start = async function(room, time) {
var len3, n, player, ref3;
var len3, n, player, ref4;
if (room && room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.ready_player_count_without_host >= room.max_player - 1) {
time -= 1;
if (time) {
......@@ -3772,9 +4080,9 @@
wait_room_start(room, time);
}), 1000);
} else {
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player && player.is_host) {
await ROOM_ban_player(player.name, player.ip, "${random_ban_reason_zombie}");
ygopro.stoc_send_chat_to_room(room, `${player.name} \${kicked_by_system}`, ygopro.constants.COLORS.RED);
......@@ -3786,14 +4094,14 @@
};
wait_room_start_arena = async function(room) {
var display_name, len3, n, player, ref3;
var display_name, len3, n, player, ref4;
if (room && room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.waiting_for_player) {
room.waiting_for_player_time = room.waiting_for_player_time - 1;
if (room.waiting_for_player_time > 0) {
if (!(room.waiting_for_player_time % 5)) {
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (!(player)) {
continue;
}
......@@ -3814,14 +4122,33 @@
//tip
ygopro.stoc_send_random_tip = async function(client) {
if (settings.modules.tips.enabled && tips.tips.length) {
ygopro.stoc_send_chat(client, "Tip: " + tips.tips[Math.floor(Math.random() * tips.tips.length)]);
var tip_type;
tip_type = "tips";
if (settings.modules.tips.split_zh && tips.tips_zh.length && client.lang === "zh-cn") {
tip_type = "tips_zh";
}
if (settings.modules.tips.enabled && tips.tips.length && !client.is_local && !client.closed) {
ygopro.stoc_send_chat(client, "Tip: " + tips[tip_type][Math.floor(Math.random() * tips[tip_type].length)]);
}
};
ygopro.stoc_send_random_tip_to_room = async function(room) {
var len3, len4, n, o, player, ref4, ref5;
if (settings.modules.tips.enabled && tips.tips.length) {
ygopro.stoc_send_chat_to_room(room, "Tip: " + tips.tips[Math.floor(Math.random() * tips.tips.length)]);
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player && !player.is_local && !player.closed) {
ygopro.stoc_send_random_tip(player);
}
}
ref5 = room.watchers;
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player && !player.is_local && !player.closed) {
ygopro.stoc_send_random_tip(player);
}
}
}
};
......@@ -3844,8 +4171,34 @@
});
};
if (settings.modules.tips.get) {
load_tips_zh = global.load_tips_zh = async function(callback) {
request({
url: settings.modules.tips.get_zh,
json: true
}, function(error, response, body) {
if (_.isString(body)) {
log.warn("zh tips bad json", body);
} else if (error || !body) {
log.warn('zh tips error', error, response);
} else {
setting_change(tips, "tips_zh", body);
log.info("zh tips loaded", tips.tips_zh.length);
}
if (callback) {
callback(error, body);
}
});
};
if (settings.modules.tips.enabled && settings.modules.tips.get) {
load_tips();
}
if (settings.modules.tips.enabled && settings.modules.tips.get_zh) {
load_tips_zh();
}
if (settings.modules.tips.enabled) {
setInterval(function() {
var len3, n, room;
for (n = 0, len3 = ROOM_all.length; n < len3; n++) {
......@@ -3860,7 +4213,7 @@
}
ygopro.stoc_follow('DUEL_START', false, async function(buffer, info, client, server, datas) {
var deck_arena, deck_name, deck_text, len3, len4, n, o, player, ref3, ref4, room;
var deck_arena, deck_name, deck_text, len3, len4, n, o, player, ref4, ref5, room;
room = ROOM_all[client.rid];
if (!(room && !client.reconnecting)) {
return;
......@@ -3874,9 +4227,9 @@
}
//room.duels = []
room.dueling_players = [];
ref3 = room.get_playing_player();
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.get_playing_player();
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
room.dueling_players[player.pos] = player;
room.scores[player.name_vpass] = 0;
room.player_datas.push({
......@@ -3901,9 +4254,9 @@
}
}
if (settings.modules.hide_name && room.duel_count === 0) {
ref4 = room.get_playing_player();
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
ref5 = room.get_playing_player();
for (o = 0, len4 = ref5.length; o < len4; o++) {
player = ref5[o];
if (player !== client) {
ygopro.stoc_send(client, 'HS_PLAYER_ENTER', {
name: player.name,
......@@ -3968,18 +4321,29 @@
});
ygopro.ctos_follow('SURRENDER', true, async function(buffer, info, client, server, datas) {
var room;
var room, sur_player;
room = ROOM_all[client.rid];
if (!room) {
return;
}
if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN || room.hostinfo.mode === 2) {
if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN) {
return true;
}
if (room.random_type && room.turn < 3 && !client.flee_free && !settings.modules.test_mode.surrender_anytime && !(room.random_type === 'M' && settings.modules.random_duel.record_match_scores)) {
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE);
return true;
}
if (room.hostinfo.mode === 2) {
if (!settings.modules.tag_duel_surrender) {
return true;
} else if (!client.surrend_confirm && !CLIENT_get_partner(client).closed && !CLIENT_get_partner(client).is_local) {
sur_player = CLIENT_get_partner(client);
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE);
sur_player.surrend_confirm = true;
return true;
}
}
return false;
});
......@@ -4012,7 +4376,7 @@
//else
//log.info 'BIG BROTHER OK', response.statusCode, roomname, body
ygopro.ctos_follow('CHAT', true, async function(buffer, info, client, server, datas) {
var cancel, ccolor, cip, cmd, cmsg, cname, color, cvalue, msg, name, oldmsg, ref3, room, struct, windbot;
var buy_result, cancel, ccolor, cip, cmd, cmsg, cname, code, color, cvalue, key, msg, name, oldmsg, ref4, room, struct, sur_player, uname, windbot, word;
room = ROOM_all[client.rid];
if (!room) {
return;
......@@ -4026,18 +4390,27 @@
switch (cmd[0]) {
case '/投降':
case '/surrender':
if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN || room.hostinfo.mode === 2) {
if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN || (room.hostinfo.mode === 2 && !settings.modules.tag_duel_surrender)) {
return cancel;
}
if (room.random_type && room.turn < 3) {
if (room.random_type && room.turn < 3 && !client.flee_free) {
ygopro.stoc_send_chat(client, "${surrender_denied}", ygopro.constants.COLORS.BABYBLUE);
return cancel;
}
if (client.surrend_confirm) {
ygopro.ctos_send(client.server, 'SURRENDER');
} else {
ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE);
client.surrend_confirm = true;
sur_player = CLIENT_get_partner(client);
if (sur_player.closed || sur_player.is_local) {
sur_player = client;
}
if (room.hostinfo.mode === 2 && sur_player !== client) {
ygopro.stoc_send_chat(sur_player, "${surrender_confirm_tag}", ygopro.constants.COLORS.BABYBLUE);
ygopro.stoc_send_chat(client, "${surrender_confirm_sent}", ygopro.constants.COLORS.BABYBLUE);
} else {
ygopro.stoc_send_chat(client, "${surrender_confirm}", ygopro.constants.COLORS.BABYBLUE);
}
sur_player.surrend_confirm = true;
}
break;
case '/help':
......@@ -4052,12 +4425,15 @@
if (settings.modules.tips.enabled) {
ygopro.stoc_send_chat(client, "${chat_order_tip}");
}
if (settings.modules.chat_color.enabled) {
if (settings.modules.chat_color.enabled && (!(settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip) || client.vip)) {
ygopro.stoc_send_chat(client, "${chat_order_chatcolor_1}");
}
if (settings.modules.chat_color.enabled) {
if (settings.modules.chat_color.enabled && (!(settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip) || client.vip)) {
ygopro.stoc_send_chat(client, "${chat_order_chatcolor_2}");
}
if (settings.modules.vip.enabled) {
ygopro.stoc_send_chat(client, "${chat_order_vip}");
}
break;
case '/tip':
if (settings.modules.tips.enabled) {
......@@ -4094,24 +4470,36 @@
case '/color':
if (settings.modules.chat_color.enabled) {
cip = CLIENT_get_authorize_key(client);
if (cmsg = cmd[1]) {
if (settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip && !client.vip) {
CLIENT_send_vip_status(client);
} else if (cmsg = cmd[1]) {
if (cmsg.toLowerCase() === "help") {
ygopro.stoc_send_chat(client, "${show_color_list}", ygopro.constants.COLORS.BABYBLUE);
ref3 = ygopro.constants.COLORS;
for (cname in ref3) {
cvalue = ref3[cname];
ref4 = ygopro.constants.COLORS;
for (cname in ref4) {
cvalue = ref4[cname];
if (cvalue > 10) {
ygopro.stoc_send_chat(client, cname, cvalue);
}
}
} else if (cmsg.toLowerCase() === "default") {
chat_color.save_list[cip] = false;
if (settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip) {
delete vip_info.players[client.name].chat_color;
setting_save(vip_info);
} else {
delete chat_color.save_list[cip];
}
setting_save(chat_color);
ygopro.stoc_send_chat(client, "${set_chat_color_default}", ygopro.constants.COLORS.BABYBLUE);
} else {
ccolor = cmsg.toUpperCase();
if (ygopro.constants.COLORS[ccolor] && ygopro.constants.COLORS[ccolor] > 10 && ygopro.constants.COLORS[ccolor] < 20) {
chat_color.save_list[cip] = ccolor;
if (settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip) {
vip_info.players[client.name].chat_color = ccolor;
setting_save(vip_info);
} else {
chat_color.save_list[cip] = ccolor;
}
setting_save(chat_color);
ygopro.stoc_send_chat(client, "${set_chat_color_part1}" + ccolor + "${set_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE);
} else {
......@@ -4119,13 +4507,119 @@
}
}
} else {
if (color = chat_color.save_list[cip]) {
if (color = (settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip ? vip_info.players[client.name].chat_color : chat_color.save_list[cip])) {
ygopro.stoc_send_chat(client, "${get_chat_color_part1}" + color + "${get_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE);
} else {
ygopro.stoc_send_chat(client, "${get_chat_color_default}", ygopro.constants.COLORS.BABYBLUE);
}
}
}
break;
case '/vip':
if (settings.modules.vip.enabled) {
if (name = cmd[1]) {
uname = name.toLowerCase();
switch (uname) {
case 'help':
ygopro.stoc_send_chat(client, "${chat_order_vip_help}");
ygopro.stoc_send_chat(client, "${chat_order_vip_status}");
ygopro.stoc_send_chat(client, "${chat_order_vip_buy}");
ygopro.stoc_send_chat(client, "${chat_order_vip_password}");
ygopro.stoc_send_chat(client, "${chat_order_vip_dialogues}");
ygopro.stoc_send_chat(client, "${chat_order_vip_words}");
ygopro.stoc_send_chat(client, "${chat_order_vip_victory}");
break;
case 'status':
CLIENT_send_vip_status(client, true);
break;
case 'buy':
if (vip_info.players[client.name] && vip_info.players[client.name].password !== client.vpass) {
ygopro.stoc_send_chat(client, "${vip_account_existed}", ygopro.constants.COLORS.RED);
} else if ((!client.vpass && client.name.length > 13) || (client.vpass && (client.name.length + client.vpass.length) > 18)) {
ygopro.stoc_send_chat(client, "${vip_player_name_too_long}", ygopro.constants.COLORS.RED);
} else {
key = cmd[2];
buy_result = CLIENT_use_cdkey(client, key);
switch (buy_result) {
case 0:
ygopro.stoc_send_chat(client, "${vip_key_not_found}", ygopro.constants.COLORS.RED);
break;
case 1:
ygopro.stoc_send_chat(client, "${vip_success_new_part1}" + client.name + "$" + client.vpass + "${vip_success_new_part2}", ygopro.constants.COLORS.BABYBLUE);
break;
case 2:
ygopro.stoc_send_chat(client, "${vip_success_renew}", ygopro.constants.COLORS.BABYBLUE);
}
}
break;
case 'dialogues':
if (!client.vip) {
CLIENT_send_vip_status(client);
} else {
code = cmd[2];
word = concat_name(cmd, 3);
if (!code || !parseInt(code)) {
ygopro.stoc_send_chat(client, "${vip_invalid_card_code}", ygopro.constants.COLORS.RED);
} else if (!word) {
delete vip_info.players[client.name].dialogues[parseInt(code)];
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_cleared_dialogues_part1}" + code + "${vip_cleared_dialogues_part2}", ygopro.constants.COLORS.BABYBLUE);
} else {
vip_info.players[client.name].dialogues[parseInt(code)] = word;
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_set_dialogues_part1}" + code + "${vip_set_dialogues_part2}", ygopro.constants.COLORS.BABYBLUE);
}
}
break;
case 'words':
if (!client.vip) {
CLIENT_send_vip_status(client);
} else {
word = concat_name(cmd, 2);
if (!word) {
delete vip_info.players[client.name].words;
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_cleared_words}", ygopro.constants.COLORS.BABYBLUE);
} else {
vip_info.players[client.name].words = word;
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_set_words}", ygopro.constants.COLORS.BABYBLUE);
}
}
break;
case 'victory':
if (!client.vip) {
CLIENT_send_vip_status(client);
} else {
word = concat_name(cmd, 2);
if (!word) {
delete vip_info.players[client.name].victory;
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_cleared_victory}", ygopro.constants.COLORS.BABYBLUE);
} else {
vip_info.players[client.name].victory = word;
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_set_victory}", ygopro.constants.COLORS.BABYBLUE);
}
}
break;
case 'password':
if (!client.vip) {
CLIENT_send_vip_status(client);
} else {
word = cmd[2];
if (word && (client.name.length + word.length) <= 18) {
vip_info.players[client.name].password = word;
client.vpass = word;
setting_save(vip_info);
ygopro.stoc_send_chat(client, "${vip_password_changed}", ygopro.constants.COLORS.BABYBLUE);
}
}
}
} else {
CLIENT_send_vip_status(client);
}
}
}
//when '/test'
// ygopro.stoc_send_hint_card_to_room(room, 2333365)
......@@ -4263,17 +4757,17 @@
return true;
}
buff_main = (function() {
var n, ref3, results;
var n, ref4, results;
results = [];
for (i = n = 0, ref3 = info.mainc; (0 <= ref3 ? n < ref3 : n > ref3); i = 0 <= ref3 ? ++n : --n) {
for (i = n = 0, ref4 = info.mainc; (0 <= ref4 ? n < ref4 : n > ref4); i = 0 <= ref4 ? ++n : --n) {
results.push(info.deckbuf[i]);
}
return results;
})();
buff_side = (function() {
var n, ref3, ref4, results;
var n, ref4, ref5, results;
results = [];
for (i = n = ref3 = info.mainc, ref4 = info.mainc + info.sidec; (ref3 <= ref4 ? n < ref4 : n > ref4); i = ref3 <= ref4 ? ++n : --n) {
for (i = n = ref4 = info.mainc, ref5 = info.mainc + info.sidec; (ref4 <= ref5 ? n < ref5 : n > ref5); i = ref4 <= ref5 ? ++n : --n) {
results.push(info.deckbuf[i]);
}
return results;
......@@ -4327,7 +4821,7 @@
struct.set("deckbuf", [4392470, 4392470]);
ygopro.stoc_send_chat(client, "${deck_incorrect_reconnect}", ygopro.constants.COLORS.RED);
}
} else if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.hostinfo.mode === 1 && settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.deck_check && fs.readdirSync(settings.modules.tournament_mode.deck_path).length) {
} else if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.deck_check && fs.readdirSync(settings.modules.tournament_mode.deck_path).length) {
struct.set("mainc", 1);
struct.set("sidec", 1);
struct.set("deckbuf", [4392470, 4392470]);
......@@ -4502,7 +4996,7 @@
});
ygopro.stoc_follow('CHAT', true, async function(buffer, info, client, server, datas) {
var len3, n, pid, player, ref3, room, tcolor, tplayer;
var len3, n, pid, player, ref4, room, tcolor, tplayer;
room = ROOM_all[client.rid];
pid = info.player;
if (!(room && pid < 4 && settings.modules.chat_color.enabled && (!settings.modules.hide_name || room.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN))) {
......@@ -4520,17 +5014,17 @@
pid = 1 - pid;
}
}
ref3 = room.players;
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
ref4 = room.players;
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player && player.pos === pid) {
tplayer = player;
}
}
if (!tplayer) {
if (!(tplayer && (!(settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip) || tplayer.vip))) {
return;
}
tcolor = chat_color.save_list[CLIENT_get_authorize_key(tplayer)];
tcolor = settings.modules.vip.enabled && settings.modules.chat_color.restrict_to_vip ? vip_info.players[tplayer.name].chat_color : chat_color.save_list[CLIENT_get_authorize_key(tplayer)];
if (tcolor) {
ygopro.stoc_send(client, 'CHAT', {
player: ygopro.constants.COLORS[tcolor],
......@@ -4660,7 +5154,7 @@
});
ygopro.stoc_follow('REPLAY', true, async function(buffer, info, client, server, datas) {
var duellog, dueltime, i, len3, len4, n, o, player, ref3, ref4, replay_filename, room;
var duellog, dueltime, i, len3, len4, n, o, player, ref4, ref5, replay_filename, room;
room = ROOM_all[client.rid];
if (!room) {
return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player || settings.modules.replay_delay;
......@@ -4674,15 +5168,15 @@
dueltime = moment().format('YYYY-MM-DD HH-mm-ss');
replay_filename = dueltime;
if (room.hostinfo.mode !== 2) {
ref3 = room.dueling_players;
for (i = n = 0, len3 = ref3.length; n < len3; i = ++n) {
player = ref3[i];
ref4 = room.dueling_players;
for (i = n = 0, len3 = ref4.length; n < len3; i = ++n) {
player = ref4[i];
replay_filename = replay_filename + (i > 0 ? " VS " : " ") + player.name;
}
} else {
ref4 = room.dueling_players;
for (i = o = 0, len4 = ref4.length; o < len4; i = ++o) {
player = ref4[i];
ref5 = room.dueling_players;
for (i = o = 0, len4 = ref5.length; o < len4; i = ++o) {
player = ref5[i];
replay_filename = replay_filename + (i > 0 ? (i === 2 ? " VS " : " & ") : " ") + player.name;
}
}
......@@ -4696,11 +5190,11 @@
replay_filename: replay_filename,
roommode: room.hostinfo.mode,
players: (function() {
var len5, p, ref5, results;
ref5 = room.dueling_players;
var len5, p, ref6, results;
ref6 = room.dueling_players;
results = [];
for (p = 0, len5 = ref5.length; p < len5; p++) {
player = ref5[p];
for (p = 0, len5 = ref6.length; p < len5; p++) {
player = ref6[p];
results.push({
real_name: player.name_vpass,
deckbuf: player.start_deckbuf.toString("base64"),
......@@ -4805,13 +5299,13 @@
if (settings.modules.heartbeat_detection.enabled) {
setInterval(function() {
var len3, len4, n, o, player, ref3, room;
var len3, len4, n, o, player, ref4, room;
for (n = 0, len3 = ROOM_all.length; n < len3; n++) {
room = ROOM_all[n];
if (room && room.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN && (room.hostinfo.time_limit === 0 || room.duel_stage !== ygopro.constants.DUEL_STAGE.DUELING) && !room.windbot) {
ref3 = room.get_playing_player();
for (o = 0, len4 = ref3.length; o < len4; o++) {
player = ref3[o];
ref4 = room.get_playing_player();
for (o = 0, len4 = ref4.length; o < len4; o++) {
player = ref4[o];
if (player && (room.duel_stage !== ygopro.constants.DUEL_STAGE.SIDING || player.selected_preduel)) {
CLIENT_heartbeat_register(player, true);
}
......@@ -4894,7 +5388,7 @@
return callback + "( " + text + " );";
};
requestListener = async function(request, response) {
var archive_args, archive_name, archive_process, check, death_room_found, duellog, err, error, filename, getpath, len3, n, parseQueryString, pass_validated, ref3, replay, roomsjson, u;
var archive_args, archive_name, archive_process, check, death_room_found, duellog, err, error, filename, getpath, key, len3, len4, n, o, parseQueryString, pass_validated, ref4, ref5, replay, ret_keys, roomsjson, tasks, u;
parseQueryString = true;
u = url.parse(request.url, parseQueryString);
//pass_validated = u.query.pass == settings.modules.http.password
......@@ -4919,11 +5413,11 @@
roommode: room.hostinfo.mode,
needpass: (room.name.indexOf('$') !== -1).toString(),
users: _.sortBy((function() {
var len3, n, ref3, results;
ref3 = room.players;
var len3, n, ref4, results;
ref4 = room.players;
results = [];
for (n = 0, len3 = ref3.length; n < len3; n++) {
player = ref3[n];
for (n = 0, len3 = ref4.length; n < len3; n++) {
player = ref4[n];
if (player.pos != null) {
results.push({
id: (-1).toString(),
......@@ -4960,6 +5454,25 @@
duellog = JSON.stringify(duel_log.duel_log, null, 2);
response.end(addCallback(u.query.callback, duellog));
}
} else if (u.pathname === '/api/getkeys' && settings.modules.vip.enabled) {
if (!auth.auth(u.query.username, u.query.pass, "vip", "get_keys")) {
response.writeHead(200);
response.end(addCallback(u.query.callback, "Unauthorized."));
return;
} else if (!u.query.keytype || !vip_info.cdkeys[u.query.keytype]) {
response.writeHead(200);
response.end(addCallback(u.query.callback, "Key type not found."));
return;
} else {
response.writeHead(200);
ret_keys = "";
ref4 = vip_info.cdkeys[u.query.keytype];
for (n = 0, len3 = ref4.length; n < len3; n++) {
key = ref4[n];
ret_keys = ret_keys + u.query.keytype + "D" + settings.port + ":" + key + "\n";
}
response.end(addCallback(u.query.callback, ret_keys));
}
} else if (u.pathname === '/api/archive.zip' && settings.modules.tournament_mode.enabled) {
if (!(await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay_archive"))) {
response.writeHead(403);
......@@ -4970,9 +5483,9 @@
archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip";
archive_args = ["a", "-mx0", "-y", archive_name];
check = false;
ref3 = duel_log.duel_log;
for (n = 0, len3 = ref3.length; n < len3; n++) {
replay = ref3[n];
ref5 = duel_log.duel_log;
for (o = 0, len4 = ref5.length; o < len4; o++) {
replay = ref5[o];
check = true;
archive_args.push(replay.replay_filename);
}
......@@ -5125,7 +5638,13 @@
response.end(addCallback(u.query.callback, "['密码错误', 0]"));
return;
}
load_tips(function(err) {
tasks = {
tips: load_tips
};
if (settings.modules.tips.get_zh) {
tasks.tips_zh = load_tips_zh;
}
_async.auto(tasks, function(err) {
response.writeHead(200);
if (err) {
return response.end(addCallback(u.query.callback, "['tip fail', '" + settings.modules.tips.get + "']"));
......@@ -5139,7 +5658,13 @@
response.end(addCallback(u.query.callback, "['密码错误', 0]"));
return;
}
load_dialogues(function(err) {
tasks = {
dialogues: load_dialogues
};
if (settings.modules.dialogues.get_custom) {
tasks.dialogues_custom = load_dialogues_custom;
}
_async.auto(tasks, function(err) {
response.writeHead(200);
if (err) {
return response.end(addCallback(u.query.callback, "['dialogues fail', '" + settings.modules.dialogues.get + "']"));
......@@ -5243,6 +5768,15 @@
response.end(addCallback(u.query.callback, "['reboot ok', '" + u.query.reboot + "']"));
return process.exit();
});
} else if (u.query.generatekey && settings.modules.vip.enabled) {
if (!auth.auth(u.query.username, u.query.pass, "vip", "generate_keys")) {
response.writeHead(200);
response.end(addCallback(u.query.callback, "['密码错误', 0]"));
return;
}
VIP_generate_cdkeys(u.query.generatekey, settings.modules.vip.generate_count);
response.writeHead(200);
response.end(addCallback(u.query.callback, "['Keys generated', '" + u.query.generatekey + "']"));
} else {
response.writeHead(400);
response.end();
......
......@@ -81,6 +81,7 @@ var makeChangelogs = function(dir, since) {
if (prc_git_log.stdout) {
var logs = prc_git_log.stdout.toString().split(/\n/g);
for (var i in logs) {
console.log(logs[i])
var log = logs[i].split(",");
var date = log[1];
if (date) {
......@@ -88,7 +89,8 @@ var makeChangelogs = function(dir, since) {
if (prc_git_diff.stdout) {
var lines = prc_git_diff.stdout.toString().split(/\n/g);
for (var j in lines) {
var line = lines[j].match(/c(\d+)\.lua/);
console.log(lines[j])
var line = lines[j].match(/.*c(\d+)\.lua.*/);
if (line) {
var name = cardNames[line[1]] || line[1];
addedCards.push(name);
......@@ -99,6 +101,7 @@ var makeChangelogs = function(dir, since) {
}
}
for (var i in logs) {
console.log(logs[i])
var log = logs[i].split(",");
var date = log[1];
if (date) {
......@@ -106,7 +109,8 @@ var makeChangelogs = function(dir, since) {
if (prc_git_diff.stdout) {
var lines = prc_git_diff.stdout.toString().split(/\n/g);
for (var j in lines) {
var line = lines[j].match(/c(\d+)\.lua/);
console.log(lines[j])
var line = lines[j].match(/.*c(\d+)\.lua.*/);
if (line) {
var name = cardNames[line[1]] || line[1];
sendResponse("<span class='change'>" + date + " * " + name + "</span>");
......
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