Commit 8c5a41cb authored by mercury233's avatar mercury233

merge

parent 87a452c6
# ignore # ignore
test* jsconfig.json
coffeelint.json
.vscode/
password.json
config.*.json
node_modules/.bin/ /ygopro
node_modules/bunyan/ /windbot
node_modules/request/ /decks/
node_modules/underscore/ /decks_save*
node_modules/underscore.string/ /node_modules/
node_modules/sqlite3/
node_modules/moment/
test*
*.heapsnapshot *.heapsnapshot
*.tmp *.tmp
*.bak *.bak
*.log *.log
Thumbs.db Thumbs.db
ehthumbs.db ehthumbs.db
Desktop.ini Desktop.ini
......
## ygopro-server ## ygopro-server
一个YGOPRO服务器,基于mycard代码修改 一个YGOPRO服务器。
现用于[YGOPRO 233服](http://mercury233.me/ygosrv233/) 现用于[mycard](https://mycard.moe/)
###支持功能 ###支持功能
* Linux上运行 * Linux上运行
...@@ -11,29 +11,56 @@ ...@@ -11,29 +11,56 @@
* 广播消息 * 广播消息
* 召唤台词 * 召唤台词
* 先行卡一键更新 * 先行卡一键更新
* Windbot在线AI
###不支持功能 ###不支持功能
* 用户账号系统 * 用户账号系统
* 在线AI
* 在线聊天室 * 在线聊天室
###使用方法 ###使用方法
* 安装修改后的mycard版ygopro服务端:https://github.com/mercury233/ygopro/tree/server * 可参考[wiki](https://github.com/mercury233/ygopro-server/wiki)安装
* `git clone https://github.com/mercury233/ygopro-server.git` * 手动安装:
* `cd ygopro-server` * 安装mycard版ygopro服务端:https://github.com/mycard/ygopro/tree/server
* `npm install` * `git clone https://github.com/mycard/ygopro-server.git`
* 修改`config.json` * `cd ygopro-server`
* `npm install`
*`config.json`复制为`config.user.json`并进行修改
* `port`为你想要的端口 * `port`为你想要的端口
* `version`为ygopro的十进制版本号(例如,0x1336=4918)
* `ygopro_path`为ygopro服务端的相对路径
* `modules.stop`为文本时,表示服务器关闭 * `modules.stop`为文本时,表示服务器关闭
* `modules.TCG_banlist_id`为lflist中正在使用的TCG禁卡表的编号,0开始 * 更多选项参见wiki
* `node ygopro-server.js`即可运行 * `node ygopro-server.js`即可运行
* 简易的控制台在http://mercury233.me/ygosrv233/dashboard.html (我没有开发给用户使用的大厅的打算。) * 简易的控制台在http://mercury233.me/ygosrv233/dashboard.html (我没有开发给用户使用的大厅的打算。)
###高级功能
* 待补充说明
* 简易的先行卡更新控制台在http://mercury233.me/ygosrv233/pre-dashboard.html * 简易的先行卡更新控制台在http://mercury233.me/ygosrv233/pre-dashboard.html
###开发计划 ### 开发计划
* 重写全部代码,与SalvationServer合并,或作为分支版本 * 重做CTOS和STOC部分
* 模块化附加功能
* 房名代码
* 随机对战
* 召唤台词
* WindBot
* 云录像
* 比赛模式
* 先行卡更新
* 用户账号系统和管理员账号系统
* 云录像更换存储方式
### TODO
* refactoring CTOS and STOC
* change features to modules
* room name parsing
* random duel
* summon dialogues
* WindBot
* cloud replay
* tournament mode
* expansions updater
* user and admin account system
* new database for cloud replay
## Install Docker ## Install Docker
```bash ```bash
......
{ {
"port": 7911, "port": 7911,
"ygopro_path": "ygopro",
"modules": { "modules": {
"welcome": "YGOPRO Server", "welcome": "YGOPRO Server",
"update": "请更新游戏版本,可在社区手动下载更新包", "update": "请更新游戏版本,可在社区手动下载更新包",
"stop": false, "stop": false,
"tips": "http://mycard.moe/tips.json", "tips": "http://mycard.moe/tips.json",
"dialogues": "http://mycard.moe/dialogues.json", "dialogues": "http://mycard.moe/dialogues.json",
"redis_port": 6379,
"enable_websocket_roomlist": true,
"enable_random_duel": false, "enable_random_duel": false,
"enable_halfway_watch": true,
"enable_TCG_as_default": false,
"enable_cloud_replay": false,
"enable_windbot": true, "enable_windbot": true,
"enable_websocket_roomlist": true,
"enable_deck_log": false,
"redis_port": 6379,
"windbot_port": 2399,
"spawn_windbot": true,
"mycard_auth": "https://ygobbs.com", "mycard_auth": "https://ygobbs.com",
"post_start_watching": true, "hang_timeout": 90,
"enable_TCG_as_default": false, "tournament_mode": {
"enabled": false,
"deck_path": "./decks/",
"duel_log": [],
"password": "123456",
"port": 7933
},
"pre_util": {
"enabled": false,
"port": 7944,
"password": "123456",
"git_html_path": "../mercury233.github.io/",
"html_path": "../mercury233.github.io/ygosrv233/",
"html_filename": "pre.html",
"git_db_path": "../ygopro-unofficial/",
"db_path": "../ygopro-unofficial/unofficial/",
"html_img_rel_path": "pre/pics/",
"html_img_thumbnail": "thumbnail/",
"ygopro_path": "../ygopro-pre/",
"only_show_dbs": {
"news.cdb": true,
"pre-release.cdb": true
},
"html_gits": [
{
"name": "GitHub",
"push": ["push", "origin"]
},
{
"name": "Coding",
"push": ["push", "coding", "master:master"]
}
]
},
"http": { "http": {
"port": 7922, "port": 7922,
"password": "123456", "password": "123456",
...@@ -24,5 +62,14 @@ ...@@ -24,5 +62,14 @@
"key": "ssl/privkey.pem" "key": "ssl/privkey.pem"
} }
} }
},
"ban": {
"banned_user": [],
"banned_ip": [],
"badword_level0": ["滚", "衮", "操", "草", "艹", "狗", "日", "曰", "妈", "娘", "逼"],
"badword_level1": ["傻逼", "鸡巴"],
"badword_level2": ["死妈", "草你妈"],
"badword_level3": ["迷奸", "仿真枪"],
"illegal_id": ["^Lv.\\d+", "^VIP.\\d+"]
} }
} }
{
"port": 2333,
"password": "123456",
"git_html_path": "../mercury233.github.io/",
"html_path": "../mercury233.github.io/ygosrv233/",
"html_filename": "pre.html",
"git_db_path": "../ygopro-cards/",
"db_path": "../ygopro-cards/unofficial/",
"html_img_rel_path": "pre/pics/",
"ygopro_path": "../ygopro-pre/"
}
\ No newline at end of file
...@@ -247,6 +247,18 @@ ...@@ -247,6 +247,18 @@
"ATTRIBUTE_LIGHT": 16, "ATTRIBUTE_LIGHT": 16,
"ATTRIBUTE_DARK": 32, "ATTRIBUTE_DARK": 32,
"ATTRIBUTE_DEVINE": 64 "ATTRIBUTE_DEVINE": 64
},
"COLORS": {
"LIGHTBLUE": 8,
"RED": 11,
"GREEN": 12,
"BLUE": 13,
"BABYBLUE": 14,
"PINK": 15,
"YELLOW": 16,
"WHITE": 17,
"GRAY": 18,
"DARKGRAY": 19
} }
} }
......
...@@ -10,14 +10,14 @@ ...@@ -10,14 +10,14 @@
], ],
"author": "zh99998 <zh99998@gmail.com>, mercury233 <me@mercury233.me>", "author": "zh99998 <zh99998@gmail.com>, mercury233 <me@mercury233.me>",
"dependencies": { "dependencies": {
"bunyan": "latest",
"moment": "latest",
"nconf": "latest",
"pg": "latest",
"request": "latest",
"underscore": "latest", "underscore": "latest",
"underscore.string": "latest", "underscore.string": "latest",
"request": "latest", "ws": "latest"
"moment": "latest",
"sqlite3": "latest",
"bunyan": "latest",
"ws": "latest",
"pg": "latest"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"GAME_MSG": "GameMsg_Hint_Card_only", "GAME_MSG": "GameMsg_Hint_Card_only",
"SELECT_HAND": "", "SELECT_HAND": "",
"SELECT_TP": "", "SELECT_TP": "",
"REPLAY": "",
"CHAT": "STOC_Chat" "CHAT": "STOC_Chat"
} }
} }
This diff is collapsed.
This diff is collapsed.
WebSocketServer = require('ws').Server; WebSocketServer = require('ws').Server
server = null server = null
......
// a special version of node-struct by xdenser
// https://github.com/xdenser/node-struct/tree/f843487d6768cd0bf20c2ce7803dde2d92df5694
function byteField(p, offset) { function byteField(p, offset) {
this.length = 1; this.length = 1;
this.get = function () { this.get = function () {
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
"deck": [ "deck": [
{"name": "mainc", "type": "unsigned int"}, {"name": "mainc", "type": "unsigned int"},
{"name": "sidec", "type": "unsigned int"}, {"name": "sidec", "type": "unsigned int"},
{"name": "deckbuf", "type": "unsigned int", "length": 75} {"name": "deckbuf", "type": "unsigned int", "length": 90}
], ],
"chat": [ "chat": [
{"name": "msg", "type": "unsigned short", "length":"255", "encoding": "UTF-16LE"} {"name": "msg", "type": "unsigned short", "length":"255", "encoding": "UTF-16LE"}
......
...@@ -8,11 +8,9 @@ ...@@ -8,11 +8,9 @@
*/ */
var sqlite3 = require('sqlite3').verbose(); var sqlite3 = require('sqlite3').verbose();
var fs = require('fs'); var fs = require('fs');
var config = require('./config.deckstats.json'); //{ "deckpath": "../decks", "dbfile": "cards.cdb" }
var constants = require('./constants.json'); var constants = require('./constants.json');
var DECKPATH="C:\\deck\\deck"
var DBFILE="F:\\Works\\deck\\cards.cdb"
var ALL_MAIN_CARDS={}; var ALL_MAIN_CARDS={};
var ALL_SIDE_CARDS={}; var ALL_SIDE_CARDS={};
var ALL_CARD_DATAS={}; var ALL_CARD_DATAS={};
...@@ -27,6 +25,9 @@ function add_to_deck(deck,id) { ...@@ -27,6 +25,9 @@ function add_to_deck(deck,id) {
} }
function add_to_all_list(LIST,id,use) { function add_to_all_list(LIST,id,use) {
if (!ALL_CARD_DATAS[id]) {
return;
}
if (ALL_CARD_DATAS[id].alias) { if (ALL_CARD_DATAS[id].alias) {
id=ALL_CARD_DATAS[id].alias; id=ALL_CARD_DATAS[id].alias;
} }
...@@ -46,7 +47,7 @@ function add_to_all_list(LIST,id,use) { ...@@ -46,7 +47,7 @@ function add_to_all_list(LIST,id,use) {
function read_deck_file(filename) { function read_deck_file(filename) {
console.log("reading "+filename); console.log("reading "+filename);
var deck_text=fs.readFileSync(DECKPATH+"\\"+filename,{encoding:"ASCII"}) var deck_text=fs.readFileSync(config.deckpath+"\\"+filename,{encoding:"ASCII"})
var deck_array=deck_text.split("\n"); var deck_array=deck_text.split("\n");
var deck_main={}; var deck_main={};
var deck_side={}; var deck_side={};
...@@ -68,10 +69,10 @@ function read_deck_file(filename) { ...@@ -68,10 +69,10 @@ function read_deck_file(filename) {
} }
function load_database(callback) { function load_database(callback) {
var db=new sqlite3.Database(DBFILE); var db=new sqlite3.Database(config.dbfile);
db.each("select * from datas,texts where datas.id=texts.id", function (err,result) { db.each("select * from datas,texts where datas.id=texts.id", function (err,result) {
if (err) { if (err) {
console.log(DBFILE + ":" + err); console.log(config.dbfile + ":" + err);
return; return;
} }
else { else {
...@@ -141,7 +142,7 @@ function load_database(callback) { ...@@ -141,7 +142,7 @@ function load_database(callback) {
} }
function read_decks() { function read_decks() {
var ALL_DECKS=fs.readdirSync(DECKPATH); var ALL_DECKS=fs.readdirSync(config.deckpath);
for (var i in ALL_DECKS) { for (var i in ALL_DECKS) {
var filename=ALL_DECKS[i]; var filename=ALL_DECKS[i];
...@@ -150,7 +151,12 @@ function read_decks() { ...@@ -150,7 +151,12 @@ function read_decks() {
} }
} }
output_csv(ALL_MAIN_CARDS,"main.csv"); output_csv(ALL_MAIN_CARDS,"main.csv");
if (ALL_SIDE_CARDS.length) { var ALL_SIDE_CARDS_isempty = true;
for (var j in ALL_SIDE_CARDS) {
ALL_SIDE_CARDS_isempty = false;
break;
}
if (!ALL_SIDE_CARDS_isempty) {
output_csv(ALL_SIDE_CARDS,"side.csv"); output_csv(ALL_SIDE_CARDS,"side.csv");
} }
} }
......
...@@ -17,7 +17,13 @@ var moment = require('moment'); ...@@ -17,7 +17,13 @@ var moment = require('moment');
moment.locale('zh-cn'); moment.locale('zh-cn');
var constants = require('./constants.json'); var constants = require('./constants.json');
var config = require('./config.pre.json');
var nconf = require('nconf');
nconf.file('./config.user.json');
var defaultconfig = require('./config.json');
nconf.defaults(defaultconfig);
var settings = nconf.get();
config=settings.modules.pre_util;
//全卡HTML列表 //全卡HTML列表
var cardHTMLs=[]; var cardHTMLs=[];
...@@ -52,7 +58,7 @@ var loadDb = function(db_file) { ...@@ -52,7 +58,7 @@ var loadDb = function(db_file) {
var cardHTML="<tr>"; var cardHTML="<tr>";
cardHTML+='<td><a href="'+ config.html_img_rel_path + result.id +'.jpg" target="_blank"><img src="'+config.html_img_rel_path+'thumbnail/'+ result.id +'.jpg" alt="'+ result.name +'"></a></td>'; cardHTML+='<td><a href="'+ config.html_img_rel_path + result.id +'.jpg" target="_blank"><img src="'+config.html_img_rel_path+config.html_img_thumbnail+ result.id +'.jpg" alt="'+ result.name +'"></a></td>';
cardHTML+='<td>'+ result.name +'</td>'; cardHTML+='<td>'+ result.name +'</td>';
var cardText=""; var cardText="";
...@@ -92,7 +98,7 @@ var loadDb = function(db_file) { ...@@ -92,7 +98,7 @@ var loadDb = function(db_file) {
if (result.race & constants.RACES.RACE_ZOMBIE) {cardRace="不死";} if (result.race & constants.RACES.RACE_ZOMBIE) {cardRace="不死";}
if (result.race & constants.RACES.RACE_MACHINE) {cardRace="机械";} if (result.race & constants.RACES.RACE_MACHINE) {cardRace="机械";}
if (result.race & constants.RACES.RACE_AQUA) {cardRace="";} if (result.race & constants.RACES.RACE_AQUA) {cardRace="";}
if (result.race & constants.RACES.RACE_PYRO) {cardRace="念动力";} if (result.race & constants.RACES.RACE_PYRO) {cardRace="";}
if (result.race & constants.RACES.RACE_ROCK) {cardRace="岩石";} if (result.race & constants.RACES.RACE_ROCK) {cardRace="岩石";}
if (result.race & constants.RACES.RACE_WINDBEAST) {cardRace="鸟兽";} if (result.race & constants.RACES.RACE_WINDBEAST) {cardRace="鸟兽";}
if (result.race & constants.RACES.RACE_PLANT) {cardRace="植物";} if (result.race & constants.RACES.RACE_PLANT) {cardRace="植物";}
...@@ -119,7 +125,7 @@ var loadDb = function(db_file) { ...@@ -119,7 +125,7 @@ var loadDb = function(db_file) {
if (result.attribute & constants.ATTRIBUTES.ATTRIBUTE_LIGHT) {cardAttr="";} if (result.attribute & constants.ATTRIBUTES.ATTRIBUTE_LIGHT) {cardAttr="";}
if (result.attribute & constants.ATTRIBUTES.ATTRIBUTE_DARK) {cardAttr="";} if (result.attribute & constants.ATTRIBUTES.ATTRIBUTE_DARK) {cardAttr="";}
if (result.attribute & constants.ATTRIBUTES.ATTRIBUTE_DEVINE) {cardAttr="";} if (result.attribute & constants.ATTRIBUTES.ATTRIBUTE_DEVINE) {cardAttr="";}
cardText+="/"+ cardAttr +"\r\n"; cardText+="/"+ cardAttr +"\n";
var cardLevel; var cardLevel;
var cardLScale; var cardLScale;
...@@ -141,14 +147,14 @@ var loadDb = function(db_file) { ...@@ -141,14 +147,14 @@ var loadDb = function(db_file) {
cardText+=" " + cardLScale + "/" +cardRScale; cardText+=" " + cardLScale + "/" +cardRScale;
} }
cardText+="\r\n"; cardText+="\n";
} }
else { else {
cardText+="\r\n"; cardText+="\n";
} }
cardText+=result.desc; cardText+=result.desc;
cardHTML+='<td>'+ cardText.replace(/\r\n/g,"<br>") +'</td>'; cardHTML+='<td>'+ cardText.replace(/\n/g,"<br>") +'</td>';
cardHTML+='</tr>'; cardHTML+='</tr>';
cardHTMLs.push(cardHTML); cardHTMLs.push(cardHTML);
...@@ -166,11 +172,11 @@ var loadDb = function(db_file) { ...@@ -166,11 +172,11 @@ var loadDb = function(db_file) {
//将cardHTMLs中内容更新到指定列表页,同步 //将cardHTMLs中内容更新到指定列表页,同步
var writeToFile = function(message) { var writeToFile = function(message) {
var fileContent=fs.readFileSync(config.html_path+config.html_filename, {"encoding":"utf-8"}); var fileContent=fs.readFileSync(config.html_path+config.html_filename, {"encoding":"utf-8"});
var newContent=cardHTMLs.join("\r\n"); var newContent=cardHTMLs.join("\n");
fileContent=fileContent.replace(/<tbody class="auto-generated">[\w\W]*<\/tbody>/,'<tbody class="auto-generated">\r\n'+newContent+'\r\n</tbody>'); fileContent=fileContent.replace(/<tbody class="auto-generated">[\w\W]*<\/tbody>/,'<tbody class="auto-generated">\n'+newContent+'\n</tbody>');
if (message) { if (message) {
message="<li>"+moment().format('L HH:mm')+"<ul><li>"+message.split("!换行符!").join("</li><li>")+"</li></ul></li>"; message="<li>"+moment().format('L HH:mm')+"<ul><li>"+message.split("!换行符!").join("</li><li>")+"</li></ul></li>";
fileContent=fileContent.replace(/<ul class="auto-generated">/,'<ul class="auto-generated">\r\n'+message); fileContent=fileContent.replace(/<ul class="auto-generated">/,'<ul class="auto-generated">\n'+message);
} }
fs.writeFileSync(config.html_path+config.html_filename, fileContent); fs.writeFileSync(config.html_path+config.html_filename, fileContent);
sendResponse("列表更新完成。"); sendResponse("列表更新完成。");
...@@ -183,7 +189,7 @@ var loadAllDbs = function() { ...@@ -183,7 +189,7 @@ var loadAllDbs = function() {
var files = fs.readdirSync(config.db_path+"expansions/"); var files = fs.readdirSync(config.db_path+"expansions/");
for (var i in files) { for (var i in files) {
var filename = files[i]; var filename = files[i];
if (filename.slice(-4) === ".cdb") { if (filename.slice(-4) === ".cdb" && (!config.only_show_dbs || config.only_show_dbs.length==0 || config.only_show_dbs[filename])) {
loadDb(config.db_path+"expansions/"+filename); loadDb(config.db_path+"expansions/"+filename);
} }
} }
...@@ -198,7 +204,7 @@ var fetchDatas = function() { ...@@ -198,7 +204,7 @@ var fetchDatas = function() {
}); });
proc.stderr.setEncoding('utf8'); proc.stderr.setEncoding('utf8');
proc.stderr.on('data', function(data) { proc.stderr.on('data', function(data) {
sendResponse("git pull error: "+data); sendResponse("git pull: "+data);
}); });
proc.on('close', function (code) { proc.on('close', function (code) {
sendResponse("数据更新完成。"); sendResponse("数据更新完成。");
...@@ -210,7 +216,7 @@ var fetchDatas = function() { ...@@ -210,7 +216,7 @@ var fetchDatas = function() {
}); });
proc2.stderr.setEncoding('utf8'); proc2.stderr.setEncoding('utf8');
proc2.stderr.on('data', function(data) { proc2.stderr.on('data', function(data) {
sendResponse("git pull error: "+data); sendResponse("git pull: "+data);
}); });
proc2.on('close', function (code) { proc2.on('close', function (code) {
sendResponse("网页同步完成。"); sendResponse("网页同步完成。");
...@@ -225,30 +231,27 @@ var pushDatas = function() { ...@@ -225,30 +231,27 @@ var pushDatas = function() {
} catch (error) { } catch (error) {
sendResponse("git error: "+error.stdout); sendResponse("git error: "+error.stdout);
} }
var proc2 = spawn("git", ["push", "gitcafe", "master:gitcafe-pages"], { cwd: config.git_html_path, env: process.env }); for (var i in config.html_gits) {
proc2.stdout.setEncoding('utf8'); var git = config.html_gits[i];
proc2.stdout.on('data', function(data) { var proc = spawn("git", git.push, { cwd: config.git_html_path, env: process.env });
sendResponse("git push: "+data); proc.stdout.setEncoding('utf8');
}); proc.stdout.on('data', (function(git) {
proc2.stderr.setEncoding('utf8'); return function(data) {
proc2.stderr.on('data', function(data) { sendResponse(git.name + " git push: " + data);
sendResponse("git push error: "+data); }
}); })(git));
proc2.on('close', function (code) { proc.stderr.setEncoding('utf8');
sendResponse("gitcafe上传完成。"); proc.stderr.on('data', (function(git) {
}); return function(data) {
var proc = spawn("git", ["push"], { cwd: config.git_html_path, env: process.env }); sendResponse(git.name + " git push: " + data);
proc.stdout.setEncoding('utf8'); }
proc.stdout.on('data', function(data) { })(git));
sendResponse("git push: "+data); proc.on('close', (function(git) {
}); return function(code) {
proc.stderr.setEncoding('utf8'); sendResponse(git.name + "上传完成。");
proc.stderr.on('data', function(data) { }
sendResponse("git push: "+data); })(git));
}); }
proc.on('close', function (code) {
sendResponse("github上传完成。");
});
} }
//将数据库文件夹里卡图复制到列表页对应文件夹里,同步 //将数据库文件夹里卡图复制到列表页对应文件夹里,同步
...@@ -260,9 +263,13 @@ var copyImages = function() { ...@@ -260,9 +263,13 @@ var copyImages = function() {
//将数据库文件夹复制到YGOPRO文件夹里,同步 //将数据库文件夹复制到YGOPRO文件夹里,同步
var copyToYGOPRO = function() { var copyToYGOPRO = function() {
execSync('rm -rf "' + config.ygopro_path + 'expansions/*' + '"'); execSync('rm -rf ' + config.ygopro_path + 'expansions/*' + '');
execSync('cp -rf "' + config.db_path + 'expansions' + '" "' + config.ygopro_path + '"'); execSync('cp -rf "' + config.db_path + 'expansions' + '" "' + config.ygopro_path + '"');
execSync('cp -rf "' + config.db_path + 'script' + '" "' + config.ygopro_path + 'expansions"'); execSync('cp -rf "' + config.db_path + 'script' + '" "' + config.ygopro_path + 'expansions"');
try {
execSync('cp -rf "' + config.db_path + 'lflist.conf' + '" "' + config.ygopro_path + '"');
}
catch (e) {}
sendResponse("更新完成。"); sendResponse("更新完成。");
} }
......
This diff is collapsed.
This diff is collapsed.
/*
ygopro-tournament.js
ygopro tournament util
Author: mercury233
License: MIT
不带参数运行时,会建立一个服务器,调用API执行对应操作
*/
var http = require('http');
var fs = require('fs');
var url = require('url');
var request = require('request');
var formidable = require('formidable');
var _ = require('underscore');
_.str = require('underscore.string');
_.mixin(_.str.exports());
var nconf = require('nconf');
nconf.file('./config.user.json');
var defaultconfig = require('./config.json');
nconf.defaults(defaultconfig);
var settings = nconf.get();
config=settings.modules.tournament_mode;
//http长连接
var responder;
config.wallpapers=[""];
request({
url: "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=8&mkt=zh-CN",
json: true
}, function(error, response, body) {
if (_.isString(body)) {
console.log("wallpapers bad json", body);
}
else if (error || !body) {
console.log('wallpapers error', error, response);
}
else {
config.wallpapers=[];
for (var i in body.images) {
var wallpaper=body.images[i];
var img={
"url": "http://s.cn.bing.net"+wallpaper.urlbase+"_768x1366.jpg",
"desc": wallpaper.copyright
}
config.wallpapers.push(img);
}
}
});
//输出反馈信息,如有http长连接则输出到http,否则输出到控制台
var sendResponse = function(text) {
text=""+text;
if (responder) {
text=text.replace(/\n/g,"<br>");
responder.write("data: " + text + "\n\n");
}
else {
console.log(text);
}
}
//读取指定卡组
var readDeck = function(deck_name, deck_full_path) {
var deck={};
deck.name=deck_name;
deck_text = fs.readFileSync(deck_full_path, { encoding: "ASCII" });
deck_array = deck_text.split("\n");
deck.main = [];
deck.extra = [];
deck.side = [];
current_deck = deck.main;
for (l in deck_array) {
line = deck_array[l];
if (line.indexOf("#extra") >= 0) {
current_deck = deck.extra;
}
if (line.indexOf("!side") >= 0) {
current_deck = deck.side;
}
card = parseInt(line);
if (!isNaN(card)) {
current_deck.push(card);
}
}
return deck;
}
//读取指定文件夹中所有卡组
var getDecks = function() {
var decks=[];
var decks_list = fs.readdirSync(config.deck_path);
for (var k in decks_list) {
var deck_name = decks_list[k];
if (_.endsWith(deck_name, ".ydk")) {
var deck = readDeck(deck_name, config.deck_path+deck_name);
decks.push(deck);
}
}
return decks;
}
var delDeck = function(deck_name) {
var result=0;
try {
fs.unlinkSync(config.deck_path+deck_name);
result="已删除"+deck_name+"";
}
catch(e) {
result=e.toString();
}
finally {
return result;
}
}
var clearDecks = function() {
var decks_list = fs.readdirSync(config.deck_path);
for (var k in decks_list) {
var deck_name = decks_list[k];
if (_.endsWith(deck_name, ".ydk")) {
delDeck(deck_name);
}
}
}
var receiveDecks = function(files) {
var result=[];
for (var i in files) {
var file=files[i];
if (_.endsWith(file.name, ".ydk")) {
var deck=readDeck(file.name, file.path);
if (deck.main.length>=40) {
fs.createReadStream(file.path).pipe(fs.createWriteStream(config.deck_path+file.name));
result.push({
file: file.name,
status: "OK"
});
}
else {
result.push({
file: file.name,
status: "卡组不合格"
});
}
}
else {
result.push({
file: file.name,
status: "不是卡组文件"
});
}
}
return result;
}
//建立一个http服务器,接收API操作
http.createServer(function (req, res) {
var u = url.parse(req.url, true);
if (u.query.password !== config.password) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
if (u.pathname === '/api/upload_decks' && req.method.toLowerCase() == 'post') {
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {
"Access-Control-Allow-origin": "*",
'content-type': 'text/plain'
});
var result=receiveDecks(files);
//console.log(files);
res.end(JSON.stringify(result));
});
}
else if (u.pathname === '/api/msg') {
res.writeHead(200, {
"Access-Control-Allow-origin": "*",
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive"
});
res.on("close", function(){
responder = null;
});
responder = res;
sendResponse("已连接。");
}
else if (u.pathname === '/api/get_bg') {
res.writeHead(200);
res.end(u.query.callback+'('+JSON.stringify(config.wallpapers[Math.floor(Math.random() * config.wallpapers.length)])+');');
}
else if (u.pathname === '/api/get_decks') {
res.writeHead(200);
var decklist=getDecks();
res.end(u.query.callback+'('+JSON.stringify(decklist)+');');
}
else if (u.pathname === '/api/del_deck') {
res.writeHead(200);
var result=delDeck(u.query.msg);
res.end(u.query.callback+'("'+result+'");');
}
else if (u.pathname === '/api/clear_decks') {
res.writeHead(200);
clearDecks();
res.end(u.query.callback+'("已删除全部卡组。");');
}
else {
res.writeHead(400);
res.end("400");
}
}).listen(config.port);
_ = require 'underscore' _ = require 'underscore'
_.str = require 'underscore.string' _.str = require 'underscore.string'
_.mixin(_.str.exports()); _.mixin(_.str.exports())
Struct = require('struct').Struct Struct = require('./struct.js').Struct
#常量/类型声明 #常量/类型声明
structs_declaration = require './structs.json' #结构体声明 structs_declaration = require './structs.json' #结构体声明
...@@ -137,17 +137,26 @@ for name, declaration of structs_declaration ...@@ -137,17 +137,26 @@ for name, declaration of structs_declaration
console.log "err stoc_send_hint_card_to_room" console.log "err stoc_send_hint_card_to_room"
return return
for client in room.players for client in room.players
@stoc_send client, 'GAME_MSG',{ @stoc_send client, 'GAME_MSG', {
curmsg: 2, curmsg: 2,
type: 10, type: 10,
player: 0, player: 0,
data: card data: card
} if client } if client
for client in room.watchers for client in room.watchers
@stoc_send client, 'GAME_MSG',{ @stoc_send client, 'GAME_MSG', {
curmsg: 2, curmsg: 2,
type: 10, type: 10,
player: 0, player: 0,
data: card data: card
} if client } if client
return return
@stoc_die = (client, msg)->
@stoc_send_chat(client, msg, @constants.COLORS.RED)
@stoc_send client, 'ERROR_MSG', {
msg: 1
code: 2
} if client
client.destroy() if client
return
\ No newline at end of file
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
_.mixin(_.str.exports()); _.mixin(_.str.exports());
Struct = require('struct').Struct; Struct = require('./struct.js').Struct;
structs_declaration = require('./structs.json'); structs_declaration = require('./structs.json');
...@@ -245,4 +245,17 @@ ...@@ -245,4 +245,17 @@
} }
}; };
this.stoc_die = function(client, msg) {
this.stoc_send_chat(client, msg, this.constants.COLORS.RED);
if (client) {
this.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
}
if (client) {
client.destroy();
}
};
}).call(this); }).call(this);
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