Commit 937769bf authored by nanahira's avatar nanahira

merge config

parents 78caea33 cfa53219
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
......@@ -6,6 +6,8 @@ coffeelint.json
password.json
config.*.json
/bak
/config
/ygopro
/windbot
/decks/
......@@ -30,3 +32,5 @@ $RECYCLE.BIN/
.DS_Store
*.csv
config.user.bak
\ No newline at end of file
......@@ -21,19 +21,16 @@
### 使用方法
* 可参考[wiki](https://github.com/mercury233/ygopro-server/wiki)安装
* 手动安装:
* 安装修改后的YGOPro服务端:https://github.com/moecube/ygopro/tree/server
* `git clone https://github.com/moecube/srvpro.git`
* `cd srvpro`
* `npm install`
*`config.json`复制为`config.user.json`并进行修改
* `port`为你想要的端口
* ~~更多选项参见wiki~~
* 安装修改后的YGOPro服务端:https://github.com/moecube/ygopro/tree/server
* `node ygopro-server.js`即可运行
* 简易的控制台在 http://mercury233.me/ygosrv233/dashboard.html
* 简易的控制台在 http://srvpro.ygo233.com/dashboard.html
### 高级功能
* 待补充说明
* 简易的先行卡更新控制台在 http://mercury233.me/ygosrv233/pre-dashboard.html
* 简易的先行卡更新控制台在 http://srvpro.ygo233.com/pre-dashboard.html
### 开发计划
* 重做CTOS和STOC部分
......@@ -64,7 +61,7 @@
### License
SRVPro
Copyright (C) 2013-2017 MoeCube Team
Copyright (C) 2013-2018 MoeCube Team
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
......
{
"file": "./config/config.json",
"port": 7210,
"version": 4924,
"version": 4930,
"hostinfo": {
"lflist": 0,
"rule": 0,
......@@ -39,7 +40,7 @@
"get": "http://mercury233.me/ygosrv233/dialogues.json"
},
"words": {
"enabled": true,
"enabled": false,
"get": false
},
"music": {
......@@ -69,10 +70,10 @@
"auth_key": "233333"
},
"deck_log": {
"enabled": true,
"enabled": false,
"accesskey": "233",
"local": "./decks_save/",
"post": false,
"local": "./deck_log/",
"post": "https://api.mycard.moe/ygopro/analytics/deck/text",
"arena": "233"
},
"big_brother": {
......@@ -121,7 +122,9 @@
"cdn": {
"enabled": false,
"exe": "upx",
"params": ["sync"],
"params": [
"sync"
],
"local": "./ygosrv233",
"remote": "/ygosrv233",
"pics_remote": "/ygopro/"
......@@ -134,18 +137,51 @@
"html_gits": [
{
"name": "GitHub",
"push": ["push", "origin"]
"push": [
"push",
"origin"
]
},
{
"name": "Coding",
"push": ["push", "coding", "master:master"]
"push": [
"push",
"coding",
"master:master"
]
}
]
},
"update_util": {
"enabled": false,
"port": 7955,
"password": "123456",
"git_html_path": "../ygo233-web/",
"html_path": "../ygo233-web/",
"changelog_filename": "changelog.json",
"html_gits": [
{
"name": "GitHub",
"push": [
"push",
"origin"
]
},
{
"name": "Coding",
"push": [
"push",
"coding",
"master:master"
]
}
]
},
"command": {
"enabled": true,
"identity": {
"Nanahira": "Halozy"
"username1": "password1",
"username1": "password2"
},
"command_list": {
"ygopro": {
......@@ -235,31 +271,12 @@
"ban": {
"banned_user": [],
"banned_ip": [],
"badword_level0": ["滚", "衮", "操", "草", "艹", "狗", "日", "曰", "妈", "娘", "逼"],
"badword_level1": ["傻逼", "鸡巴"],
"badword_level2": ["死妈", "草你妈"],
"badword_level3": ["迷奸", "仿真枪"],
"illegal_id": ["^Lv\\.-*\\d+\\s*(.*)", "^VIP\\.\\d+\\s*(.*)"],
"spam_word": ["——"]
},
"tips": [
"欢迎来到本服务器",
"本服务器使用萌卡代码搭建"
],
"words": {
"test1": [
"test_word_1"
],
"test2": [
"test_word_2"
]
},
"dialogues": {
"46986414": [
"出来吧,我最强的仆人,黑魔导!"
"illegal_id": [
"^Lv\\.-*\\d+\\s*(.*)",
"^VIP\\.\\d+\\s*(.*)"
],
"58481572": [
"我们来做朋友吧!"
"spam_word": [
"——"
]
}
}
\ No newline at end of file
{
"file": "./config/config.json",
"port": 7911,
"version": 4924,
"version": 4930,
"hostinfo": {
"lflist": 0,
"rule": 0,
......@@ -121,7 +122,9 @@
"cdn": {
"enabled": false,
"exe": "upx",
"params": ["sync"],
"params": [
"sync"
],
"local": "./ygosrv233",
"remote": "/ygosrv233",
"pics_remote": "/ygopro/"
......@@ -134,11 +137,43 @@
"html_gits": [
{
"name": "GitHub",
"push": ["push", "origin"]
"push": [
"push",
"origin"
]
},
{
"name": "Coding",
"push": ["push", "coding", "master:master"]
"push": [
"push",
"coding",
"master:master"
]
}
]
},
"update_util": {
"enabled": false,
"port": 7955,
"password": "123456",
"git_html_path": "../ygo233-web/",
"html_path": "../ygo233-web/",
"changelog_filename": "changelog.json",
"html_gits": [
{
"name": "GitHub",
"push": [
"push",
"origin"
]
},
{
"name": "Coding",
"push": [
"push",
"coding",
"master:master"
]
}
]
},
......@@ -236,31 +271,12 @@
"ban": {
"banned_user": [],
"banned_ip": [],
"badword_level0": ["滚", "衮", "操", "草", "艹", "狗", "日", "曰", "妈", "娘", "逼"],
"badword_level1": ["傻逼", "鸡巴"],
"badword_level2": ["死妈", "草你妈"],
"badword_level3": ["迷奸", "仿真枪"],
"illegal_id": ["^Lv\\.-*\\d+\\s*(.*)", "^VIP\\.\\d+\\s*(.*)"],
"spam_word": ["——"]
},
"tips": [
"欢迎来到本服务器",
"本服务器使用萌卡代码搭建"
],
"words": {
"test1": [
"test_word_1"
],
"test2": [
"test_word_2"
]
},
"dialogues": {
"46986414": [
"出来吧,我最强的仆人,黑魔导!"
"illegal_id": [
"^Lv\\.-*\\d+\\s*(.*)",
"^VIP\\.\\d+\\s*(.*)"
],
"58481572": [
"我们来做朋友吧!"
"spam_word": [
"——"
]
}
}
\ No newline at end of file
{
"badwords": {
"file": "./config/badwords.json",
"level0": ["滚", "衮", "操", "草", "艹", "狗", "日", "曰", "妈", "娘", "逼"],
"level1": ["傻逼", "鸡巴"],
"level2": ["死妈", "草你妈"],
"level3": ["迷奸", "仿真枪"]
},
"tips": {
"file": "./config/tips.json",
"tips": [
"欢迎来到本服务器",
"本服务器使用萌卡代码搭建"
]
},
"words": {
"test1": [
"test_word_1"
],
"test2": [
"test_word_2"
]
},
"dialogues": {
"file": "./config/dialogues.json",
"dialogues": {
"46986414": [
"出来吧,我最强的仆人,黑魔导!"
],
"58481572": [
"我们来做朋友吧!"
]
}
}
}
\ No newline at end of file
{
"port": 7911,
"modules": {
"welcome": "MyCard YGOPro Server",
"update": "请更新游戏版本,可在社区(https://ygobbs.com)手动下载更新包",
"tips": {
"enabled": true,
"get": "http://mycard.moe/tips.json"
},
"dialogues": {
"enabled": true,
"get": "http://mercury233.me/ygosrv233/dialogues.json"
},
"mycard": {
"enabled": true,
"auth_base_url": "https://ygobbs.com",
"auth_database": "postgres://233@233.mycard.moe/233",
"auth_key": "233333"
},
"deck_log": {
"enabled": true,
"accesskey": "233",
"local": false,
"post": "https://api.mycard.moe/ygopro/analytics/deck/text",
"arena": "mycard"
},
"arena_mode": {
"enabled": true,
"mode": "entertain",
"comment": "mode: athletic / entertain",
"accesskey": "233",
"post_score": "https://mycard.moe/ygopro/api/score",
"get_score": "https://mycard.moe/ygopro/api/user?username="
},
"windbot": {
"enabled": true,
"botlist": "./windbot/bots.json",
"spawn": false,
"port": 2399
},
"http": {
"port": 7922,
"password": "123456",
"websocket_roomlist": true,
"ssl": {
"enabled": true,
"port": 7923,
"cert": "ssl/fullchain.pem",
"key": "ssl/privkey.pem"
}
}
}
}
......@@ -11,8 +11,8 @@
"author": "zh99998 <zh99998@gmail.com>, mercury233 <me@mercury233.me>",
"dependencies": {
"bunyan": "latest",
"deepmerge": "latest",
"moment": "latest",
"nconf": "latest",
"redis": "latest",
"formidable": "latest",
"request": "latest",
......
......@@ -8,8 +8,8 @@
*/
var sqlite3 = require('sqlite3').verbose();
var fs = require('fs');
var config = require('./config.deckstats.json'); //{ "deckpath": "../decks", "dbfile": "cards.cdb" }
var constants = require('./constants.json');
var config = require('./config/deckstats.json'); //{ "deckpath": "../decks", "dbfile": "cards.cdb" }
var constants = require('./data/constants.json');
var ALL_MAIN_CARDS={};
var ALL_SIDE_CARDS={};
......
......@@ -16,13 +16,9 @@ var url = require('url');
var moment = require('moment');
moment.locale('zh-cn');
var constants = require('./constants.json');
var constants = require('./data/constants.json');
var nconf = require('nconf');
nconf.file('./config.user.json');
var defaultconfig = require('./config.json');
nconf.defaults(defaultconfig);
var settings = nconf.get();
var settings = require('./config/config.json');
config=settings.modules.pre_util;
//全卡HTML列表
......
......@@ -39,20 +39,58 @@ moment.locale('zh-cn', {
}
})
merge = require 'deepmerge'
#heapdump = require 'heapdump'
# 配置
# use nconf to save user config.user.json .
# config.json shouldn't be changed
nconf = require 'nconf'
nconf.file('./config.user.json')
defaultconfig = require('./config.json')
nconf.defaults(defaultconfig)
settings = global.settings = nconf.get()
nconf.myset = (settings, path, val) ->
# 导入旧配置
if not fs.existsSync('./config')
fs.mkdirSync('./config')
try
oldconfig=require('./config.user.json')
if oldconfig.tips
oldtips = {}
oldtips.file = './config/tips.json'
oldtips.tips = oldconfig.tips
fs.writeFileSync(oldtips.file, JSON.stringify(oldtips, null, 2))
delete oldconfig.tips
if oldconfig.dialogues
olddialogues = {}
olddialogues.file = './config/dialogues.json'
olddialogues.dialogues = oldconfig.dialogues
fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2))
delete oldconfig.dialogues
oldbadwords={}
if oldconfig.ban.badword_level0
oldbadwords.level0 = oldconfig.ban.badword_level0
if oldconfig.ban.badword_level1
oldbadwords.level1 = oldconfig.ban.badword_level1
if oldconfig.ban.badword_level2
oldbadwords.level2 = oldconfig.ban.badword_level2
if oldconfig.ban.badword_level3
oldbadwords.level3 = oldconfig.ban.badword_level3
if not _.isEmpty(oldbadwords)
oldbadwords.file = './config/badwords.json'
fs.writeFileSync(oldbadwords.file, JSON.stringify(oldbadwords, null, 2))
delete oldconfig.ban.badword_level0
delete oldconfig.ban.badword_level1
delete oldconfig.ban.badword_level2
delete oldconfig.ban.badword_level3
if not _.isEmpty(oldconfig)
# log.info oldconfig
fs.writeFileSync('./config/config.json', JSON.stringify(oldconfig, null, 2))
log.info 'imported old config from config.user.json'
fs.renameSync('./config.user.json', './config.user.bak')
catch e
log.info e unless e.code == 'MODULE_NOT_FOUND'
setting_save = (settings) ->
fs.writeFileSync(settings.file, JSON.stringify(settings, null, 2))
return
setting_change = (settings, path, val) ->
# path should be like "modules:welcome"
nconf.set(path, val)
nconf.save()
log.info("setting changed", path, val) if _.isString(val)
path=path.split(':')
if path.length == 0
......@@ -64,17 +102,44 @@ nconf.myset = (settings, path, val) ->
target=target[key]
key = path.shift()
target[key] = val
setting_save(settings)
return
# 读取配置
default_config = require('./data/default_config.json')
try
config = require('./config/config.json')
catch
config = {}
settings = global.settings = merge(default_config, config, { arrayMerge: (destination, source) -> source })
# 读取数据
default_data = require('./data/default_data.json')
try
tips = require('./config/tips.json')
catch
tips = default_data.tips
setting_save(tips)
try
dialogues = require('./config/dialogues.json')
catch
dialogues = default_data.dialogues
setting_save(dialogues)
try
badwords = require('./config/badwords.json')
catch
badwords = default_data.badwords
setting_save(badwords)
try
cppversion = parseInt(fs.readFileSync('ygopro/gframe/game.cpp', 'utf8').match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16')
nconf.myset(settings, "version", cppversion)
setting_change(settings, "version", cppversion)
log.info "ygopro version 0x"+settings.version.toString(16), "(from source code)"
catch
#settings.version = settings.version_default
log.info "ygopro version 0x"+settings.version.toString(16), "(from config)"
# load the lflist of current date
settings.lflist = (for list in fs.readFileSync('ygopro/lflist.conf', 'utf8').match(/!.*/g)
lflists = (for list in fs.readFileSync('ygopro/lflist.conf', 'utf8').match(/!.*/g)
date=list.match(/!([\d\.]+)/)
continue unless date
{date: moment(list.match(/!([\d\.]+)/)[1], 'YYYY.MM.DD').utcOffset("-08:00"), tcg: list.indexOf('TCG') != -1})
......@@ -88,7 +153,16 @@ if settings.modules.cloud_replay.enabled
return
if settings.modules.windbot.enabled
settings.modules.windbots = require(settings.modules.windbot.botlist).windbots
windbots = require(settings.modules.windbot.botlist).windbots
if settings.modules.tournament_mode.enabled
duel_log = {}
clearlog = () ->
duel_log = {}
duel_log.file = 'duel_log.' + moment().format('YYYY-MM-DD HH-mm-ss') + '.json'
duel_log.duel_log = []
setting_save(duel_log)
clearlog()
# 组件
ygopro = require './ygopro.js'
......@@ -148,7 +222,7 @@ ROOM_bad_ip = {}
# ban a user manually and permanently
ban_user = (name) ->
settings.ban.banned_user.push(name)
nconf.myset(settings, "ban:banned_user", settings.ban.banned_user)
setting_save(settings)
bad_ip=0
for room in ROOM_all when room and room.established
for player in room.players
......@@ -240,17 +314,17 @@ ROOM_find_or_create_ai = (name)->
if room = ROOM_find_by_name(name)
return room
else if uname == 'AI'
windbot = _.sample settings.modules.windbots
windbot = _.sample windbots
name = 'AI#' + Math.floor(Math.random() * 100000)
else if namea.length>1
ainame = namea[namea.length-1]
windbot = _.sample _.filter settings.modules.windbots, (w)->
windbot = _.sample _.filter windbots, (w)->
w.name == ainame or w.deck == ainame
if !windbot
return { "error": "${windbot_deck_not_found}" }
name = name + ',' + Math.floor(Math.random() * 100000)
else
windbot = _.sample settings.modules.windbots
windbot = _.sample windbots
name = name + '#' + Math.floor(Math.random() * 100000)
if name.replace(/[^\x00-\xff]/g,"00").length>20
log.info "long ai name", name
......@@ -317,9 +391,9 @@ class Room
ROOM_all.push this
@hostinfo ||= JSON.parse(JSON.stringify(settings.hostinfo))
if settings.lflist.length
if lflists.length
if @hostinfo.rule == 1 and @hostinfo.lflist == 0
@hostinfo.lflist = _.findIndex settings.lflist, (list)-> list.tcg
@hostinfo.lflist = _.findIndex lflists, (list)-> list.tcg
else
@hostinfo.lflist = -1
@hostinfo.replay_mode = if settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.replay_safe then 1 else 0
......@@ -355,7 +429,7 @@ class Room
if (rule.match /(^|,|,)(TCGONLY|TO)(,|,|$)/)
@hostinfo.rule = 1
@hostinfo.lflist = _.findIndex settings.lflist, (list)-> list.tcg
@hostinfo.lflist = _.findIndex lflists, (list)-> list.tcg
if (rule.match /(^|,|,)(OCGONLY|OO)(,|,|$)/)
@hostinfo.rule = 0
......@@ -444,6 +518,9 @@ class Room
log.info "YGOPRO " + data
ygopro.stoc_send_chat_to_room this, data, ygopro.constants.COLORS.RED
@has_ygopro_error = true
@ygopro_error_length = if @ygopro_error_length then @ygopro_error_length + data.length else data.length
if @ygopro_error_length > 10000
@process.kill()
return
catch
@error = "${create_room_failed}"
......@@ -833,6 +910,9 @@ net.createServer (client) ->
log.info "server started", settings.port
return
if settings.modules.stop
log.info "NOTE: server not open due to config, ", settings.modules.stop
# 功能模块
# return true to cancel a synchronous message
......@@ -985,7 +1065,7 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
start_hand: opt3 >> 4
draw_count: opt3 & 0xF
}
options.lflist = _.findIndex settings.lflist, (list)-> ((options.rule == 1) == list.tcg) and list.date.isBefore()
options.lflist = _.findIndex lflists, (list)-> ((options.rule == 1) == list.tcg) and list.date.isBefore()
room = new Room(name, options)
room.title = info.pass.slice(8).replace(String.fromCharCode(0xFEFF), ' ')
room.private = action == 2
......@@ -1079,6 +1159,7 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
else if _.indexOf(settings.ban.banned_user, client.name) > -1 #账号被封
settings.ban.banned_ip.push(client.ip)
setting_save(settings)
log.warn("BANNED USER LOGIN", client.name, client.ip)
ygopro.stoc_die(client, "${banned_user_login}")
......@@ -1086,21 +1167,21 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
log.warn("BANNED IP LOGIN", client.name, client.ip)
ygopro.stoc_die(client, "${banned_ip_login}")
else if _.any(settings.ban.badword_level3, (badword) ->
else if _.any(badwords.level3, (badword) ->
regexp = new RegExp(badword, 'i')
return name.match(regexp)
, name = client.name)
log.warn("BAD NAME LEVEL 3", client.name, client.ip)
ygopro.stoc_die(client, "${bad_name_level3}")
else if _.any(settings.ban.badword_level2, (badword) ->
else if _.any(badwords.level2, (badword) ->
regexp = new RegExp(badword, 'i')
return name.match(regexp)
, name = client.name)
log.warn("BAD NAME LEVEL 2", client.name, client.ip)
ygopro.stoc_die(client, "${bad_name_level2}")
else if _.any(settings.ban.badword_level1, (badword) ->
else if _.any(badwords.level1, (badword) ->
regexp = new RegExp(badword, 'i')
return name.match(regexp)
, name = client.name)
......@@ -1224,8 +1305,8 @@ load_dialogues = () ->
else if error or !body
log.warn 'dialogues error', error, response
else
nconf.myset(settings, "dialogues", body)
log.info "dialogues loaded", _.size body
setting_change(dialogues, "dialogues", body)
log.info "dialogues loaded", _.size dialogues.dialogues
return
return
......@@ -1326,8 +1407,8 @@ ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)->
if settings.modules.dialogues.enabled
if ygopro.constants.MSG[msg] == 'SUMMONING' or ygopro.constants.MSG[msg] == 'SPSUMMONING'
card = buffer.readUInt32LE(1)
if settings.dialogues[card]
for line in _.lines settings.dialogues[card][Math.floor(Math.random() * settings.dialogues[card].length)]
if 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)
return
......@@ -1446,12 +1527,12 @@ wait_room_start_arena = (room)->
#tip
ygopro.stoc_send_random_tip = (client)->
if settings.modules.tips.enabled && settings.tips.length
ygopro.stoc_send_chat(client, "Tip: " + settings.tips[Math.floor(Math.random() * settings.tips.length)])
if settings.modules.tips.enabled && tips.tips.length
ygopro.stoc_send_chat(client, "Tip: " + tips.tips[Math.floor(Math.random() * tips.tips.length)])
return
ygopro.stoc_send_random_tip_to_room = (room)->
if settings.modules.tips.enabled && settings.tips.length
ygopro.stoc_send_chat_to_room(room, "Tip: " + settings.tips[Math.floor(Math.random() * settings.tips.length)])
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)])
return
load_tips = ()->
......@@ -1464,8 +1545,8 @@ load_tips = ()->
else if error or !body
log.warn 'tips error', error, response
else
nconf.myset(settings, "tips", body)
log.info "tips loaded", settings.tips.length
setting_change(tips, "tips", body)
log.info "tips loaded", tips.tips.length
return
return
......@@ -1597,13 +1678,13 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
when '/ai'
if settings.modules.windbot.enabled
if name = cmd[1]
windbot = _.sample _.filter settings.modules.windbots, (w)->
windbot = _.sample _.filter windbots, (w)->
w.name == name or w.deck == name
if !windbot
ygopro.stoc_send_chat(client, "${windbot_deck_not_found}", ygopro.constants.COLORS.RED)
return
else
windbot = _.sample settings.modules.windbots
windbot = _.sample windbots
room.add_windbot(windbot)
when '/roomname'
......@@ -1623,7 +1704,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
ygopro.stoc_send_chat(client, "${banned_chat_tip}", ygopro.constants.COLORS.RED)
return true
oldmsg = msg
if (_.any(settings.ban.badword_level3, (badword) ->
if (_.any(badwords.level3, (badword) ->
regexp = new RegExp(badword, 'i')
return msg.match(regexp)
, msg))
......@@ -1651,7 +1732,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
client.abuse_count=client.abuse_count+2
ygopro.stoc_send_chat(client, "${chat_warn_level0}", ygopro.constants.COLORS.RED)
cancel = true
else if (_.any(settings.ban.badword_level2, (badword) ->
else if (_.any(badwords.level2, (badword) ->
regexp = new RegExp(badword, 'i')
return msg.match(regexp)
, msg))
......@@ -1661,7 +1742,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
ygopro.stoc_send_chat(client, "${chat_warn_level2}", ygopro.constants.COLORS.RED)
cancel = true
else
_.each(settings.ban.badword_level1, (badword) ->
_.each(badwords.level1, (badword) ->
#log.info msg
regexp = new RegExp(badword, "ig")
msg = msg.replace(regexp, "**")
......@@ -1676,7 +1757,7 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server)->
struct._setBuff(buffer)
struct.set("msg", msg)
buffer = struct.buffer
else if (_.any(settings.ban.badword_level0, (badword) ->
else if (_.any(badwords.level0, (badword) ->
regexp = new RegExp(badword, 'i')
return msg.match(regexp)
, msg))
......@@ -1816,8 +1897,8 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server)->
winner: player.pos == room.winner
)
}
settings.modules.tournament_mode.duel_log.unshift duellog
nconf.myset(settings, "modules:tournament_mode:duel_log", settings.modules.tournament_mode.duel_log)
duel_log.duel_log.unshift duellog
setting_save(duel_log)
fs.writeFile(settings.modules.tournament_mode.replay_path + replay_filename, buffer, (err)->
if err then log.warn "SAVE REPLAY ERROR", replay_filename, err
)
......@@ -1924,7 +2005,7 @@ if settings.modules.http
return
else
response.writeHead(200)
duellog = JSON.stringify settings.modules.tournament_mode.duel_log, null, 2
duellog = JSON.stringify duel_log.duel_log, null, 2
response.end(addCallback(u.query.callback, duellog))
else if u.pathname == '/api/archive.zip' and settings.modules.tournament_mode.enabled
......@@ -1937,7 +2018,7 @@ if settings.modules.http
archive_name = moment().format('YYYY-MM-DD HH:mm:ss') + ".zip"
archive_args = ["a", "-mx0", "-y", archive_name]
check = false
for replay in settings.modules.tournament_mode.duel_log
for replay in duel_log.duel_log
check = true
archive_args.push(replay.replay_filename)
if !check
......@@ -1977,8 +2058,7 @@ if settings.modules.http
return
else
response.writeHead(200)
settings.modules.tournament_mode.duel_log = []
nconf.myset(settings, "modules:tournament_mode:duel_log", settings.modules.tournament_mode.duel_log)
clearlog()
response.end(addCallback(u.query.callback, "[{name:'Success'}]"))
else if _.startsWith(u.pathname, '/api/replay') and settings.modules.tournament_mode.enabled
......@@ -2013,12 +2093,12 @@ if settings.modules.http
else if u.query.stop
if u.query.stop == 'false'
u.query.stop = false
settings.modules.stop = u.query.stop
setting_change(settings, 'modules:stop', u.query.stop)
response.writeHead(200)
response.end(addCallback(u.query.callback, "['stop ok', '" + u.query.stop + "']"))
else if u.query.welcome
nconf.myset(settings, 'modules:welcome', u.query.welcome)
setting_change(settings, 'modules:welcome', u.query.welcome)
response.writeHead(200)
response.end(addCallback(u.query.callback, "['welcome ok', '" + u.query.welcome + "']"))
......
// Generated by CoffeeScript 1.12.7
(function() {
var Cloud_replay_ids, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_connected_ip, ROOM_find_by_name, 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_players_banned, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, Room, _, addCallback, ban_user, bunyan, cppversion, crypto, date, defaultconfig, execFile, fs, geoip, get_memory_usage, http, http_server, https, https_server, list, load_dialogues, load_tips, log, moment, nconf, net, options, os, path, pgClient, pg_client, pg_query, redis, redisdb, report_to_big_brother, request, requestListener, roomlist, settings, spawn, spawnSync, url, users_cache, wait_room_start, wait_room_start_arena, windbot_bin, windbot_parameters, windbot_process, ygopro, zlib;
var Cloud_replay_ids, ROOM_all, ROOM_bad_ip, ROOM_ban_player, ROOM_connected_ip, ROOM_find_by_name, 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_players_banned, ROOM_players_oppentlist, ROOM_unwelcome, ROOM_validate, Room, _, addCallback, badwords, ban_user, bunyan, clearlog, config, cppversion, crypto, date, default_config, default_data, dialogues, duel_log, e, execFile, fs, geoip, get_memory_usage, http, http_server, https, https_server, lflists, list, load_dialogues, load_tips, log, merge, moment, net, oldbadwords, oldconfig, olddialogues, oldtips, options, os, path, pgClient, pg_client, pg_query, redis, redisdb, report_to_big_brother, request, requestListener, roomlist, setting_change, setting_save, settings, spawn, spawnSync, tips, url, users_cache, wait_room_start, wait_room_start_arena, windbot_bin, windbot_parameters, windbot_process, windbots, ygopro, zlib;
var words, oldwords;
net = require('net');
......@@ -56,20 +58,74 @@
}
});
nconf = require('nconf');
nconf.file('./config.user.json');
merge = require('deepmerge');
defaultconfig = require('./config.json');
if (!fs.existsSync('./config')) {
fs.mkdirSync('./config');
}
nconf.defaults(defaultconfig);
try {
oldconfig = require('./config.user.json');
if (oldconfig.tips) {
oldtips = {};
oldtips.file = './config/tips.json';
oldtips.tips = oldconfig.tips;
fs.writeFileSync(oldtips.file, JSON.stringify(oldtips, null, 2));
delete oldconfig.tips;
}
if (oldconfig.words) {
oldwords = {};
olddialogues.file = './config/words.json';
olddialogues.words = oldconfig.words;
fs.writeFileSync(olddialogues.file, JSON.stringify(oldwords, null, 2));
delete oldconfig.words;
}
if (oldconfig.dialogues) {
olddialogues = {};
olddialogues.file = './config/dialogues.json';
olddialogues.dialogues = oldconfig.dialogues;
fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2));
delete oldconfig.dialogues;
}
oldbadwords = {};
if (oldconfig.ban.badword_level0) {
oldbadwords.level0 = oldconfig.ban.badword_level0;
}
if (oldconfig.ban.badword_level1) {
oldbadwords.level1 = oldconfig.ban.badword_level1;
}
if (oldconfig.ban.badword_level2) {
oldbadwords.level2 = oldconfig.ban.badword_level2;
}
if (oldconfig.ban.badword_level3) {
oldbadwords.level3 = oldconfig.ban.badword_level3;
}
if (!_.isEmpty(oldbadwords)) {
oldbadwords.file = './config/badwords.json';
fs.writeFileSync(oldbadwords.file, JSON.stringify(oldbadwords, null, 2));
delete oldconfig.ban.badword_level0;
delete oldconfig.ban.badword_level1;
delete oldconfig.ban.badword_level2;
delete oldconfig.ban.badword_level3;
}
if (!_.isEmpty(oldconfig)) {
fs.writeFileSync('./config/config.json', JSON.stringify(oldconfig, null, 2));
log.info('imported old config from config.user.json');
}
fs.renameSync('./config.user.json', './config.user.bak');
} catch (error1) {
e = error1;
if (e.code !== 'MODULE_NOT_FOUND') {
log.info(e);
}
}
settings = global.settings = nconf.get();
setting_save = function(settings) {
fs.writeFileSync(settings.file, JSON.stringify(settings, null, 2));
};
nconf.myset = function(settings, path, val) {
setting_change = function(settings, path, val) {
var key, target;
nconf.set(path, val);
nconf.save();
if (_.isString(val)) {
log.info("setting changed", path, val);
}
......@@ -85,17 +141,55 @@
key = path.shift();
target[key] = val;
}
setting_save(settings);
};
default_config = require('./data/default_config.json');
try {
config = require('./config/config.json');
} catch (error1) {
config = {};
}
settings = global.settings = merge(default_config, config, {
arrayMerge: function(destination, source) {
return source;
}
});
default_data = require('./data/default_data.json');
try {
tips = require('./config/tips.json');
} catch (error1) {
tips = default_data.tips;
setting_save(tips);
}
try {
dialogues = require('./config/dialogues.json');
} catch (error1) {
dialogues = default_data.dialogues;
setting_save(dialogues);
}
try {
badwords = require('./config/badwords.json');
} catch (error1) {
badwords = default_data.badwords;
setting_save(badwords);
}
try {
cppversion = parseInt(fs.readFileSync('ygopro/gframe/game.cpp', 'utf8').match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16');
nconf.myset(settings, "version", cppversion);
setting_change(settings, "version", cppversion);
log.info("ygopro version 0x" + settings.version.toString(16), "(from source code)");
} catch (error1) {
log.info("ygopro version 0x" + settings.version.toString(16), "(from config)");
}
settings.lflist = (function() {
lflists = (function() {
var j, len, ref, ref_custom, results;
results = [];
try {
......@@ -142,7 +236,18 @@
}
if (settings.modules.windbot.enabled) {
settings.modules.windbots = require(settings.modules.windbot.botlist).windbots;
windbots = require(settings.modules.windbot.botlist).windbots;
}
if (settings.modules.tournament_mode.enabled) {
duel_log = {};
clearlog = function() {
duel_log = {};
duel_log.file = 'duel_log.' + moment().format('YYYY-MM-DD HH-mm-ss') + '.json';
duel_log.duel_log = [];
return setting_save(duel_log);
};
clearlog();
}
ygopro = require('./ygopro.js');
......@@ -211,7 +316,7 @@
ban_user = function(name) {
var bad_ip, j, k, len, len1, player, ref, room;
settings.ban.banned_user.push(name);
nconf.myset(settings, "ban:banned_user", settings.ban.banned_user);
setting_save(settings);
bad_ip = 0;
for (j = 0, len = ROOM_all.length; j < len; j++) {
room = ROOM_all[j];
......@@ -342,11 +447,11 @@
if (room = ROOM_find_by_name(name)) {
return room;
} else if (uname === 'AI') {
windbot = _.sample(settings.modules.windbots);
windbot = _.sample(windbots);
name = 'AI#' + Math.floor(Math.random() * 100000);
} else if (namea.length > 1) {
ainame = namea[namea.length - 1];
windbot = _.sample(_.filter(settings.modules.windbots, function(w) {
windbot = _.sample(_.filter(windbots, function(w) {
return w.name === ainame || w.deck === ainame;
}));
if (!windbot) {
......@@ -356,7 +461,7 @@
}
name = name + ',' + Math.floor(Math.random() * 100000);
} else {
windbot = _.sample(settings.modules.windbots);
windbot = _.sample(windbots);
name = name + '#' + Math.floor(Math.random() * 100000);
}
if (name.replace(/[^\x00-\xff]/g, "00").length > 20) {
......@@ -452,9 +557,9 @@
this.death = 0;
ROOM_all.push(this);
this.hostinfo || (this.hostinfo = JSON.parse(JSON.stringify(settings.hostinfo)));
if (settings.lflist.length) {
if (lflists.length) {
if (this.hostinfo.rule === 1 && this.hostinfo.lflist === 0) {
this.hostinfo.lflist = _.findIndex(settings.lflist, function(list) {
this.hostinfo.lflist = _.findIndex(lflists, function(list) {
return list.tcg;
});
}
......@@ -492,7 +597,7 @@
}
if (rule.match(/(^|,|,)(TCGONLY|TO)(,|,|$)/)) {
this.hostinfo.rule = 1;
this.hostinfo.lflist = _.findIndex(settings.lflist, function(list) {
this.hostinfo.lflist = _.findIndex(lflists, function(list) {
return list.tcg;
});
}
......@@ -617,6 +722,10 @@
log.info("YGOPRO " + data);
ygopro.stoc_send_chat_to_room(_this, data, ygopro.constants.COLORS.RED);
_this.has_ygopro_error = true;
_this.ygopro_error_length = _this.ygopro_error_length ? _this.ygopro_error_length + data.length : data.length;
if (_this.ygopro_error_length > 10000) {
_this.process.kill();
}
};
})(this));
} catch (error1) {
......@@ -1084,6 +1193,10 @@
log.info("server started", settings.port);
});
if (settings.modules.stop) {
log.info("NOTE: server not open due to config, ", settings.modules.stop);
}
ygopro.ctos_follow('PLAYER_INFO', true, function(buffer, info, client, server) {
var geo, lang, name, struct;
name = info.name.split("$")[0];
......@@ -1228,7 +1341,7 @@
start_hand: opt3 >> 4,
draw_count: opt3 & 0xF
};
options.lflist = _.findIndex(settings.lflist, function(list) {
options.lflist = _.findIndex(lflists, function(list) {
return ((options.rule === 1) === list.tcg) && list.date.isBefore();
});
room = new Room(name, options);
......@@ -1339,26 +1452,27 @@
ygopro.stoc_die(client, "${too_much_connection}" + client.ip);
} else if (_.indexOf(settings.ban.banned_user, client.name) > -1) {
settings.ban.banned_ip.push(client.ip);
setting_save(settings);
log.warn("BANNED USER LOGIN", client.name, client.ip);
ygopro.stoc_die(client, "${banned_user_login}");
} else if (_.indexOf(settings.ban.banned_ip, client.ip) > -1) {
log.warn("BANNED IP LOGIN", client.name, client.ip);
ygopro.stoc_die(client, "${banned_ip_login}");
} else if (_.any(settings.ban.badword_level3, function(badword) {
} else if (_.any(badwords.level3, function(badword) {
var regexp;
regexp = new RegExp(badword, 'i');
return name.match(regexp);
}, name = client.name)) {
log.warn("BAD NAME LEVEL 3", client.name, client.ip);
ygopro.stoc_die(client, "${bad_name_level3}");
} else if (_.any(settings.ban.badword_level2, function(badword) {
} else if (_.any(badwords.level2, function(badword) {
var regexp;
regexp = new RegExp(badword, 'i');
return name.match(regexp);
}, name = client.name)) {
log.warn("BAD NAME LEVEL 2", client.name, client.ip);
ygopro.stoc_die(client, "${bad_name_level2}");
} else if (_.any(settings.ban.badword_level1, function(badword) {
} else if (_.any(badwords.level1, function(badword) {
var regexp;
regexp = new RegExp(badword, 'i');
return name.match(regexp);
......@@ -1403,8 +1517,8 @@
if (!room) {
return;
}
if (settings.modules.words.enabled && settings.words[client.name]) {
var player_words = _.lines(settings.words[client.name][Math.floor(Math.random() * settings.words[client.name].length)]);
if (settings.modules.words.enabled && words.words[client.name]) {
var player_words = _.lines(words.words[client.name][Math.floor(Math.random() * words.words[client.name].length)]);
for (j = 0, len = player_words.length; j < len; j++) {
line = player_words[j];
ygopro.stoc_send_chat_to_room(room, line, ygopro.constants.COLORS.PINK);
......@@ -1492,7 +1606,7 @@
} else if (error || !body) {
log.warn('words error', error, response);
} else {
nconf.myset(settings, "words", body);
setting_change(words, "words", body);
log.info("words loaded", _.size(body));
}
});
......@@ -1512,8 +1626,8 @@
} else if (error || !body) {
log.warn('dialogues error', error, response);
} else {
nconf.myset(settings, "dialogues", body);
log.info("dialogues loaded", _.size(body));
setting_change(dialogues, "dialogues", body);
log.info("dialogues loaded", _.size(dialogues.dialogues));
}
});
};
......@@ -1642,8 +1756,8 @@
if (settings.modules.dialogues.enabled) {
if (ygopro.constants.MSG[msg] === 'SUMMONING' || ygopro.constants.MSG[msg] === 'SPSUMMONING') {
card = buffer.readUInt32LE(1);
if (settings.dialogues[card]) {
ref2 = _.lines(settings.dialogues[card][Math.floor(Math.random() * settings.dialogues[card].length)]);
if (dialogues.dialogues[card]) {
ref2 = _.lines(dialogues.dialogues[card][Math.floor(Math.random() * dialogues.dialogues[card].length)]);
for (j = 0, len = ref2.length; j < len; j++) {
line = ref2[j];
ygopro.stoc_send_chat(client, line, ygopro.constants.COLORS.PINK);
......@@ -1823,14 +1937,14 @@
};
ygopro.stoc_send_random_tip = function(client) {
if (settings.modules.tips.enabled && settings.tips.length) {
ygopro.stoc_send_chat(client, "Tip: " + settings.tips[Math.floor(Math.random() * settings.tips.length)]);
if (settings.modules.tips.enabled && tips.tips.length) {
ygopro.stoc_send_chat(client, "Tip: " + tips.tips[Math.floor(Math.random() * tips.tips.length)]);
}
};
ygopro.stoc_send_random_tip_to_room = function(room) {
if (settings.modules.tips.enabled && settings.tips.length) {
ygopro.stoc_send_chat_to_room(room, "Tip: " + settings.tips[Math.floor(Math.random() * settings.tips.length)]);
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)]);
}
};
......@@ -1844,8 +1958,8 @@
} else if (error || !body) {
log.warn('tips error', error, response);
} else {
nconf.myset(settings, "tips", body);
log.info("tips loaded", settings.tips.length);
setting_change(tips, "tips", body);
log.info("tips loaded", tips.tips.length);
}
});
};
......@@ -2065,7 +2179,7 @@
case '/ai':
if (settings.modules.windbot.enabled) {
if (name = cmd[1]) {
windbot = _.sample(_.filter(settings.modules.windbots, function(w) {
windbot = _.sample(_.filter(windbots, function(w) {
return w.name === name || w.deck === name;
}));
if (!windbot) {
......@@ -2073,7 +2187,7 @@
return;
}
} else {
windbot = _.sample(settings.modules.windbots);
windbot = _.sample(windbots);
}
room.add_windbot(windbot);
}
......@@ -2149,7 +2263,7 @@
return true;
}
oldmsg = msg;
if (_.any(settings.ban.badword_level3, function(badword) {
if (_.any(badwords.level3, function(badword) {
var regexp;
regexp = new RegExp(badword, 'i');
return msg.match(regexp);
......@@ -2178,7 +2292,7 @@
client.abuse_count = client.abuse_count + 2;
ygopro.stoc_send_chat(client, "${chat_warn_level0}", ygopro.constants.COLORS.RED);
cancel = true;
} else if (_.any(settings.ban.badword_level2, function(badword) {
} else if (_.any(badwords.level2, function(badword) {
var regexp;
regexp = new RegExp(badword, 'i');
return msg.match(regexp);
......@@ -2189,7 +2303,7 @@
ygopro.stoc_send_chat(client, "${chat_warn_level2}", ygopro.constants.COLORS.RED);
cancel = true;
} else {
_.each(settings.ban.badword_level1, function(badword) {
_.each(badwords.level1, function(badword) {
var regexp;
regexp = new RegExp(badword, "ig");
msg = msg.replace(regexp, "**");
......@@ -2203,7 +2317,7 @@
struct._setBuff(buffer);
struct.set("msg", msg);
buffer = struct.buffer;
} else if (_.any(settings.ban.badword_level0, function(badword) {
} else if (_.any(badwords.level0, function(badword) {
var regexp;
regexp = new RegExp(badword, 'i');
return msg.match(regexp);
......@@ -2417,8 +2531,8 @@
return results;
})()
};
settings.modules.tournament_mode.duel_log.unshift(duellog);
nconf.myset(settings, "modules:tournament_mode:duel_log", settings.modules.tournament_mode.duel_log);
duel_log.duel_log.unshift(duellog);
setting_save(duel_log);
fs.writeFile(settings.modules.tournament_mode.replay_path + replay_filename, buffer, function(err) {
if (err) {
return log.warn("SAVE REPLAY ERROR", replay_filename, err);
......@@ -2568,7 +2682,7 @@
return;
} else {
response.writeHead(200);
duellog = JSON.stringify(settings.modules.tournament_mode.duel_log, null, 2);
duellog = JSON.stringify(duel_log.duel_log, null, 2);
response.end(addCallback(u.query.callback, duellog));
}
} else if (u.pathname === '/api/archive.zip' && settings.modules.tournament_mode.enabled) {
......@@ -2581,7 +2695,7 @@
archive_name = moment().format('YYYY-MM-DD HH:mm:ss') + ".zip";
archive_args = ["a", "-mx0", "-y", archive_name];
check = false;
ref = settings.modules.tournament_mode.duel_log;
ref = duel_log.duel_log;
for (j = 0, len = ref.length; j < len; j++) {
replay = ref[j];
check = true;
......@@ -2642,8 +2756,7 @@
return;
} else {
response.writeHead(200);
settings.modules.tournament_mode.duel_log = [];
nconf.myset(settings, "modules:tournament_mode:duel_log", settings.modules.tournament_mode.duel_log);
clearlog();
response.end(addCallback(u.query.callback, "[{name:'Success'}]"));
}
} else if (_.startsWith(u.pathname, '/api/replay') && settings.modules.tournament_mode.enabled) {
......@@ -2708,11 +2821,11 @@
if (u.query.stop === 'false') {
u.query.stop = false;
}
settings.modules.stop = u.query.stop;
setting_change(settings, 'modules:stop', u.query.stop);
response.writeHead(200);
response.end(addCallback(u.query.callback, "['stop ok', '" + u.query.stop + "']"));
} else if (u.query.welcome) {
nconf.myset(settings, 'modules:welcome', u.query.welcome);
setting_change(settings, 'modules:welcome', u.query.welcome);
response.writeHead(200);
response.end(addCallback(u.query.callback, "['welcome ok', '" + u.query.welcome + "']"));
} else if (u.query.getwelcome) {
......
......@@ -15,11 +15,7 @@ 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();
var settings = require('./config/config.json');
config=settings.modules.tournament_mode;
//http长连接
......
/*
ygopro-update.js
ygopro update util (not fully implymented)
Author: mercury233
License: MIT
不带参数运行时,会建立一个服务器,调用API执行对应操作
TODO:带参数运行时执行对应操作后退出
*/
var http = require('http');
var sqlite3 = require('sqlite3').verbose();
var fs = require('fs');
var execSync = require('child_process').execSync;
var spawn = require('child_process').spawn;
var spawnSync = require('child_process').spawnSync;
var url = require('url');
var moment = require('moment');
moment.locale('zh-cn');
var constants = require('./data/constants.json');
var settings = require('./config/config.json');
config=settings.modules.update_util;
//全卡名称列表
var cardNames={};
//
var changelog=[];
//http长连接
var responder;
//输出反馈信息,如有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);
}
}
//读取数据库内内容到cardNames,异步
var loadDb = function(db_file) {
var db = new sqlite3.Database(db_file);
db.each("select id,name from texts", function (err,result) {
if (err) {
sendResponse(db_file + ":" + err);
return;
}
else {
cardNames[result.id] = result.name;
}
}, function(err, num) {
if(err) {
sendResponse(db_file + ":" + err);
}
else {
sendResponse("已加载数据库"+db_file+",共"+num+"张卡。");
}
});
}
var loadChangelog = function(json_file) {
changelog = JSON.parse(fs.readFileSync(json_file, 'utf8')).changelog;
sendResponse("已加载更新记录"+json_file+",共"+changelog.length+"条,最后更新于"+changelog[0].date+"");
}
var makeChangelogs = function(dir, since) {
var lastcommit;
var addedCards=[];
var changedCards=[];
var prc_git_log = spawnSync("git", [ "log", "--pretty=%H,%ai", since ], { "cwd" : dir });
if (prc_git_log.stdout) {
var logs = prc_git_log.stdout.toString().split(/\n/g);
for (var i in logs) {
var log = logs[i].split(",");
var date = log[1];
if (date) {
var prc_git_diff = spawnSync("git", [ "diff-tree", "--no-commit-id", "--name-only" ,"--diff-filter=A" , "-r", log[0] ], { "cwd" : dir });
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/);
if (line) {
var name = cardNames[line[1]] || line[1];
addedCards.push(name);
sendResponse("<span class='add'>" + date + " + " + name + "</span>");
}
}
}
}
}
for (var i in logs) {
var log = logs[i].split(",");
var date = log[1];
if (date) {
var prc_git_diff = spawnSync("git", [ "diff-tree", "--no-commit-id", "--name-only" ,"--diff-filter=ad" , "-r", log[0] ], { "cwd" : dir });
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/);
if (line) {
var name = cardNames[line[1]] || line[1];
sendResponse("<span class='change'>" + date + " * " + name + "</span>");
if (!addedCards.includes(name) && !changedCards.includes(name)) {
changedCards.push(name);
}
}
}
}
}
}
sendResponse("新增卡片:");
for (var i in addedCards) {
sendResponse("-&nbsp;&nbsp;&nbsp;" + addedCards[i]);
}
if (addedCards.length == 0) {
sendResponse("-&nbsp;&nbsp;&nbsp;无");
}
sendResponse("\n");
sendResponse("卡片更改:");
for (var i in changedCards) {
sendResponse("-&nbsp;&nbsp;&nbsp;" + changedCards[i]);
}
if (changedCards.length == 0) {
sendResponse("-&nbsp;&nbsp;&nbsp;无");
}
} else {
sendResponse("获取更新记录失败:" + prc_git_log.stderr.toString());
}
}
//从远程更新数据库,异步
var fetchDatas = function() {
var proc = spawn("git", ["pull", "origin", "master"], { cwd: config.git_db_path, env: process.env });
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', function(data) {
sendResponse("git pull: "+data);
});
proc.stderr.setEncoding('utf8');
proc.stderr.on('data', function(data) {
sendResponse("git pull: "+data);
});
proc.on('close', function (code) {
sendResponse("数据更新完成。");
});
var proc2 = spawn("git", ["pull", "origin", "master"], { cwd: config.git_html_path, env: process.env });
proc2.stdout.setEncoding('utf8');
proc2.stdout.on('data', function(data) {
sendResponse("git pull: "+data);
});
proc2.stderr.setEncoding('utf8');
proc2.stderr.on('data', function(data) {
sendResponse("git pull: "+data);
});
proc2.on('close', function (code) {
sendResponse("网页同步完成。");
});
}
//建立一个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/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/load_db') {
res.writeHead(200);
res.end(u.query.callback+'({"message":"开始加载数据库。"});');
loadDb("./ygopro/cards.cdb");
loadChangelog(config.html_path + config.changelog_filename);
}
else if (u.pathname === '/api/make_changelog') {
res.writeHead(200);
var date = moment(changelog[0].date).add(1,'days').format("YYYY-MM-DD");
res.end(u.query.callback+'({"message":"开始生成'+ date +'以来的更新记录:"});');
makeChangelogs("./ygopro/script", "--since="+date);
}
else if (u.pathname === '/api/make_more_changelog') {
res.writeHead(200);
res.end(u.query.callback+'({"message":"开始生成最近20次的更新记录:"});');
makeChangelogs("./ygopro/script", "-20");
}
else if (u.pathname === '/api/push_datas') {
res.writeHead(200);
res.end(u.query.callback+'({"message":"开始上传到网页。"});');
pushDatas();
}
else if (u.pathname === '/api/write_to_file') {
res.writeHead(200);
res.end(u.query.callback+'({"message":"开始写列表页。"});');
writeToFile(u.query.message);
}
else {
res.writeHead(400);
res.end("400");
}
}).listen(config.port);
......@@ -4,13 +4,13 @@ _.mixin(_.str.exports())
Struct = require('./struct.js').Struct
i18ns = require './i18n.json'
i18ns = require './data/i18n.json'
#常量/类型声明
structs_declaration = require './structs.json' #结构体声明
typedefs = require './typedefs.json' #类型声明
@proto_structs = require './proto_structs.json' #消息与结构体的对应,未完成,对着duelclient.cpp加
@constants = require './constants.json' #network.h里定义的常量
structs_declaration = require './data/structs.json' #结构体声明
typedefs = require './data/typedefs.json' #类型声明
@proto_structs = require './data/proto_structs.json' #消息与结构体的对应,未完成,对着duelclient.cpp加
@constants = require './data/constants.json' #network.h里定义的常量
#结构体定义
@structs = {}
......
......@@ -10,15 +10,15 @@
Struct = require('./struct.js').Struct;
i18ns = require('./i18n.json');
i18ns = require('./data/i18n.json');
structs_declaration = require('./structs.json');
structs_declaration = require('./data/structs.json');
typedefs = require('./typedefs.json');
typedefs = require('./data/typedefs.json');
this.proto_structs = require('./proto_structs.json');
this.proto_structs = require('./data/proto_structs.json');
this.constants = require('./constants.json');
this.constants = require('./data/constants.json');
this.structs = {};
......
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