Commit de15fb02 authored by nanahira's avatar nanahira

fixes

parent 028febf3
...@@ -14,6 +14,7 @@ config.user.bak ...@@ -14,6 +14,7 @@ config.user.bak
/windbot /windbot
/decks /decks
/decks_save* /decks_save*
/deck_log
/replays /replays
/node_modules /node_modules
/ssl /ssl
......
...@@ -14,6 +14,7 @@ config.user.bak ...@@ -14,6 +14,7 @@ config.user.bak
/windbot /windbot
/decks /decks
/decks_save* /decks_save*
/deck_log
/replays /replays
/node_modules /node_modules
/ssl /ssl
......
...@@ -117,7 +117,7 @@ class Replay ...@@ -117,7 +117,7 @@ class Replay
@header == null ? false : @header.isTag @header == null ? false : @header.isTag
@fromFile: (filePath) -> @fromFile: (filePath) ->
Replay.fromBuffer fs.readFileSync filePath Replay.fromBuffer await fs.promises.readFile filePath
@fromBuffer: (buffer) -> @fromBuffer: (buffer) ->
reader = new ReplayReader buffer reader = new ReplayReader buffer
......
...@@ -175,8 +175,8 @@ ...@@ -175,8 +175,8 @@
}; };
} }
static fromFile(filePath) { static async fromFile(filePath) {
return Replay.fromBuffer(fs.readFileSync(filePath)); return Replay.fromBuffer((await fs.promises.readFile(filePath)));
} }
static fromBuffer(buffer) { static fromBuffer(buffer) {
......
...@@ -232,14 +232,22 @@ class DataManager { ...@@ -232,14 +232,22 @@ class DataManager {
return allDuelLogs.map(duelLog => duelLog.replayFileName); return allDuelLogs.map(duelLog => duelLog.replayFileName);
} }
async clearDuelLog() { async clearDuelLog() {
const repo = this.db.getRepository(DuelLog_1.DuelLog); //await this.db.transaction(async (mdb) => {
const runner = this.db.createQueryRunner();
try { try {
await repo.clear(); await runner.connect();
await runner.startTransaction();
await runner.query("SET FOREIGN_KEY_CHECKS = 0; ");
await runner.clearTable("duel_log_player");
await runner.clearTable("duel_log");
await runner.query("SET FOREIGN_KEY_CHECKS = 1; ");
await runner.commitTransaction();
} }
catch (e) { catch (e) {
await runner.rollbackTransaction();
this.log.warn(`Failed to clear duel logs: ${e.toString()}`); this.log.warn(`Failed to clear duel logs: ${e.toString()}`);
return [];
} }
//});
} }
async saveDuelLog(name, roomId, cloudReplayId, replayFilename, roomMode, duelCount, playerInfos) { async saveDuelLog(name, roomId, cloudReplayId, replayFilename, roomMode, duelCount, playerInfos) {
const duelLog = new DuelLog_1.DuelLog(); const duelLog = new DuelLog_1.DuelLog();
......
...@@ -262,13 +262,21 @@ export class DataManager { ...@@ -262,13 +262,21 @@ export class DataManager {
return allDuelLogs.map(duelLog => duelLog.replayFileName); return allDuelLogs.map(duelLog => duelLog.replayFileName);
} }
async clearDuelLog() { async clearDuelLog() {
const repo = this.db.getRepository(DuelLog); //await this.db.transaction(async (mdb) => {
const runner = this.db.createQueryRunner();
try { try {
await repo.clear(); await runner.connect();
await runner.startTransaction();
await runner.query("SET FOREIGN_KEY_CHECKS = 0; ");
await runner.clearTable("duel_log_player");
await runner.clearTable("duel_log");
await runner.query("SET FOREIGN_KEY_CHECKS = 1; ");
await runner.commitTransaction();
} catch (e) { } catch (e) {
await runner.rollbackTransaction();
this.log.warn(`Failed to clear duel logs: ${e.toString()}`); this.log.warn(`Failed to clear duel logs: ${e.toString()}`);
return [];
} }
//});
} }
async saveDuelLog(name: string, roomId: number, cloudReplayId: number, replayFilename: string, roomMode: number, duelCount: number, playerInfos: DuelLogPlayerInfo[]) { async saveDuelLog(name: string, roomId: number, cloudReplayId: number, replayFilename: string, roomMode: number, duelCount: number, playerInfos: DuelLogPlayerInfo[]) {
const duelLog = new DuelLog(); const duelLog = new DuelLog();
......
...@@ -27,7 +27,7 @@ let DuelLog = class DuelLog { ...@@ -27,7 +27,7 @@ let DuelLog = class DuelLog {
getViewJSON(tournamentModeSettings) { getViewJSON(tournamentModeSettings) {
const data = { const data = {
id: this.id, id: this.id,
time: moment_1.default(this.time).format("YYYY-MM-DD HH-mm-ss"), time: moment_1.default(this.time).format("YYYY-MM-DD HH:mm:ss"),
name: this.name + (tournamentModeSettings.show_info ? " (Duel:" + this.duelCount + ")" : ""), name: this.name + (tournamentModeSettings.show_info ? " (Duel:" + this.duelCount + ")" : ""),
roomid: this.roomId, roomid: this.roomId,
cloud_replay_id: "R#" + this.cloudReplayId, cloud_replay_id: "R#" + this.cloudReplayId,
...@@ -42,6 +42,7 @@ let DuelLog = class DuelLog { ...@@ -42,6 +42,7 @@ let DuelLog = class DuelLog {
}; };
}) })
}; };
return data;
} }
}; };
__decorate([ __decorate([
......
...@@ -44,7 +44,7 @@ export class DuelLog { ...@@ -44,7 +44,7 @@ export class DuelLog {
getViewJSON(tournamentModeSettings: any) { getViewJSON(tournamentModeSettings: any) {
const data = { const data = {
id: this.id, id: this.id,
time: moment(this.time).format("YYYY-MM-DD HH-mm-ss"), time: moment(this.time).format("YYYY-MM-DD HH:mm:ss"),
name: this.name + (tournamentModeSettings.show_info ? " (Duel:" + this.duelCount + ")" : ""), name: this.name + (tournamentModeSettings.show_info ? " (Duel:" + this.duelCount + ")" : ""),
roomid: this.roomId, roomid: this.roomId,
cloud_replay_id: "R#" + this.cloudReplayId, cloud_replay_id: "R#" + this.cloudReplayId,
...@@ -59,5 +59,6 @@ export class DuelLog { ...@@ -59,5 +59,6 @@ export class DuelLog {
} }
}) })
} }
return data;
} }
} }
\ No newline at end of file
...@@ -426,6 +426,11 @@ ...@@ -426,6 +426,11 @@
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
}, },
"coffeescript": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz",
"integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ=="
},
"color-convert": { "color-convert": {
"version": "1.9.3", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
...@@ -1988,6 +1993,11 @@ ...@@ -1988,6 +1993,11 @@
} }
} }
}, },
"typescript": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz",
"integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ=="
},
"ultron": { "ultron": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
"axios": "^0.19.2", "axios": "^0.19.2",
"bunyan": "^1.8.14", "bunyan": "^1.8.14",
"challonge": "latest", "challonge": "latest",
"coffeescript": "^2.5.1",
"deepmerge": "latest", "deepmerge": "latest",
"formidable": "latest", "formidable": "latest",
"geoip-country-lite": "latest", "geoip-country-lite": "latest",
...@@ -32,12 +33,14 @@ ...@@ -32,12 +33,14 @@
"request": "latest", "request": "latest",
"sqlite3": "latest", "sqlite3": "latest",
"typeorm": "^0.2.29", "typeorm": "^0.2.29",
"typescript": "^4.0.5",
"underscore": "latest", "underscore": "latest",
"underscore.string": "latest", "underscore.string": "latest",
"ws": "^1.1.1" "ws": "^1.1.1"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
"build": "coffee -c *.coffee && tsc",
"start": "node ygopro-server.js", "start": "node ygopro-server.js",
"tournament": "node ygopro-tournament.js", "tournament": "node ygopro-tournament.js",
"pre": "node ygopro-pre.js", "pre": "node ygopro-pre.js",
......
...@@ -107,13 +107,6 @@ try ...@@ -107,13 +107,6 @@ try
olddialogues.dialogues = oldconfig.dialogues olddialogues.dialogues = oldconfig.dialogues
fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2)) fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2))
delete oldconfig.dialogues delete oldconfig.dialogues
if oldconfig.modules
if oldconfig.modules.tournament_mode and oldconfig.modules.tournament_mode.duel_log
oldduellog = {}
oldduellog.file = './config/duel_log.json'
oldduellog.duel_log = oldconfig.modules.tournament_mode.duel_log
fs.writeFileSync(oldduellog.file, JSON.stringify(oldduellog, null, 2))
delete oldconfig.oldduellog
oldbadwords={} oldbadwords={}
if oldconfig.ban if oldconfig.ban
if oldconfig.ban.badword_level0 if oldconfig.ban.badword_level0
...@@ -139,15 +132,14 @@ try ...@@ -139,15 +132,14 @@ try
catch e catch e
log.info e unless e.code == 'ENOENT' log.info e unless e.code == 'ENOENT'
setting_save = global.setting_save = (settings, callback) -> setting_save = global.setting_save = (settings) ->
if !callback try
callback = (err) -> await fs.promises.writeFile(settings.file, JSON.stringify(settings, null, 2))
if(err) catch e
log.warn("setting save fail", err.toString()) log.warn("setting save fail", e.toString())
fs.writeFile(settings.file, JSON.stringify(settings, null, 2), callback)
return return
setting_change = global.setting_change = (settings, path, val, callback) -> setting_change = global.setting_change = (settings, path, val) ->
# path should be like "modules:welcome" # path should be like "modules:welcome"
log.info("setting changed", path, val) if _.isString(val) log.info("setting changed", path, val) if _.isString(val)
path=path.split(':') path=path.split(':')
...@@ -160,7 +152,7 @@ setting_change = global.setting_change = (settings, path, val, callback) -> ...@@ -160,7 +152,7 @@ setting_change = global.setting_change = (settings, path, val, callback) ->
target=target[key] target=target[key]
key = path.shift() key = path.shift()
target[key] = val target[key] = val
setting_save(settings, callback) await setting_save(settings)
return return
# 读取配置 # 读取配置
...@@ -262,11 +254,6 @@ try ...@@ -262,11 +254,6 @@ try
catch catch
badwords = global.badwords = default_data.badwords badwords = global.badwords = default_data.badwords
setting_save(badwords) setting_save(badwords)
try
duel_log = global.duel_log = loadJSON('./config/duel_log.json')
catch
duel_log = global.duel_log = default_data.duel_log
setting_save(duel_log)
try try
chat_color = global.chat_color = loadJSON('./config/chat_color.json') chat_color = global.chat_color = loadJSON('./config/chat_color.json')
catch catch
...@@ -333,10 +320,19 @@ if settings.modules.mysql.enabled ...@@ -333,10 +320,19 @@ if settings.modules.mysql.enabled
dataManager = global.dataManager = new DataManager(settings.modules.mysql.db, log) dataManager = global.dataManager = new DataManager(settings.modules.mysql.db, log)
dataManager.init().then(() -> log.info("Database ready.")) dataManager.init().then(() -> log.info("Database ready."))
else else
log.warn("Some functions may be limited without MySQL .")
if settings.modules.cloud_replay.enabled if settings.modules.cloud_replay.enabled
settings.modules.cloud_replay.enabled = false settings.modules.cloud_replay.enabled = false
setting_save(settings) setting_save(settings)
log.warn("Cloud replay cannot be enabled because no MySQL.") log.warn("Cloud replay cannot be enabled because no MySQL.")
if settings.modules.enable_recover.enabled
settings.modules.enable_recover.enabled = false
setting_save(settings)
log.warn("Recover mode cannot be enabled because no MySQL.")
if settings.modules.chat_color.enabled
settings.modules.chat_color.enabled = false
setting_save(settings)
log.warn("Chat color cannot be enabled because no MySQL.")
if settings.modules.mycard.enabled if settings.modules.mycard.enabled
pgClient = require('pg').Client pgClient = require('pg').Client
...@@ -515,7 +511,7 @@ ROOM_kick = (name, callback)-> ...@@ -515,7 +511,7 @@ ROOM_kick = (name, callback)->
done() done()
return return
found = true found = true
room.termiate() room.terminate()
done() done()
, (err)-> , (err)->
callback(null, found) callback(null, found)
...@@ -592,7 +588,12 @@ ROOM_find_or_create_by_name = global.ROOM_find_or_create_by_name = (name, player ...@@ -592,7 +588,12 @@ ROOM_find_or_create_by_name = global.ROOM_find_or_create_by_name = (name, player
else if memory_usage >= 90 else if memory_usage >= 90
return null return null
else else
return new Room(name) room = new Room(name)
if room.recover_duel_log_id
success = await room.initialize_recover()
if !success
return {"error": "${cloud_replay_no}"}
return room
ROOM_find_or_create_random = global.ROOM_find_or_create_random = (type, player_ip)-> ROOM_find_or_create_random = global.ROOM_find_or_create_random = (type, player_ip)->
if settings.modules.mysql.enabled if settings.modules.mysql.enabled
...@@ -1190,14 +1191,7 @@ class Room ...@@ -1190,14 +1191,7 @@ class Room
@recovered = true @recovered = true
@recovering = true @recovering = true
@recover_from_turn = parseInt(param[4]) @recover_from_turn = parseInt(param[4])
duel_log_id = parseInt(param[3]) @recover_duel_log_id = parseInt(param[3])
@recover_duel_log = _.find(duel_log.duel_log, (duel) ->
return duel.id == duel_log_id and duel.roommode != 2 and duel.players[0].deck
)
if !@recover_duel_log || !fs.existsSync(settings.modules.tournament_mode.replay_path + @recover_duel_log.replay_filename)
@error = "${cloud_replay_no}"
return
@recover_replay = ReplayParser.fromFile(settings.modules.tournament_mode.replay_path + @recover_duel_log.replay_filename)
@recover_buffers = [[], [], [], []] @recover_buffers = [[], [], [], []]
@welcome = "${recover_hint}" @welcome = "${recover_hint}"
...@@ -1208,12 +1202,16 @@ class Room ...@@ -1208,12 +1202,16 @@ class Room
if (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) or (@hostinfo.mode == 1 and settings.modules.replay_delay) if (settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player) or (@hostinfo.mode == 1 and settings.modules.replay_delay)
@hostinfo.replay_mode |= 0x2 @hostinfo.replay_mode |= 0x2
if !@recovered
@spawn()
spawn: (firstSeed) ->
param = [0, @hostinfo.lflist, @hostinfo.rule, @hostinfo.mode, @hostinfo.duel_rule, param = [0, @hostinfo.lflist, @hostinfo.rule, @hostinfo.mode, @hostinfo.duel_rule,
(if @hostinfo.no_check_deck then 'T' else 'F'), (if @hostinfo.no_shuffle_deck then 'T' else 'F'), (if @hostinfo.no_check_deck then 'T' else 'F'), (if @hostinfo.no_shuffle_deck then 'T' else 'F'),
@hostinfo.start_lp, @hostinfo.start_hand, @hostinfo.draw_count, @hostinfo.time_limit, @hostinfo.replay_mode] @hostinfo.start_lp, @hostinfo.start_hand, @hostinfo.draw_count, @hostinfo.time_limit, @hostinfo.replay_mode]
if @recovered if firstSeed
param.push(@recover_replay.header.seed) param.push(firstSeed)
seeds = getSeedTimet(2) seeds = getSeedTimet(2)
param.push(seeds[i]) for i in [0...2] param.push(seeds[i]) for i in [0...2]
else else
...@@ -1362,6 +1360,23 @@ class Room ...@@ -1362,6 +1360,23 @@ class Room
roomlist.delete this if !@windbot and @established and settings.modules.http.websocket_roomlist roomlist.delete this if !@windbot and @established and settings.modules.http.websocket_roomlist
return return
initialize_recover: ->
@recover_duel_log = await dataManager.getDuelLogFromId(@recover_duel_log_id)
#console.log(@recover_duel_log, fs.existsSync(settings.modules.tournament_mode.replay_path + @recover_duel_log.replayFileName))
if !@recover_duel_log || !fs.existsSync(settings.modules.tournament_mode.replay_path + @recover_duel_log.replayFileName)
@terminate()
return false
try
@recover_replay = await ReplayParser.fromFile(settings.modules.tournament_mode.replay_path + @recover_duel_log.replayFileName)
@spawn(@recover_replay.header.seed)
return true
catch e
log.warn("LOAD RECOVER REPLAY FAIL", e.toString())
@terminate()
return false
get_playing_player: -> get_playing_player: ->
playing_player = [] playing_player = []
_.each @players, (player)-> _.each @players, (player)->
...@@ -1553,19 +1568,22 @@ class Room ...@@ -1553,19 +1568,22 @@ class Room
ygopro.stoc_send_chat_to_room(this, "${death_cancel}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(this, "${death_cancel}", ygopro.constants.COLORS.BABYBLUE)
return true return true
termiate: -> terminate: ->
if @duel_stage != ygopro.constants.DUEL_STAGE.BEGIN if @duel_stage != ygopro.constants.DUEL_STAGE.BEGIN
@scores[@dueling_players[0].name_vpass] = 0 @scores[@dueling_players[0].name_vpass] = 0
@scores[@dueling_players[1].name_vpass] = 0 @scores[@dueling_players[1].name_vpass] = 0
@kicked = true @kicked = true
@send_replays() @send_replays()
if @process
try
@process.kill() @process.kill()
catch e
@delete() @delete()
finish_recover: (fail) -> finish_recover: (fail) ->
if fail if fail
ygopro.stoc_send_chat_to_room(this, "${recover_fail}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(this, "${recover_fail}", ygopro.constants.COLORS.RED)
@termiate() @terminate()
else else
ygopro.stoc_send_chat_to_room(this, "${recover_success}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat_to_room(this, "${recover_success}", ygopro.constants.COLORS.BABYBLUE)
@recovering = false @recovering = false
...@@ -1861,26 +1879,14 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -1861,26 +1879,14 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
else if info.pass.toUpperCase()=="RC" and settings.modules.tournament_mode.enable_recover else if info.pass.toUpperCase()=="RC" and settings.modules.tournament_mode.enable_recover
ygopro.stoc_send_chat(client,"${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client,"${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE)
available_logs = duel_log.duel_log.filter((duel) -> available_logs = await dataManager.getDuelLogFromRecoverSearch(client.name_vpass)
return duel.id and duel.players[0].deck and duel.roommode != 2 and _.any(duel.players, (player) -> for duelLog in available_logs
return player.real_name == client.name_vpass ygopro.stoc_send_chat(client, duelLog.getViewString(), ygopro.constants.COLORS.BABYBLUE)
)
).slice(0, 8)
_.each(available_logs, (duel) ->
player_names = duel.players[0].real_name.split("$")[0] + (if duel.players[2] then "+" + duel.players[2].real_name.split("$")[0] else "") +
" VS " +
(if duel.players[1] then duel.players[1].real_name.split("$")[0] else "AI") +
(if duel.players[3] then "+" + duel.players[3].real_name.split("$")[0] else "")
ygopro.stoc_send_chat(client,"<#{duel.id}> #{player_names} #{duel.time}", ygopro.constants.COLORS.BABYBLUE)
)
# 强行等待异步执行完毕_(:з」∠)_
setTimeout (()->
ygopro.stoc_send client, 'ERROR_MSG',{ ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1 msg: 1
code: 9 code: 9
} }
CLIENT_kick(client) CLIENT_kick(client)
return), 500
else if info.pass[0...2].toUpperCase()=="R#" and settings.modules.cloud_replay.enabled else if info.pass[0...2].toUpperCase()=="R#" and settings.modules.cloud_replay.enabled
replay_id=info.pass.split("#")[1] replay_id=info.pass.split("#")[1]
...@@ -2128,6 +2134,8 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)-> ...@@ -2128,6 +2134,8 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
if(err) if(err)
ygopro.stoc_die(client, err) ygopro.stoc_die(client, err)
return return
create_room_with_action(data.get_user.original, data.get_user.decrypted, data.match_permit) create_room_with_action(data.get_user.original, data.get_user.decrypted, data.match_permit)
) )
...@@ -3219,13 +3227,14 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)-> ...@@ -3219,13 +3227,14 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)->
room.last_active_time = moment() room.last_active_time = moment()
if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.recovering if room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.recovering
recover_player_data = _.find(room.recover_duel_log.players, (player) -> recover_player_data = _.find(room.recover_duel_log.players, (player) ->
return player.real_name == client.name_vpass and _.isEqual(buffer, Buffer.from(player.deckbuf, "base64")) return player.realName == client.name_vpass and buffer.toString("base64") == player.startDeckBuffer
) )
if recover_player_data if recover_player_data
struct.set("mainc", recover_player_data.deck.main.length) recoveredDeck = recover_player_data.getCurrentDeck()
struct.set("sidec", recover_player_data.deck.side.length) struct.set("mainc", recoveredDeck.main.length)
struct.set("deckbuf", recover_player_data.deck.main.concat(recover_player_data.deck.side)) struct.set("sidec", recoveredDeck.side.length)
if recover_player_data.is_first struct.set("deckbuf", recoveredDeck.main.concat(recoveredDeck.side))
if recover_player_data.isFirst
room.determine_firstgo = client room.determine_firstgo = client
else else
struct.set("mainc", 1) struct.set("mainc", 1)
...@@ -3475,10 +3484,9 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)-> ...@@ -3475,10 +3484,9 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
if !room.replays[room.duel_count - 1] if !room.replays[room.duel_count - 1]
# console.log("Replay saved: ", room.duel_count - 1, client.pos) # console.log("Replay saved: ", room.duel_count - 1, client.pos)
room.replays[room.duel_count - 1] = buffer room.replays[room.duel_count - 1] = buffer
if settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.replay_safe or settings.modules.tournament_mode.enable_recover if settings.modules.mysql.enabled
if client.pos == 0 if client.pos == 0
dueltime=moment().format('YYYY-MM-DD HH-mm-ss') replay_filename=moment().format("YYYY-MM-DD HH-mm-ss")
replay_filename=dueltime
if room.hostinfo.mode != 2 if room.hostinfo.mode != 2
for player,i in room.dueling_players for player,i in room.dueling_players
replay_filename=replay_filename + (if i > 0 then " VS " else " ") + player.name replay_filename=replay_filename + (if i > 0 then " VS " else " ") + player.name
...@@ -3486,32 +3494,28 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)-> ...@@ -3486,32 +3494,28 @@ ygopro.stoc_follow 'REPLAY', true, (buffer, info, client, server, datas)->
for player,i in room.dueling_players for player,i in room.dueling_players
replay_filename=replay_filename + (if i > 0 then (if i == 2 then " VS " else " & ") else " ") + player.name replay_filename=replay_filename + (if i > 0 then (if i == 2 then " VS " else " & ") else " ") + player.name
replay_filename=replay_filename.replace(/[\/\\\?\*]/g, '_')+".yrp" replay_filename=replay_filename.replace(/[\/\\\?\*]/g, '_')+".yrp"
duellog = { playerInfos = room.dueling_players.map((player) ->
id: duel_log.duel_log.length + 1, return {
time: dueltime, name: player.name
name: room.name + (if settings.modules.tournament_mode.show_info then (" (Duel:" + room.duel_count + ")") else ""), pos: player.pos
roomid: room.process_pid.toString(), realName: player.name_vpass
cloud_replay_id: "R#"+room.cloud_replay_id, startDeckBuffer: player.start_deckbuf
replay_filename: replay_filename,
roommode: room.hostinfo.mode,
players: (for player in room.dueling_players
real_name: player.name_vpass,
deckbuf: player.start_deckbuf.toString("base64"),
deck: { deck: {
main: player.main, main: player.main,
side: player.side side: player.side
} }
pos: player.pos isFirst: player.is_first
is_first: player.is_first
name: player.name + (if settings.modules.tournament_mode.show_ip and !player.is_local then (" (IP: " + player.ip.slice(7) + ")") else "") + (if settings.modules.tournament_mode.show_info and not (room.hostinfo.mode == 2 and player.pos % 2 > 0) then (" (Score:" + room.scores[player.name_vpass] + " LP:" + (if player.lp? then player.lp else room.hostinfo.start_lp) + (if room.hostinfo.mode != 2 then (" Cards:" + (if player.card_count? then player.card_count else room.hostinfo.start_hand)) else "") + ")") else ""),
winner: player.pos == room.winner winner: player.pos == room.winner
) ip: player.ip
score: room.scores[player.name_vpass]
lp: if player.lp? then player.lp else room.hostinfo.start_lp
cardCount: if player.card_count? then player.card_count else room.hostinfo.start_hand
} }
duel_log.duel_log.unshift duellog )
setting_save(duel_log)
fs.writeFile(settings.modules.tournament_mode.replay_path + replay_filename, buffer, (err)-> fs.writeFile(settings.modules.tournament_mode.replay_path + replay_filename, buffer, (err)->
if err then log.warn "SAVE REPLAY ERROR", replay_filename, err if err then log.warn "SAVE REPLAY ERROR", replay_filename, err
) )
dataManager.saveDuelLog(room.name, room.process_pid.toString(), room.cloud_replay_id, replay_filename, room.hostinfo.mode, room.duel_count, playerInfos) # no synchronize here because too slow
if settings.modules.cloud_replay.enabled and settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.replay_safe if settings.modules.cloud_replay.enabled and settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.replay_safe
ygopro.stoc_send_chat(client, "${cloud_replay_delay_part1}R##{room.cloud_replay_id}${cloud_replay_delay_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${cloud_replay_delay_part1}R##{room.cloud_replay_id}${cloud_replay_delay_part2}", ygopro.constants.COLORS.BABYBLUE)
await return settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player or settings.modules.replay_delay and room.hostinfo.mode == 1 await return settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.block_replay_to_player or settings.modules.replay_delay and room.hostinfo.mode == 1
...@@ -3671,17 +3675,17 @@ if settings.modules.http ...@@ -3671,17 +3675,17 @@ if settings.modules.http
) )
else if u.pathname == '/api/duellog' and settings.modules.tournament_mode.enabled else if u.pathname == '/api/duellog' and settings.modules.mysql.enabled
if !await auth.auth(u.query.username, u.query.pass, "duel_log", "duel_log") if !await auth.auth(u.query.username, u.query.pass, "duel_log", "duel_log")
response.writeHead(200) response.writeHead(200)
response.end(addCallback(u.query.callback, "[{name:'密码错误'}]")) response.end(addCallback(u.query.callback, "[{name:'密码错误'}]"))
return return
else else
response.writeHead(200) response.writeHead(200)
duellog = JSON.stringify duel_log.duel_log, null, 2 duellog = JSON.stringify(await dataManager.getDuelLogJSON(settings.modules.tournament_mode), null, 2)
response.end(addCallback(u.query.callback, duellog)) response.end(addCallback(u.query.callback, duellog))
else if u.pathname == '/api/archive.zip' and settings.modules.tournament_mode.enabled else if u.pathname == '/api/archive.zip' and settings.modules.mysql.enabled
if !await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay_archive") if !await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay_archive")
response.writeHead(403) response.writeHead(403)
response.end("Invalid password.") response.end("Invalid password.")
...@@ -3691,9 +3695,9 @@ if settings.modules.http ...@@ -3691,9 +3695,9 @@ if settings.modules.http
archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip" archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip"
archive_args = ["a", "-mx0", "-y", archive_name] archive_args = ["a", "-mx0", "-y", archive_name]
check = false check = false
for replay in duel_log.duel_log for filename in await dataManager.getAllReplayFilenames()
check = true check = true
archive_args.push(replay.replay_filename) archive_args.push(filename)
if !check if !check
response.writeHead(403) response.writeHead(403)
response.end("Duel logs not found.") response.end("Duel logs not found.")
...@@ -3724,7 +3728,7 @@ if settings.modules.http ...@@ -3724,7 +3728,7 @@ if settings.modules.http
response.writeHead(403) response.writeHead(403)
response.end("Failed reading replays. " + error) response.end("Failed reading replays. " + error)
else if u.pathname == '/api/clearlog' and settings.modules.tournament_mode.enabled else if u.pathname == '/api/clearlog' and settings.modules.mysql.enabled
if !await auth.auth(u.query.username, u.query.pass, "clear_duel_log", "clear_duel_log") if !await auth.auth(u.query.username, u.query.pass, "clear_duel_log", "clear_duel_log")
response.writeHead(200) response.writeHead(200)
response.end(addCallback(u.query.callback, "[{name:'密码错误'}]")) response.end(addCallback(u.query.callback, "[{name:'密码错误'}]"))
...@@ -3732,15 +3736,14 @@ if settings.modules.http ...@@ -3732,15 +3736,14 @@ if settings.modules.http
else else
response.writeHead(200) response.writeHead(200)
if settings.modules.tournament_mode.log_save_path if settings.modules.tournament_mode.log_save_path
fs.writeFile(settings.modules.tournament_mode.log_save_path + 'duel_log.' + moment().format('YYYY-MM-DD HH-mm-ss') + '.json', JSON.stringify(duel_log, null, 2), (err) -> fs.writeFile(settings.modules.tournament_mode.log_save_path + 'duel_log.' + moment().format('YYYY-MM-DD HH-mm-ss') + '.json', JSON.stringify(await dataManager.getDuelLogJSON(settings.modules.tournament_mode), null, 2), (err) ->
if err if err
log.warn 'DUEL LOG SAVE ERROR', err log.warn 'DUEL LOG SAVE ERROR', err
) )
duel_log.duel_log = [] await dataManager.clearDuelLog()
setting_save(duel_log)
response.end(addCallback(u.query.callback, "[{name:'Success'}]")) response.end(addCallback(u.query.callback, "[{name:'Success'}]"))
else if _.startsWith(u.pathname, '/api/replay') and settings.modules.tournament_mode.enabled else if _.startsWith(u.pathname, '/api/replay') and settings.modules.mysql.enabled
if !await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay") if !await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay")
response.writeHead(403) response.writeHead(403)
response.end("密码错误") response.end("密码错误")
...@@ -3791,7 +3794,7 @@ if settings.modules.http ...@@ -3791,7 +3794,7 @@ if settings.modules.http
u.query.stop = false u.query.stop = false
response.writeHead(200) response.writeHead(200)
try try
await util.promisify(setting_change)(settings, 'modules:stop', u.query.stop) await setting_change(settings, 'modules:stop', u.query.stop)
response.end(addCallback(u.query.callback, "['stop ok', '" + u.query.stop + "']")) response.end(addCallback(u.query.callback, "['stop ok', '" + u.query.stop + "']"))
catch err catch err
response.end(addCallback(u.query.callback, "['stop fail', '" + u.query.stop + "']")) response.end(addCallback(u.query.callback, "['stop fail', '" + u.query.stop + "']"))
...@@ -3802,7 +3805,7 @@ if settings.modules.http ...@@ -3802,7 +3805,7 @@ if settings.modules.http
response.end(addCallback(u.query.callback, "['密码错误', 0]")) response.end(addCallback(u.query.callback, "['密码错误', 0]"))
return return
try try
await util.promisify(setting_change)(settings, 'modules:welcome', u.query.welcome) await setting_change(settings, 'modules:welcome', u.query.welcome)
response.end(addCallback(u.query.callback, "['welcome ok', '" + u.query.welcome + "']")) response.end(addCallback(u.query.callback, "['welcome ok', '" + u.query.welcome + "']"))
catch err catch err
response.end(addCallback(u.query.callback, "['welcome fail', '" + u.query.welcome + "']")) response.end(addCallback(u.query.callback, "['welcome fail', '" + u.query.welcome + "']"))
...@@ -3952,6 +3955,13 @@ if settings.modules.http ...@@ -3952,6 +3955,13 @@ if settings.modules.http
roomlist.init https_server, ROOM_all roomlist.init https_server, ROOM_all
https_server.listen settings.modules.http.ssl.port https_server.listen settings.modules.http.ssl.port
mkdirList = [
"./plugins",
settings.modules.tournament_mode.deck_path,
settings.modules.tournament_mode.replay_path,
settings.modules.tournament_mode.log_save_path,
settings.modules.deck_log.local
]
if not fs.existsSync('./plugins') if not fs.existsSync('./plugins')
fs.mkdirSync('./plugins') fs.mkdirSync('./plugins')
......
// Generated by CoffeeScript 2.5.1 // Generated by CoffeeScript 2.5.1
(function() { (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_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, 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, mkdirList, moment, n, net, oldbadwords, oldconfig, olddialogues, 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;
net = require('net'); net = require('net');
...@@ -102,15 +102,6 @@ ...@@ -102,15 +102,6 @@
fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2)); fs.writeFileSync(olddialogues.file, JSON.stringify(olddialogues, null, 2));
delete oldconfig.dialogues; delete oldconfig.dialogues;
} }
if (oldconfig.modules) {
if (oldconfig.modules.tournament_mode && oldconfig.modules.tournament_mode.duel_log) {
oldduellog = {};
oldduellog.file = './config/duel_log.json';
oldduellog.duel_log = oldconfig.modules.tournament_mode.duel_log;
fs.writeFileSync(oldduellog.file, JSON.stringify(oldduellog, null, 2));
delete oldconfig.oldduellog;
}
}
oldbadwords = {}; oldbadwords = {};
if (oldconfig.ban) { if (oldconfig.ban) {
if (oldconfig.ban.badword_level0) { if (oldconfig.ban.badword_level0) {
...@@ -147,18 +138,16 @@ ...@@ -147,18 +138,16 @@
} }
} }
setting_save = global.setting_save = function(settings, callback) { setting_save = global.setting_save = async function(settings) {
if (!callback) { try {
callback = function(err) { await fs.promises.writeFile(settings.file, JSON.stringify(settings, null, 2));
if (err) { } catch (error1) {
return log.warn("setting save fail", err.toString()); e = error1;
} log.warn("setting save fail", e.toString());
};
} }
fs.writeFile(settings.file, JSON.stringify(settings, null, 2), callback);
}; };
setting_change = global.setting_change = function(settings, path, val, callback) { setting_change = global.setting_change = async function(settings, path, val) {
var key, target; var key, target;
if (_.isString(val)) { if (_.isString(val)) {
// path should be like "modules:welcome" // path should be like "modules:welcome"
...@@ -176,7 +165,7 @@ ...@@ -176,7 +165,7 @@
key = path.shift(); key = path.shift();
target[key] = val; target[key] = val;
} }
setting_save(settings, callback); await setting_save(settings);
}; };
// 读取配置 // 读取配置
...@@ -322,13 +311,6 @@ ...@@ -322,13 +311,6 @@
setting_save(badwords); setting_save(badwords);
} }
try {
duel_log = global.duel_log = loadJSON('./config/duel_log.json');
} catch (error1) {
duel_log = global.duel_log = default_data.duel_log;
setting_save(duel_log);
}
try { try {
chat_color = global.chat_color = loadJSON('./config/chat_color.json'); chat_color = global.chat_color = loadJSON('./config/chat_color.json');
} catch (error1) { } catch (error1) {
...@@ -431,11 +413,22 @@ ...@@ -431,11 +413,22 @@
return log.info("Database ready."); return log.info("Database ready.");
}); });
} else { } else {
log.warn("Some functions may be limited without MySQL .");
if (settings.modules.cloud_replay.enabled) { if (settings.modules.cloud_replay.enabled) {
settings.modules.cloud_replay.enabled = false; settings.modules.cloud_replay.enabled = false;
setting_save(settings); setting_save(settings);
log.warn("Cloud replay cannot be enabled because no MySQL."); log.warn("Cloud replay cannot be enabled because no MySQL.");
} }
if (settings.modules.enable_recover.enabled) {
settings.modules.enable_recover.enabled = false;
setting_save(settings);
log.warn("Recover mode cannot be enabled because no MySQL.");
}
if (settings.modules.chat_color.enabled) {
settings.modules.chat_color.enabled = false;
setting_save(settings);
log.warn("Chat color cannot be enabled because no MySQL.");
}
} }
if (settings.modules.mycard.enabled) { if (settings.modules.mycard.enabled) {
...@@ -687,7 +680,7 @@ ...@@ -687,7 +680,7 @@
return; return;
} }
found = true; found = true;
room.termiate(); room.terminate();
return done(); return done();
}, function(err) { }, function(err) {
callback(null, found); callback(null, found);
...@@ -785,7 +778,7 @@ ...@@ -785,7 +778,7 @@
} }
ROOM_find_or_create_by_name = global.ROOM_find_or_create_by_name = async function(name, player_ip) { ROOM_find_or_create_by_name = global.ROOM_find_or_create_by_name = async function(name, player_ip) {
var room, uname; var room, success, uname;
uname = name.toUpperCase(); uname = name.toUpperCase();
if (settings.modules.windbot.enabled && (uname.slice(0, 2) === 'AI' || (!settings.modules.random_duel.enabled && uname === ''))) { if (settings.modules.windbot.enabled && (uname.slice(0, 2) === 'AI' || (!settings.modules.random_duel.enabled && uname === ''))) {
return ROOM_find_or_create_ai(name); return ROOM_find_or_create_ai(name);
...@@ -798,7 +791,16 @@ ...@@ -798,7 +791,16 @@
} else if (memory_usage >= 90) { } else if (memory_usage >= 90) {
return null; return null;
} else { } else {
return new Room(name); room = new Room(name);
if (room.recover_duel_log_id) {
success = (await room.initialize_recover());
if (!success) {
return {
"error": "${cloud_replay_no}"
};
}
}
return room;
} }
}; };
...@@ -1431,7 +1433,7 @@ ...@@ -1431,7 +1433,7 @@
Room = class Room { Room = class Room {
constructor(name, hostinfo) { constructor(name, hostinfo) {
var death_time, draw_count, duel_log_id, duel_rule, i, lflist, n, o, param, rule, seeds, start_hand, start_lp, time_limit; var death_time, draw_count, duel_rule, lflist, param, rule, start_hand, start_lp, time_limit;
this.hostinfo = hostinfo; this.hostinfo = hostinfo;
this.name = name; this.name = name;
//@alive = true //@alive = true
...@@ -1586,15 +1588,7 @@ ...@@ -1586,15 +1588,7 @@
this.recovered = true; this.recovered = true;
this.recovering = true; this.recovering = true;
this.recover_from_turn = parseInt(param[4]); this.recover_from_turn = parseInt(param[4]);
duel_log_id = parseInt(param[3]); this.recover_duel_log_id = parseInt(param[3]);
this.recover_duel_log = _.find(duel_log.duel_log, function(duel) {
return duel.id === duel_log_id && duel.roommode !== 2 && duel.players[0].deck;
});
if (!this.recover_duel_log || !fs.existsSync(settings.modules.tournament_mode.replay_path + this.recover_duel_log.replay_filename)) {
this.error = "${cloud_replay_no}";
return;
}
this.recover_replay = ReplayParser.fromFile(settings.modules.tournament_mode.replay_path + this.recover_duel_log.replay_filename);
this.recover_buffers = [[], [], [], []]; this.recover_buffers = [[], [], [], []];
this.welcome = "${recover_hint}"; this.welcome = "${recover_hint}";
} }
...@@ -1606,9 +1600,16 @@ ...@@ -1606,9 +1600,16 @@
if ((settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) || (this.hostinfo.mode === 1 && settings.modules.replay_delay)) { if ((settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player) || (this.hostinfo.mode === 1 && settings.modules.replay_delay)) {
this.hostinfo.replay_mode |= 0x2; this.hostinfo.replay_mode |= 0x2;
} }
if (!this.recovered) {
this.spawn();
}
}
spawn(firstSeed) {
var i, n, o, param, seeds;
param = [0, this.hostinfo.lflist, this.hostinfo.rule, this.hostinfo.mode, this.hostinfo.duel_rule, (this.hostinfo.no_check_deck ? 'T' : 'F'), (this.hostinfo.no_shuffle_deck ? 'T' : 'F'), this.hostinfo.start_lp, this.hostinfo.start_hand, this.hostinfo.draw_count, this.hostinfo.time_limit, this.hostinfo.replay_mode]; param = [0, this.hostinfo.lflist, this.hostinfo.rule, this.hostinfo.mode, this.hostinfo.duel_rule, (this.hostinfo.no_check_deck ? 'T' : 'F'), (this.hostinfo.no_shuffle_deck ? 'T' : 'F'), this.hostinfo.start_lp, this.hostinfo.start_hand, this.hostinfo.draw_count, this.hostinfo.time_limit, this.hostinfo.replay_mode];
if (this.recovered) { if (firstSeed) {
param.push(this.recover_replay.header.seed); param.push(firstSeed);
seeds = getSeedTimet(2); seeds = getSeedTimet(2);
for (i = n = 0; n < 2; i = ++n) { for (i = n = 0; n < 2; i = ++n) {
param.push(seeds[i]); param.push(seeds[i]);
...@@ -1661,7 +1662,7 @@ ...@@ -1661,7 +1662,7 @@
}, 200); }, 200);
} }
}); });
this.process.stderr.on('data', (data) => { return this.process.stderr.on('data', (data) => {
data = "Debug: " + data; data = "Debug: " + data;
data = data.replace(/\n$/, ""); data = data.replace(/\n$/, "");
log.info("YGOPRO " + data); log.info("YGOPRO " + data);
...@@ -1674,7 +1675,7 @@ ...@@ -1674,7 +1675,7 @@
} }
}); });
} catch (error1) { } catch (error1) {
this.error = "${create_room_failed}"; return this.error = "${create_room_failed}";
} }
} }
...@@ -1831,6 +1832,24 @@ ...@@ -1831,6 +1832,24 @@
} }
} }
async initialize_recover() {
this.recover_duel_log = (await dataManager.getDuelLogFromId(this.recover_duel_log_id));
if (!this.recover_duel_log || !fs.existsSync(settings.modules.tournament_mode.replay_path + this.recover_duel_log.replayFileName)) {
this.terminate();
return false;
}
try {
this.recover_replay = (await ReplayParser.fromFile(settings.modules.tournament_mode.replay_path + this.recover_duel_log.replayFileName));
this.spawn(this.recover_replay.header.seed);
return true;
} catch (error1) {
e = error1;
log.warn("LOAD RECOVER REPLAY FAIL", e.toString());
this.terminate();
return false;
}
}
get_playing_player() { get_playing_player() {
var playing_player; var playing_player;
playing_player = []; playing_player = [];
...@@ -2120,14 +2139,20 @@ ...@@ -2120,14 +2139,20 @@
return true; return true;
} }
termiate() { terminate() {
if (this.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN) { if (this.duel_stage !== ygopro.constants.DUEL_STAGE.BEGIN) {
this.scores[this.dueling_players[0].name_vpass] = 0; this.scores[this.dueling_players[0].name_vpass] = 0;
this.scores[this.dueling_players[1].name_vpass] = 0; this.scores[this.dueling_players[1].name_vpass] = 0;
} }
this.kicked = true; this.kicked = true;
this.send_replays(); this.send_replays();
if (this.process) {
try {
this.process.kill(); this.process.kill();
} catch (error1) {
e = error1;
}
}
return this.delete(); return this.delete();
} }
...@@ -2135,7 +2160,7 @@ ...@@ -2135,7 +2160,7 @@
var buffer, len3, n, player, ref3, results; var buffer, len3, n, player, ref3, results;
if (fail) { if (fail) {
ygopro.stoc_send_chat_to_room(this, "${recover_fail}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat_to_room(this, "${recover_fail}", ygopro.constants.COLORS.RED);
return this.termiate(); return this.terminate();
} else { } else {
ygopro.stoc_send_chat_to_room(this, "${recover_success}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat_to_room(this, "${recover_success}", ygopro.constants.COLORS.BABYBLUE);
this.recovering = false; this.recovering = false;
...@@ -2495,7 +2520,7 @@ ...@@ -2495,7 +2520,7 @@
}); });
ygopro.ctos_follow('JOIN_GAME', true, async function(buffer, info, client, server, datas) { 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, duelLog, exactBan, index, len3, len4, len5, len6, n, name, o, p, pre_room, q, recover_match, ref3, ref4, replay, replay_id, replays, room, struct;
//log.info info //log.info info
info.pass = info.pass.trim(); info.pass = info.pass.trim();
client.pass = info.pass; client.pass = info.pass;
...@@ -2520,24 +2545,16 @@ ...@@ -2520,24 +2545,16 @@
CLIENT_kick(client); CLIENT_kick(client);
} else if (info.pass.toUpperCase() === "RC" && settings.modules.tournament_mode.enable_recover) { } else if (info.pass.toUpperCase() === "RC" && settings.modules.tournament_mode.enable_recover) {
ygopro.stoc_send_chat(client, "${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${recover_replay_hint}", ygopro.constants.COLORS.BABYBLUE);
available_logs = duel_log.duel_log.filter(function(duel) { available_logs = (await dataManager.getDuelLogFromRecoverSearch(client.name_vpass));
return duel.id && duel.players[0].deck && duel.roommode !== 2 && _.any(duel.players, function(player) { for (o = 0, len4 = available_logs.length; o < len4; o++) {
return player.real_name === client.name_vpass; duelLog = available_logs[o];
}); ygopro.stoc_send_chat(client, duelLog.getViewString(), ygopro.constants.COLORS.BABYBLUE);
}).slice(0, 8); }
_.each(available_logs, function(duel) {
var player_names;
player_names = duel.players[0].real_name.split("$")[0] + (duel.players[2] ? "+" + duel.players[2].real_name.split("$")[0] : "") + " VS " + (duel.players[1] ? duel.players[1].real_name.split("$")[0] : "AI") + (duel.players[3] ? "+" + duel.players[3].real_name.split("$")[0] : "");
return ygopro.stoc_send_chat(client, `<${duel.id}> ${player_names} ${duel.time}`, ygopro.constants.COLORS.BABYBLUE);
});
// 强行等待异步执行完毕_(:з」∠)_
setTimeout((function() {
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1, msg: 1,
code: 9 code: 9
}); });
CLIENT_kick(client); CLIENT_kick(client);
}), 500);
} else if (info.pass.slice(0, 2).toUpperCase() === "R#" && settings.modules.cloud_replay.enabled) { } else if (info.pass.slice(0, 2).toUpperCase() === "R#" && settings.modules.cloud_replay.enabled) {
replay_id = info.pass.split("#")[1]; replay_id = info.pass.split("#")[1];
replay = (await dataManager.getCloudReplayFromId(replay_id)); replay = (await dataManager.getCloudReplayFromId(replay_id));
...@@ -2573,15 +2590,15 @@ ...@@ -2573,15 +2590,15 @@
return; return;
} }
check_buffer_indentity = function(buf) { check_buffer_indentity = function(buf) {
var checksum, i, o, ref3; var checksum, i, p, ref3;
checksum = 0; checksum = 0;
for (i = o = 0, ref3 = buf.length; (0 <= ref3 ? o < ref3 : o > ref3); i = 0 <= ref3 ? ++o : --o) { for (i = p = 0, ref3 = buf.length; (0 <= ref3 ? p < ref3 : p > ref3); i = 0 <= ref3 ? ++p : --p) {
checksum += buf.readUInt8(i); checksum += buf.readUInt8(i);
} }
return (checksum & 0xFF) === 0; return (checksum & 0xFF) === 0;
}; };
create_room_with_action = async function(buffer, decrypted_buffer, match_permit) { 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, len5, len6, name, opt1, opt2, opt3, options, p, player, q, ref3, ref4, room, room_title, title;
if (client.closed) { if (client.closed) {
return; return;
} }
...@@ -2671,8 +2688,8 @@ ...@@ -2671,8 +2688,8 @@
room = (await ROOM_find_or_create_by_name('M#' + info.pass.slice(8))); room = (await ROOM_find_or_create_by_name('M#' + info.pass.slice(8)));
if (room) { if (room) {
ref3 = room.get_playing_player(); ref3 = room.get_playing_player();
for (o = 0, len4 = ref3.length; o < len4; o++) { for (p = 0, len5 = ref3.length; p < len5; p++) {
player = ref3[o]; player = ref3[p];
if (!(player && player.name === client.name)) { if (!(player && player.name === client.name)) {
continue; continue;
} }
...@@ -2712,8 +2729,8 @@ ...@@ -2712,8 +2729,8 @@
room.watchers.push(client); room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref4 = room.watcher_buffers; ref4 = room.watcher_buffers;
for (p = 0, len5 = ref4.length; p < len5; p++) { for (q = 0, len6 = ref4.length; q < len6; q++) {
buffer = ref4[p]; buffer = ref4[q];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -2760,7 +2777,7 @@ ...@@ -2760,7 +2777,7 @@
}); });
}, },
get_user: function(done) { get_user: function(done) {
var decrypted_buffer, i, id, len4, o, ref3, secret; var decrypted_buffer, i, id, len5, p, ref3, secret;
if (client.closed) { if (client.closed) {
done(); done();
return; return;
...@@ -2769,8 +2786,8 @@ ...@@ -2769,8 +2786,8 @@
secret = id % 65535 + 1; secret = id % 65535 + 1;
decrypted_buffer = Buffer.allocUnsafe(6); decrypted_buffer = Buffer.allocUnsafe(6);
ref3 = [0, 2, 4]; ref3 = [0, 2, 4];
for (o = 0, len4 = ref3.length; o < len4; o++) { for (p = 0, len5 = ref3.length; p < len5; p++) {
i = ref3[o]; i = ref3[p];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i); decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
} }
if (check_buffer_indentity(decrypted_buffer)) { if (check_buffer_indentity(decrypted_buffer)) {
...@@ -2792,14 +2809,14 @@ ...@@ -2792,14 +2809,14 @@
}, },
json: true json: true
}, function(error, response, body) { }, function(error, response, body) {
var len5, p, ref4; var len6, q, ref4;
if (!error && body && body.user) { if (!error && body && body.user) {
users_cache[client.name] = body.user.id; users_cache[client.name] = body.user.id;
secret = body.user.id % 65535 + 1; secret = body.user.id % 65535 + 1;
decrypted_buffer = Buffer.allocUnsafe(6); decrypted_buffer = Buffer.allocUnsafe(6);
ref4 = [0, 2, 4]; ref4 = [0, 2, 4];
for (p = 0, len5 = ref4.length; p < len5; p++) { for (q = 0, len6 = ref4.length; q < len6; q++) {
i = ref4[p]; i = ref4[q];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i); decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
} }
if (check_buffer_indentity(decrypted_buffer)) { if (check_buffer_indentity(decrypted_buffer)) {
...@@ -2848,8 +2865,8 @@ ...@@ -2848,8 +2865,8 @@
room.watchers.push(client); room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref3 = room.watcher_buffers; ref3 = room.watcher_buffers;
for (o = 0, len4 = ref3.length; o < len4; o++) { for (p = 0, len5 = ref3.length; p < len5; p++) {
buffer = ref3[o]; buffer = ref3[p];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -2871,7 +2888,7 @@ ...@@ -2871,7 +2888,7 @@
}); });
} }
}, async function(err, datas) { }, 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, k, len6, len7, match, player, q, r, ref4, ref5, ref6, ref7, user;
if (client.closed) { if (client.closed) {
return; return;
} }
...@@ -2933,8 +2950,8 @@ ...@@ -2933,8 +2950,8 @@
room.watchers.push(client); room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref6 = room.watcher_buffers; ref6 = room.watcher_buffers;
for (p = 0, len5 = ref6.length; p < len5; p++) { for (q = 0, len6 = ref6.length; q < len6; q++) {
buffer = ref6[p]; buffer = ref6[q];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -2944,8 +2961,8 @@ ...@@ -2944,8 +2961,8 @@
ygopro.stoc_die(client, "${watch_denied_room}"); ygopro.stoc_die(client, "${watch_denied_room}");
} else { } else {
ref7 = room.get_playing_player(); ref7 = room.get_playing_player();
for (q = 0, len6 = ref7.length; q < len6; q++) { for (r = 0, len7 = ref7.length; r < len7; r++) {
player = ref7[q]; player = ref7[r];
if (!(player && player !== client && player.challonge_info.id === client.challonge_info.id)) { if (!(player && player !== client && player.challonge_info.id === client.challonge_info.id)) {
continue; continue;
} }
...@@ -3021,8 +3038,8 @@ ...@@ -3021,8 +3038,8 @@
room.watchers.push(client); room.watchers.push(client);
ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, "${watch_watching}", ygopro.constants.COLORS.BABYBLUE);
ref4 = room.watcher_buffers; ref4 = room.watcher_buffers;
for (p = 0, len5 = ref4.length; p < len5; p++) { for (q = 0, len6 = ref4.length; q < len6; q++) {
buffer = ref4[p]; buffer = ref4[q];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -4232,7 +4249,7 @@ ...@@ -4232,7 +4249,7 @@
}); });
ygopro.ctos_follow('UPDATE_DECK', true, async function(buffer, info, client, server, datas) { ygopro.ctos_follow('UPDATE_DECK', true, async function(buffer, info, client, server, datas) {
var buff_main, buff_side, card, current_deck, deck, deck_array, deck_main, deck_side, deck_text, deckbuf, decks, found_deck, i, len3, len4, line, n, o, oppo_pos, recover_player_data, room, struct, win_pos; var buff_main, buff_side, card, current_deck, deck, deck_array, deck_main, deck_side, deck_text, deckbuf, decks, found_deck, i, len3, len4, line, n, o, oppo_pos, recover_player_data, recoveredDeck, room, struct, win_pos;
if (settings.modules.reconnect.enabled && client.pre_reconnecting) { if (settings.modules.reconnect.enabled && client.pre_reconnecting) {
if (!CLIENT_is_able_to_reconnect(client) && !CLIENT_is_able_to_kick_reconnect(client)) { if (!CLIENT_is_able_to_reconnect(client) && !CLIENT_is_able_to_kick_reconnect(client)) {
ygopro.stoc_send_chat(client, "${reconnect_failed}", ygopro.constants.COLORS.RED); ygopro.stoc_send_chat(client, "${reconnect_failed}", ygopro.constants.COLORS.RED);
...@@ -4312,13 +4329,14 @@ ...@@ -4312,13 +4329,14 @@
} }
if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.recovering) { if (room.duel_stage === ygopro.constants.DUEL_STAGE.BEGIN && room.recovering) {
recover_player_data = _.find(room.recover_duel_log.players, function(player) { recover_player_data = _.find(room.recover_duel_log.players, function(player) {
return player.real_name === client.name_vpass && _.isEqual(buffer, Buffer.from(player.deckbuf, "base64")); return player.realName === client.name_vpass && buffer.toString("base64") === player.startDeckBuffer;
}); });
if (recover_player_data) { if (recover_player_data) {
struct.set("mainc", recover_player_data.deck.main.length); recoveredDeck = recover_player_data.getCurrentDeck();
struct.set("sidec", recover_player_data.deck.side.length); struct.set("mainc", recoveredDeck.main.length);
struct.set("deckbuf", recover_player_data.deck.main.concat(recover_player_data.deck.side)); struct.set("sidec", recoveredDeck.side.length);
if (recover_player_data.is_first) { struct.set("deckbuf", recoveredDeck.main.concat(recoveredDeck.side));
if (recover_player_data.isFirst) {
room.determine_firstgo = client; room.determine_firstgo = client;
} }
} else { } else {
...@@ -4660,7 +4678,7 @@ ...@@ -4660,7 +4678,7 @@
}); });
ygopro.stoc_follow('REPLAY', true, async function(buffer, info, client, server, datas) { 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 i, len3, len4, n, o, player, playerInfos, ref3, ref4, replay_filename, room;
room = ROOM_all[client.rid]; room = ROOM_all[client.rid];
if (!room) { if (!room) {
return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player || settings.modules.replay_delay; return settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.block_replay_to_player || settings.modules.replay_delay;
...@@ -4669,10 +4687,9 @@ ...@@ -4669,10 +4687,9 @@
// console.log("Replay saved: ", room.duel_count - 1, client.pos) // console.log("Replay saved: ", room.duel_count - 1, client.pos)
room.replays[room.duel_count - 1] = buffer; room.replays[room.duel_count - 1] = buffer;
} }
if (settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.replay_safe || settings.modules.tournament_mode.enable_recover) { if (settings.modules.mysql.enabled) {
if (client.pos === 0) { if (client.pos === 0) {
dueltime = moment().format('YYYY-MM-DD HH-mm-ss'); replay_filename = moment().format("YYYY-MM-DD HH-mm-ss");
replay_filename = dueltime;
if (room.hostinfo.mode !== 2) { if (room.hostinfo.mode !== 2) {
ref3 = room.dueling_players; ref3 = room.dueling_players;
for (i = n = 0, len3 = ref3.length; n < len3; i = ++n) { for (i = n = 0, len3 = ref3.length; n < len3; i = ++n) {
...@@ -4687,43 +4704,30 @@ ...@@ -4687,43 +4704,30 @@
} }
} }
replay_filename = replay_filename.replace(/[\/\\\?\*]/g, '_') + ".yrp"; replay_filename = replay_filename.replace(/[\/\\\?\*]/g, '_') + ".yrp";
duellog = { playerInfos = room.dueling_players.map(function(player) {
id: duel_log.duel_log.length + 1, return {
time: dueltime, name: player.name,
name: room.name + (settings.modules.tournament_mode.show_info ? " (Duel:" + room.duel_count + ")" : ""), pos: player.pos,
roomid: room.process_pid.toString(), realName: player.name_vpass,
cloud_replay_id: "R#" + room.cloud_replay_id, startDeckBuffer: player.start_deckbuf,
replay_filename: replay_filename,
roommode: room.hostinfo.mode,
players: (function() {
var len5, p, ref5, results;
ref5 = room.dueling_players;
results = [];
for (p = 0, len5 = ref5.length; p < len5; p++) {
player = ref5[p];
results.push({
real_name: player.name_vpass,
deckbuf: player.start_deckbuf.toString("base64"),
deck: { deck: {
main: player.main, main: player.main,
side: player.side side: player.side
}, },
pos: player.pos, isFirst: player.is_first,
is_first: player.is_first, winner: player.pos === room.winner,
name: player.name + (settings.modules.tournament_mode.show_ip && !player.is_local ? " (IP: " + player.ip.slice(7) + ")" : "") + (settings.modules.tournament_mode.show_info && !(room.hostinfo.mode === 2 && player.pos % 2 > 0) ? " (Score:" + room.scores[player.name_vpass] + " LP:" + (player.lp != null ? player.lp : room.hostinfo.start_lp) + (room.hostinfo.mode !== 2 ? " Cards:" + (player.card_count != null ? player.card_count : room.hostinfo.start_hand) : "") + ")" : ""), ip: player.ip,
winner: player.pos === room.winner score: room.scores[player.name_vpass],
}); lp: player.lp != null ? player.lp : room.hostinfo.start_lp,
} cardCount: player.card_count != null ? player.card_count : room.hostinfo.start_hand
return results;
})()
}; };
duel_log.duel_log.unshift(duellog); });
setting_save(duel_log);
fs.writeFile(settings.modules.tournament_mode.replay_path + replay_filename, buffer, function(err) { fs.writeFile(settings.modules.tournament_mode.replay_path + replay_filename, buffer, function(err) {
if (err) { if (err) {
return log.warn("SAVE REPLAY ERROR", replay_filename, err); return log.warn("SAVE REPLAY ERROR", replay_filename, err);
} }
}); });
dataManager.saveDuelLog(room.name, room.process_pid.toString(), room.cloud_replay_id, replay_filename, room.hostinfo.mode, room.duel_count, playerInfos); // no synchronize here because too slow
} }
if (settings.modules.cloud_replay.enabled && settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.replay_safe) { if (settings.modules.cloud_replay.enabled && settings.modules.tournament_mode.enabled && settings.modules.tournament_mode.replay_safe) {
ygopro.stoc_send_chat(client, `\${cloud_replay_delay_part1}R#${room.cloud_replay_id}\${cloud_replay_delay_part2}`, ygopro.constants.COLORS.BABYBLUE); ygopro.stoc_send_chat(client, `\${cloud_replay_delay_part1}R#${room.cloud_replay_id}\${cloud_replay_delay_part2}`, ygopro.constants.COLORS.BABYBLUE);
...@@ -4894,7 +4898,7 @@ ...@@ -4894,7 +4898,7 @@
return callback + "( " + text + " );"; return callback + "( " + text + " );";
}; };
requestListener = async function(request, response) { 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, len3, n, parseQueryString, pass_validated, ref3, roomsjson, u;
parseQueryString = true; parseQueryString = true;
u = url.parse(request.url, parseQueryString); u = url.parse(request.url, parseQueryString);
//pass_validated = u.query.pass == settings.modules.http.password //pass_validated = u.query.pass == settings.modules.http.password
...@@ -4950,17 +4954,17 @@ ...@@ -4950,17 +4954,17 @@
}))); })));
}); });
} }
} else if (u.pathname === '/api/duellog' && settings.modules.tournament_mode.enabled) { } else if (u.pathname === '/api/duellog' && settings.modules.mysql.enabled) {
if (!(await auth.auth(u.query.username, u.query.pass, "duel_log", "duel_log"))) { if (!(await auth.auth(u.query.username, u.query.pass, "duel_log", "duel_log"))) {
response.writeHead(200); response.writeHead(200);
response.end(addCallback(u.query.callback, "[{name:'密码错误'}]")); response.end(addCallback(u.query.callback, "[{name:'密码错误'}]"));
return; return;
} else { } else {
response.writeHead(200); response.writeHead(200);
duellog = JSON.stringify(duel_log.duel_log, null, 2); duellog = JSON.stringify((await dataManager.getDuelLogJSON(settings.modules.tournament_mode)), null, 2);
response.end(addCallback(u.query.callback, duellog)); response.end(addCallback(u.query.callback, duellog));
} }
} else if (u.pathname === '/api/archive.zip' && settings.modules.tournament_mode.enabled) { } else if (u.pathname === '/api/archive.zip' && settings.modules.mysql.enabled) {
if (!(await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay_archive"))) { if (!(await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay_archive"))) {
response.writeHead(403); response.writeHead(403);
response.end("Invalid password."); response.end("Invalid password.");
...@@ -4970,11 +4974,11 @@ ...@@ -4970,11 +4974,11 @@
archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip"; archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip";
archive_args = ["a", "-mx0", "-y", archive_name]; archive_args = ["a", "-mx0", "-y", archive_name];
check = false; check = false;
ref3 = duel_log.duel_log; ref3 = (await dataManager.getAllReplayFilenames());
for (n = 0, len3 = ref3.length; n < len3; n++) { for (n = 0, len3 = ref3.length; n < len3; n++) {
replay = ref3[n]; filename = ref3[n];
check = true; check = true;
archive_args.push(replay.replay_filename); archive_args.push(filename);
} }
if (!check) { if (!check) {
response.writeHead(403); response.writeHead(403);
...@@ -5016,7 +5020,7 @@ ...@@ -5016,7 +5020,7 @@
response.end("Failed reading replays. " + error); response.end("Failed reading replays. " + error);
} }
} }
} else if (u.pathname === '/api/clearlog' && settings.modules.tournament_mode.enabled) { } else if (u.pathname === '/api/clearlog' && settings.modules.mysql.enabled) {
if (!(await auth.auth(u.query.username, u.query.pass, "clear_duel_log", "clear_duel_log"))) { if (!(await auth.auth(u.query.username, u.query.pass, "clear_duel_log", "clear_duel_log"))) {
response.writeHead(200); response.writeHead(200);
response.end(addCallback(u.query.callback, "[{name:'密码错误'}]")); response.end(addCallback(u.query.callback, "[{name:'密码错误'}]"));
...@@ -5024,17 +5028,16 @@ ...@@ -5024,17 +5028,16 @@
} else { } else {
response.writeHead(200); response.writeHead(200);
if (settings.modules.tournament_mode.log_save_path) { if (settings.modules.tournament_mode.log_save_path) {
fs.writeFile(settings.modules.tournament_mode.log_save_path + 'duel_log.' + moment().format('YYYY-MM-DD HH-mm-ss') + '.json', JSON.stringify(duel_log, null, 2), function(err) { fs.writeFile(settings.modules.tournament_mode.log_save_path + 'duel_log.' + moment().format('YYYY-MM-DD HH-mm-ss') + '.json', JSON.stringify((await dataManager.getDuelLogJSON(settings.modules.tournament_mode)), null, 2), function(err) {
if (err) { if (err) {
return log.warn('DUEL LOG SAVE ERROR', err); return log.warn('DUEL LOG SAVE ERROR', err);
} }
}); });
} }
duel_log.duel_log = []; await dataManager.clearDuelLog();
setting_save(duel_log);
response.end(addCallback(u.query.callback, "[{name:'Success'}]")); response.end(addCallback(u.query.callback, "[{name:'Success'}]"));
} }
} else if (_.startsWith(u.pathname, '/api/replay') && settings.modules.tournament_mode.enabled) { } else if (_.startsWith(u.pathname, '/api/replay') && settings.modules.mysql.enabled) {
if (!(await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay"))) { if (!(await auth.auth(u.query.username, u.query.pass, "download_replay", "download_replay"))) {
response.writeHead(403); response.writeHead(403);
response.end("密码错误"); response.end("密码错误");
...@@ -5092,7 +5095,7 @@ ...@@ -5092,7 +5095,7 @@
} }
response.writeHead(200); response.writeHead(200);
try { try {
await util.promisify(setting_change)(settings, 'modules:stop', u.query.stop); await setting_change(settings, 'modules:stop', u.query.stop);
response.end(addCallback(u.query.callback, "['stop ok', '" + u.query.stop + "']")); response.end(addCallback(u.query.callback, "['stop ok', '" + u.query.stop + "']"));
} catch (error1) { } catch (error1) {
err = error1; err = error1;
...@@ -5105,7 +5108,7 @@ ...@@ -5105,7 +5108,7 @@
return; return;
} }
try { try {
await util.promisify(setting_change)(settings, 'modules:welcome', u.query.welcome); await setting_change(settings, 'modules:welcome', u.query.welcome);
response.end(addCallback(u.query.callback, "['welcome ok', '" + u.query.welcome + "']")); response.end(addCallback(u.query.callback, "['welcome ok', '" + u.query.welcome + "']"));
} catch (error1) { } catch (error1) {
err = error1; err = error1;
...@@ -5268,6 +5271,8 @@ ...@@ -5268,6 +5271,8 @@
} }
} }
mkdirList = ["./plugins", settings.modules.tournament_mode.deck_path, settings.modules.tournament_mode.replay_path, settings.modules.tournament_mode.log_save_path, settings.modules.deck_log.local];
if (!fs.existsSync('./plugins')) { if (!fs.existsSync('./plugins')) {
fs.mkdirSync('./plugins'); fs.mkdirSync('./plugins');
} }
......
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