Commit c5b0e287 authored by nanahira's avatar nanahira

Merge branch 'mc'

parents 2a93316f bb6ee175
Pipeline #1272 passed with stages
in 11 minutes and 47 seconds
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
......@@ -17,6 +36,8 @@ const User_1 = require("./entities/User");
const VipKey_1 = require("./entities/VipKey");
const UserDialog_1 = require("./entities/UserDialog");
const RandomDuelScore_1 = require("./entities/RandomDuelScore");
const jszip_1 = __importDefault(require("jszip"));
const fs = __importStar(require("fs"));
class DataManager {
constructor(config, log) {
this.config = config;
......@@ -232,6 +253,51 @@ class DataManager {
return [];
}
}
getEscapedString(text) {
return text.replace(/\\/g, "").replace(/_/g, "\\_").replace(/%/g, "\\%") + "%";
}
async getDuelLogFromCondition(data) {
//console.log(data);
if (!data) {
return this.getAllDuelLogs();
}
const { roomName, duelCount, playerName, playerScore } = data;
const repo = this.db.getRepository(DuelLog_1.DuelLog);
try {
const queryBuilder = repo.createQueryBuilder("duelLog")
.where("1");
if (roomName != null && roomName.length) {
const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name like :escapedRoomName", { escapedRoomName });
}
if (duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
}
if (playerName != null && playerName.length || playerScore != null && !isNaN(playerScore)) {
let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams = {};
if (playerName != null && playerName.length) {
const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName like :escapedPlayerName";
innerQueryParams.escapedPlayerName = escapedPlayerName;
}
if (playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore";
innerQueryParams.playerScore = playerScore;
}
queryBuilder.andWhere(`exists (${innerQuery})`, innerQueryParams);
}
queryBuilder.orderBy("duelLog.id", "DESC")
.leftJoinAndSelect("duelLog.players", "player");
// console.log(queryBuilder.getSql());
const duelLogs = await queryBuilder.getMany();
return duelLogs;
}
catch (e) {
this.log.warn(`Failed to fetch duel logs: ${e.toString()}`);
return [];
}
}
async getDuelLogFromId(id) {
const repo = this.db.getRepository(DuelLog_1.DuelLog);
try {
......@@ -263,10 +329,48 @@ class DataManager {
const allDuelLogs = await this.getAllDuelLogs();
return allDuelLogs.map(duelLog => duelLog.getViewJSON(tournamentModeSettings));
}
async getDuelLogJSONFromCondition(tournamentModeSettings, data) {
const allDuelLogs = await this.getDuelLogFromCondition(data);
return allDuelLogs.map(duelLog => duelLog.getViewJSON(tournamentModeSettings));
}
async getAllReplayFilenames() {
const allDuelLogs = await this.getAllDuelLogs();
return allDuelLogs.map(duelLog => duelLog.replayFileName);
}
async getReplayFilenamesFromCondition(data) {
const allDuelLogs = await this.getDuelLogFromCondition(data);
return allDuelLogs.map(duelLog => duelLog.replayFileName);
}
async getReplayArchiveStreamFromCondition(rootPath, data) {
const filenames = await this.getReplayFilenamesFromCondition(data);
if (!filenames.length) {
return null;
}
try {
const zip = new jszip_1.default();
for (let fileName of filenames) {
const filePath = `${rootPath}${fileName}`;
try {
await fs.promises.access(filePath);
zip.file(fileName, fs.promises.readFile(filePath));
}
catch (e) {
this.log.warn(`Errored archiving ${filePath}: ${e.toString()}`);
continue;
}
}
return zip.generateNodeStream({
compression: "DEFLATE",
compressionOptions: {
level: 9
}
});
}
catch (e2) {
this.log.warn(`Errored creating archive: ${e2.toString()}`);
return null;
}
}
async clearDuelLog() {
const runner = this.db.createQueryRunner();
try {
......
......@@ -13,6 +13,8 @@ import {User} from "./entities/User";
import {VipKey} from "./entities/VipKey";
import {UserDialog} from "./entities/UserDialog";
import {RandomDuelScore} from "./entities/RandomDuelScore";
import JSZip from "jszip";
import * as fs from "fs";
interface BasePlayerInfo {
name: string;
......@@ -35,6 +37,8 @@ export interface DuelLogPlayerInfo extends BasePlayerInfo {
cardCount: number;
}
export interface DuelLogQuery {roomName: string, duelCount: number, playerName: string, playerScore: number}
export class DataManager {
config: ConnectionOptions;
......@@ -256,6 +260,52 @@ export class DataManager {
}
private getEscapedString(text: string) {
return text.replace(/\\/g, "").replace(/_/g, "\\_").replace(/%/g, "\\%") + "%";
}
async getDuelLogFromCondition(data: DuelLogQuery) {
//console.log(data);
if(!data) {
return this.getAllDuelLogs();
}
const {roomName, duelCount, playerName, playerScore} = data;
const repo = this.db.getRepository(DuelLog);
try {
const queryBuilder = repo.createQueryBuilder("duelLog")
.where("1");
if(roomName != null && roomName.length) {
const escapedRoomName = this.getEscapedString(roomName);
queryBuilder.andWhere("duelLog.name like :escapedRoomName", { escapedRoomName });
}
if(duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
}
if(playerName != null && playerName.length || playerScore != null && !isNaN(playerScore)) {
let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams: any = {};
if(playerName != null && playerName.length) {
const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName like :escapedPlayerName";
innerQueryParams.escapedPlayerName = escapedPlayerName;
}
if(playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore";
innerQueryParams.playerScore = playerScore;
}
queryBuilder.andWhere(`exists (${innerQuery})`, innerQueryParams);
}
queryBuilder.orderBy("duelLog.id", "DESC")
.leftJoinAndSelect("duelLog.players", "player");
// console.log(queryBuilder.getSql());
const duelLogs = await queryBuilder.getMany();
return duelLogs;
} catch (e) {
this.log.warn(`Failed to fetch duel logs: ${e.toString()}`);
return [];
}
}
async getDuelLogFromId(id: number) {
const repo = this.db.getRepository(DuelLog);
try {
......@@ -291,10 +341,46 @@ export class DataManager {
const allDuelLogs = await this.getAllDuelLogs();
return allDuelLogs.map(duelLog => duelLog.getViewJSON(tournamentModeSettings));
}
async getDuelLogJSONFromCondition(tournamentModeSettings: any, data: DuelLogQuery) {
const allDuelLogs = await this.getDuelLogFromCondition(data);
return allDuelLogs.map(duelLog => duelLog.getViewJSON(tournamentModeSettings));
}
async getAllReplayFilenames() {
const allDuelLogs = await this.getAllDuelLogs();
return allDuelLogs.map(duelLog => duelLog.replayFileName);
}
async getReplayFilenamesFromCondition(data: DuelLogQuery) {
const allDuelLogs = await this.getDuelLogFromCondition(data);
return allDuelLogs.map(duelLog => duelLog.replayFileName);
}
async getReplayArchiveStreamFromCondition(rootPath: string, data: DuelLogQuery) {
const filenames = await this.getReplayFilenamesFromCondition(data);
if(!filenames.length) {
return null;
}
try {
const zip = new JSZip();
for(let fileName of filenames) {
const filePath = `${rootPath}${fileName}`;
try {
await fs.promises.access(filePath);
zip.file(fileName, fs.promises.readFile(filePath));
} catch(e) {
this.log.warn(`Errored archiving ${filePath}: ${e.toString()}`)
continue;
}
}
return zip.generateNodeStream({
compression: "DEFLATE",
compressionOptions: {
level: 9
}
});
} catch(e2) {
this.log.warn(`Errored creating archive: ${e2.toString()}`)
return null;
}
}
async clearDuelLog() {
const runner = this.db.createQueryRunner();
try {
......
......@@ -77,6 +77,7 @@ __decorate([
__metadata("design:type", Number)
], DuelLog.prototype, "roomMode", void 0);
__decorate([
typeorm_1.Index(),
typeorm_1.Column("tinyint", { unsigned: true }),
__metadata("design:type", Number)
], DuelLog.prototype, "duelCount", void 0);
......
......@@ -33,6 +33,7 @@ export class DuelLog extends CreateAndUpdateTimeBase {
@Column("tinyint", {unsigned: true})
roomMode: number;
@Index()
@Column("tinyint", {unsigned: true})
duelCount: number;
......
......@@ -66,6 +66,7 @@ __decorate([
__metadata("design:type", Number)
], DuelLogPlayer.prototype, "isFirst", void 0);
__decorate([
typeorm_1.Index(),
typeorm_1.Column("tinyint"),
__metadata("design:type", Number)
], DuelLogPlayer.prototype, "score", void 0);
......
......@@ -16,6 +16,7 @@ export class DuelLogPlayer extends BasePlayer {
@Column("tinyint", {unsigned: true})
isFirst: number;
@Index()
@Column("tinyint")
score: number;
......
......@@ -846,6 +846,11 @@
"minimatch": "^3.0.4"
}
},
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
......@@ -954,11 +959,30 @@
"verror": "1.10.0"
}
},
"jszip": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz",
"integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==",
"requires": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"set-immediate-shim": "~1.0.1"
}
},
"lazy": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz",
"integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA="
},
"lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"requires": {
"immediate": "~3.0.5"
}
},
"lines-and-columns": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
......@@ -1370,6 +1394,11 @@
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz",
"integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc="
},
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"parent-require": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz",
......@@ -1657,6 +1686,11 @@
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"set-immediate-shim": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
},
"sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
......
......@@ -2006,7 +2006,7 @@ deck_name_match = global.deck_name_match = (deck_name, player_name) ->
ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server, datas)->
# checkmate use username$password, but here don't
# so remove the password
name_full =info.name.split("$")
name_full =info.name.replace(/\\/g, "").split("$")
name = name_full[0]
vpass = name_full[1]
if vpass and !vpass.length
......@@ -3880,6 +3880,21 @@ global.rebooted = false
#http
if true
getDuelLogQueryFromQs = (qdata) ->
try
ret = {}
if(qdata.roomname)
ret.roomName = decodeURIComponent(qdata.roomname).trim()
if(qdata.duelcount)
ret.duelCount = parseInt(decodeURIComponent(qdata.duelcount))
if(qdata.playername)
ret.playerName = decodeURIComponent(qdata.playername).trim()
if(qdata.score)
ret.playerScore = parseInt(decodeURIComponent(qdata.score))
return ret
catch
return {}
addCallback = (callback, text)->
if not callback then return text
return callback + "( " + text + " );"
......@@ -3933,7 +3948,7 @@ if true
return
else
response.writeHead(200)
duellog = JSON.stringify(await dataManager.getDuelLogJSON(settings.modules.tournament_mode), null, 2)
duellog = JSON.stringify(await dataManager.getDuelLogJSONFromCondition(settings.modules.tournament_mode, getDuelLogQueryFromQs(u.query)), null, 2)
response.end(addCallback(u.query.callback, duellog))
else if u.pathname == '/api/getkeys' and settings.modules.vip.enabled
......@@ -3953,38 +3968,20 @@ if true
return
else
try
archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip"
archive_args = ["a", "-mx0", "-y", archive_name]
check = false
for filename in await dataManager.getAllReplayFilenames()
check = true
archive_args.push(filename)
if !check
archiveStream = await dataManager.getReplayArchiveStreamFromCondition(settings.modules.tournament_mode.replay_path, getDuelLogQueryFromQs(u.query))
if !archiveStream
response.writeHead(403)
response.end("Duel logs not found.")
response.end("Replay not found.")
return
archive_process = spawn settings.modules.tournament_mode.replay_archive_tool, archive_args, {cwd: settings.modules.tournament_mode.replay_path}
archive_process.on 'error', (err)=>
response.writeHead(403)
response.end("Failed packing replays. " + err)
return
archive_process.on 'exit', (code)=>
fs.readFile(settings.modules.tournament_mode.replay_path + archive_name, (error, buffer)->
if error
response.writeHead(403)
response.end("Failed sending replays. " + error)
return
else
response.writeHead(200, { "Content-Type": "application/octet-stream", "Content-Disposition": "attachment" })
response.end(buffer)
return
)
archive_process.stdout.setEncoding 'utf8'
archive_process.stdout.on 'data', (data)=>
log.info "archive process: " + data
archive_process.stderr.setEncoding 'utf8'
archive_process.stderr.on 'data', (data)=>
log.warn "archive error: " + data
response.writeHead(200, { "Content-Type": "application/octet-stream", "Content-Disposition": "attachment" })
archiveStream.on "data", (data) ->
response.write data
archiveStream.on "end", () ->
response.end()
archiveStream.on "close", () ->
log.warn("Archive closed")
archiveStream.on "error", (error) ->
log.warn("Archive error: #{error}")
catch error
response.writeHead(403)
response.end("Failed reading replays. " + error)
......
// Generated by CoffeeScript 2.5.1
(function() {
// 标准库
var CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_get_save_data, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, CLIENT_send_vip_status, CLIENT_use_cdkey, 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_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, athleticChecker, auth, axios, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_queue_callbacks, checkFileExists, concat_name, createDirectoryIfNotExists, crypto, dataManager, deck_name_match, dialogues, disconnect_list, exec, execFile, fs, geoip, getSeedTimet, get_callback, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, is_challonge_requesting, lflists, loadJSON, loadJSONAsync, loadLFList, loadRemoteData, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, memory_usage, merge, moment, net, netRequestHandler, os, path, qs, real_windbot_server_ip, refresh_challonge_cache, release_disconnect, replaced_index, report_to_big_brother, request, 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, words, ygopro, zlib;
var CLIENT_check_vip, CLIENT_get_absolute_pos, CLIENT_get_authorize_key, CLIENT_get_kick_reconnect_target, CLIENT_get_partner, CLIENT_get_save_data, CLIENT_heartbeat_register, CLIENT_heartbeat_unregister, CLIENT_import_data, CLIENT_is_able_to_kick_reconnect, CLIENT_is_able_to_reconnect, CLIENT_is_banned_by_mc, CLIENT_is_player, CLIENT_kick, CLIENT_kick_reconnect, CLIENT_pre_reconnect, CLIENT_reconnect, CLIENT_reconnect_register, CLIENT_reconnect_unregister, CLIENT_send_pre_reconnect_info, CLIENT_send_reconnect_info, CLIENT_send_replays, CLIENT_send_vip_status, CLIENT_use_cdkey, 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_unwelcome, ROOM_validate, ReplayParser, ResolveData, Room, SERVER_clear_disconnect, SERVER_kick, SOCKET_flush_data, VIP_generate_cdkeys, _, _async, addCallback, athleticChecker, auth, axios, badwords, ban_user, bunyan, challonge, challonge_cache, challonge_queue_callbacks, checkFileExists, concat_name, createDirectoryIfNotExists, crypto, dataManager, deck_name_match, dialogues, disconnect_list, exec, execFile, fs, geoip, getDuelLogQueryFromQs, getSeedTimet, get_callback, get_memory_usage, http, httpRequestListener, importOldConfig, import_datas, init, is_challonge_requesting, lflists, loadJSON, loadJSONAsync, loadLFList, loadRemoteData, load_dialogues, load_dialogues_custom, load_tips, load_tips_zh, load_words, log, long_resolve_cards, memory_usage, merge, moment, net, netRequestHandler, os, path, qs, real_windbot_server_ip, refresh_challonge_cache, release_disconnect, replaced_index, report_to_big_brother, request, 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, words, ygopro, zlib;
net = require('net');
......@@ -2708,7 +2708,7 @@
var banMCRequest, e, geo, lang, name, name_full, struct, vpass;
// checkmate use username$password, but here don't
// so remove the password
name_full = info.name.split("$");
name_full = info.name.replace(/\\/g, "").split("$");
name = name_full[0];
vpass = name_full[1];
if (vpass && !vpass.length) {
......@@ -5206,6 +5206,27 @@
//http
if (true) {
getDuelLogQueryFromQs = function(qdata) {
var ret;
try {
ret = {};
if (qdata.roomname) {
ret.roomName = decodeURIComponent(qdata.roomname).trim();
}
if (qdata.duelcount) {
ret.duelCount = parseInt(decodeURIComponent(qdata.duelcount));
}
if (qdata.playername) {
ret.playerName = decodeURIComponent(qdata.playername).trim();
}
if (qdata.score) {
ret.playerScore = parseInt(decodeURIComponent(qdata.score));
}
return ret;
} catch (error1) {
return {};
}
};
addCallback = function(callback, text) {
if (!callback) {
return text;
......@@ -5213,7 +5234,7 @@
return callback + "( " + text + " );";
};
httpRequestListener = async function(request, response) {
var archive_args, archive_name, archive_process, buffer, check, death_room_found, duellog, e, err, error, filename, getpath, j, len, parseQueryString, pass_validated, ref, ret_keys, roomsjson, success, u;
var archiveStream, buffer, death_room_found, duellog, e, err, error, filename, getpath, parseQueryString, pass_validated, ret_keys, roomsjson, success, u;
parseQueryString = true;
u = url.parse(request.url, parseQueryString);
//pass_validated = u.query.pass == settings.modules.http.password
......@@ -5276,7 +5297,7 @@
return;
} else {
response.writeHead(200);
duellog = JSON.stringify((await dataManager.getDuelLogJSON(settings.modules.tournament_mode)), null, 2);
duellog = JSON.stringify((await dataManager.getDuelLogJSONFromCondition(settings.modules.tournament_mode, getDuelLogQueryFromQs(u.query))), null, 2);
response.end(addCallback(u.query.callback, duellog));
}
} else if (u.pathname === '/api/getkeys' && settings.modules.vip.enabled) {
......@@ -5296,48 +5317,27 @@
return;
} else {
try {
archive_name = moment().format('YYYY-MM-DD HH-mm-ss') + ".zip";
archive_args = ["a", "-mx0", "-y", archive_name];
check = false;
ref = (await dataManager.getAllReplayFilenames());
for (j = 0, len = ref.length; j < len; j++) {
filename = ref[j];
check = true;
archive_args.push(filename);
}
if (!check) {
archiveStream = (await dataManager.getReplayArchiveStreamFromCondition(settings.modules.tournament_mode.replay_path, getDuelLogQueryFromQs(u.query)));
if (!archiveStream) {
response.writeHead(403);
response.end("Duel logs not found.");
response.end("Replay not found.");
return;
}
archive_process = spawn(settings.modules.tournament_mode.replay_archive_tool, archive_args, {
cwd: settings.modules.tournament_mode.replay_path
response.writeHead(200, {
"Content-Type": "application/octet-stream",
"Content-Disposition": "attachment"
});
archive_process.on('error', (err) => {
response.writeHead(403);
response.end("Failed packing replays. " + err);
archiveStream.on("data", function(data) {
return response.write(data);
});
archive_process.on('exit', (code) => {
return fs.readFile(settings.modules.tournament_mode.replay_path + archive_name, function(error, buffer) {
if (error) {
response.writeHead(403);
response.end("Failed sending replays. " + error);
} else {
response.writeHead(200, {
"Content-Type": "application/octet-stream",
"Content-Disposition": "attachment"
});
response.end(buffer);
}
});
archiveStream.on("end", function() {
return response.end();
});
archive_process.stdout.setEncoding('utf8');
archive_process.stdout.on('data', (data) => {
return log.info("archive process: " + data);
archiveStream.on("close", function() {
return log.warn("Archive closed");
});
archive_process.stderr.setEncoding('utf8');
archive_process.stderr.on('data', (data) => {
return log.warn("archive error: " + data);
archiveStream.on("error", function(error) {
return log.warn(`Archive error: ${error}`);
});
} catch (error1) {
error = error1;
......
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