Commit 1e0613cb authored by nanahira's avatar nanahira

Merge branch 'master' into enter-room-log

parents 78da1f9d 103429ba
Pipeline #10117 passed with stages
in 40 minutes and 22 seconds
...@@ -8,7 +8,7 @@ RUN apt update && \ ...@@ -8,7 +8,7 @@ RUN apt update && \
rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/* rm -rf /tmp/* /var/tmp/* /var/lib/apt/lists/*
# windbot # windbot
RUN git clone --depth=1 https://github.com/nanahira/windbot /tmp/windbot && \ RUN git clone --depth=1 https://code.mycard.moe/nanahira/windbot /tmp/windbot && \
cd /tmp/windbot && \ cd /tmp/windbot && \
xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \ xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \
mv /tmp/windbot/bin/Release /ygopro-server/windbot && \ mv /tmp/windbot/bin/Release /ygopro-server/windbot && \
......
...@@ -11,6 +11,8 @@ const typedefs_json_1 = __importDefault(require("./data/typedefs.json")); ...@@ -11,6 +11,8 @@ const typedefs_json_1 = __importDefault(require("./data/typedefs.json"));
const proto_structs_json_1 = __importDefault(require("./data/proto_structs.json")); const proto_structs_json_1 = __importDefault(require("./data/proto_structs.json"));
const constants_json_1 = __importDefault(require("./data/constants.json")); const constants_json_1 = __importDefault(require("./data/constants.json"));
class Handler { class Handler {
handler;
synchronous;
constructor(handler, synchronous) { constructor(handler, synchronous) {
this.handler = handler; this.handler = handler;
this.synchronous = synchronous || false; this.synchronous = synchronous || false;
...@@ -28,6 +30,13 @@ class Handler { ...@@ -28,6 +30,13 @@ class Handler {
} }
} }
class YGOProMessagesHelper { class YGOProMessagesHelper {
handlers;
structs;
structs_declaration;
typedefs;
proto_structs;
constants;
singleHandleLimit;
constructor(singleHandleLimit) { constructor(singleHandleLimit) {
this.handlers = { this.handlers = {
STOC: [new Map(), STOC: [new Map(),
...@@ -62,7 +71,7 @@ class YGOProMessagesHelper { ...@@ -62,7 +71,7 @@ class YGOProMessagesHelper {
this.structs = new Map(); this.structs = new Map();
for (let name in this.structs_declaration) { for (let name in this.structs_declaration) {
const declaration = this.structs_declaration[name]; const declaration = this.structs_declaration[name];
let result = struct_1.Struct(); let result = (0, struct_1.Struct)();
for (let field of declaration) { for (let field of declaration) {
if (field.encoding) { if (field.encoding) {
switch (field.encoding) { switch (field.encoding) {
...@@ -171,12 +180,13 @@ class YGOProMessagesHelper { ...@@ -171,12 +180,13 @@ class YGOProMessagesHelper {
} }
handlerCollection.get(translatedProto).push(handlerObj); handlerCollection.get(translatedProto).push(handlerObj);
} }
async handleBuffer(messageBuffer, direction, protoFilter, params) { async handleBuffer(messageBuffer, direction, protoFilter, params, preconnect = false) {
let feedback = null; let feedback = null;
let messageLength = 0; let messageLength = 0;
let bufferProto = 0; let bufferProto = 0;
let datas = []; let datas = [];
for (let l = 0; l < this.singleHandleLimit; ++l) { const limit = preconnect ? 2 : this.singleHandleLimit;
for (let l = 0; l < limit; ++l) {
if (messageLength === 0) { if (messageLength === 0) {
if (messageBuffer.length >= 2) { if (messageBuffer.length >= 2) {
messageLength = messageBuffer.readUInt16LE(0); messageLength = messageBuffer.readUInt16LE(0);
...@@ -206,7 +216,14 @@ class YGOProMessagesHelper { ...@@ -206,7 +216,14 @@ class YGOProMessagesHelper {
else { else {
if (messageBuffer.length >= 2 + messageLength) { if (messageBuffer.length >= 2 + messageLength) {
const proto = this.constants[direction][bufferProto]; const proto = this.constants[direction][bufferProto];
let cancel = proto && protoFilter && underscore_1.default.indexOf(protoFilter, proto) === -1; let cancel = proto && protoFilter && !protoFilter.includes(proto);
if (cancel && preconnect) {
feedback = {
type: "INVALID_PACKET",
message: `${direction} proto not allowed`
};
break;
}
let buffer = messageBuffer.slice(3, 2 + messageLength); let buffer = messageBuffer.slice(3, 2 + messageLength);
//console.log(l, direction, proto, cancel); //console.log(l, direction, proto, cancel);
for (let priority = 0; priority < 4; ++priority) { for (let priority = 0; priority < 4; ++priority) {
...@@ -224,6 +241,12 @@ class YGOProMessagesHelper { ...@@ -224,6 +241,12 @@ class YGOProMessagesHelper {
for (let handler of handlerCollection.get(bufferProto)) { for (let handler of handlerCollection.get(bufferProto)) {
cancel = await handler.handle(buffer, info, datas, params); cancel = await handler.handle(buffer, info, datas, params);
if (cancel) { if (cancel) {
if (cancel === '_cancel') {
return {
datas: [],
feedback
};
}
break; break;
} }
} }
...@@ -246,10 +269,10 @@ class YGOProMessagesHelper { ...@@ -246,10 +269,10 @@ class YGOProMessagesHelper {
break; break;
} }
} }
if (l === this.singleHandleLimit - 1) { if (l === limit - 1) {
feedback = { feedback = {
type: "OVERSIZE", type: "OVERSIZE",
message: `Oversized ${direction}` message: `Oversized ${direction} ${limit}`
}; };
} }
} }
......
...@@ -8,13 +8,13 @@ import net from "net"; ...@@ -8,13 +8,13 @@ import net from "net";
class Handler { class Handler {
private handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>; private handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>;
synchronous: boolean; synchronous: boolean;
constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean) { constructor(handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>, synchronous: boolean) {
this.handler = handler; this.handler = handler;
this.synchronous = synchronous || false; this.synchronous = synchronous || false;
} }
async handle(buffer: Buffer, info: any, datas: Buffer[], params: any) { async handle(buffer: Buffer, info: any, datas: Buffer[], params: any): Promise<boolean | string> {
if (this.synchronous) { if (this.synchronous) {
return !!(await this.handler(buffer, info, datas, params)); return !!(await this.handler(buffer, info, datas, params));
} else { } else {
...@@ -208,7 +208,7 @@ export class YGOProMessagesHelper { ...@@ -208,7 +208,7 @@ export class YGOProMessagesHelper {
}); });
} }
addHandler(protostr: string, handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean>, synchronous: boolean, priority: number) { addHandler(protostr: string, handler: (buffer: Buffer, info: any, datas: Buffer[], params: any) => Promise<boolean | string>, synchronous: boolean, priority: number) {
if (priority < 0 || priority > 4) { if (priority < 0 || priority > 4) {
throw "Invalid priority: " + priority; throw "Invalid priority: " + priority;
} }
...@@ -226,12 +226,13 @@ export class YGOProMessagesHelper { ...@@ -226,12 +226,13 @@ export class YGOProMessagesHelper {
handlerCollection.get(translatedProto).push(handlerObj); handlerCollection.get(translatedProto).push(handlerObj);
} }
async handleBuffer(messageBuffer: Buffer, direction: string, protoFilter?: string[], params?: any): Promise<HandleResult> { async handleBuffer(messageBuffer: Buffer, direction: string, protoFilter?: string[], params?: any, preconnect = false): Promise<HandleResult> {
let feedback: Feedback = null; let feedback: Feedback = null;
let messageLength = 0; let messageLength = 0;
let bufferProto = 0; let bufferProto = 0;
let datas: Buffer[] = []; let datas: Buffer[] = [];
for (let l = 0; l < this.singleHandleLimit; ++l) { const limit = preconnect ? 2 : this.singleHandleLimit;
for (let l = 0; l < limit; ++l) {
if (messageLength === 0) { if (messageLength === 0) {
if (messageBuffer.length >= 2) { if (messageBuffer.length >= 2) {
messageLength = messageBuffer.readUInt16LE(0); messageLength = messageBuffer.readUInt16LE(0);
...@@ -257,7 +258,14 @@ export class YGOProMessagesHelper { ...@@ -257,7 +258,14 @@ export class YGOProMessagesHelper {
} else { } else {
if (messageBuffer.length >= 2 + messageLength) { if (messageBuffer.length >= 2 + messageLength) {
const proto = this.constants[direction][bufferProto]; const proto = this.constants[direction][bufferProto];
let cancel = proto && protoFilter && _.indexOf(protoFilter, proto) === -1; let cancel: string | boolean = proto && protoFilter && !protoFilter.includes(proto);
if (cancel && preconnect) {
feedback = {
type: "INVALID_PACKET",
message: `${direction} proto not allowed`
};
break;
}
let buffer = messageBuffer.slice(3, 2 + messageLength); let buffer = messageBuffer.slice(3, 2 + messageLength);
//console.log(l, direction, proto, cancel); //console.log(l, direction, proto, cancel);
for (let priority = 0; priority < 4; ++priority) { for (let priority = 0; priority < 4; ++priority) {
...@@ -275,6 +283,12 @@ export class YGOProMessagesHelper { ...@@ -275,6 +283,12 @@ export class YGOProMessagesHelper {
for (let handler of handlerCollection.get(bufferProto)) { for (let handler of handlerCollection.get(bufferProto)) {
cancel = await handler.handle(buffer, info, datas, params); cancel = await handler.handle(buffer, info, datas, params);
if (cancel) { if (cancel) {
if (cancel === '_cancel') {
return {
datas: [],
feedback
}
}
break; break;
} }
} }
...@@ -296,10 +310,10 @@ export class YGOProMessagesHelper { ...@@ -296,10 +310,10 @@ export class YGOProMessagesHelper {
break; break;
} }
} }
if (l === this.singleHandleLimit - 1) { if (l === limit - 1) {
feedback = { feedback = {
type: "OVERSIZE", type: "OVERSIZE",
message: `Oversized ${direction}` message: `Oversized ${direction} ${limit}`
}; };
} }
} }
......
...@@ -8,6 +8,9 @@ const axios_1 = __importDefault(require("axios")); ...@@ -8,6 +8,9 @@ const axios_1 = __importDefault(require("axios"));
const querystring_1 = __importDefault(require("querystring")); const querystring_1 = __importDefault(require("querystring"));
const moment_1 = __importDefault(require("moment")); const moment_1 = __importDefault(require("moment"));
class AthleticChecker { class AthleticChecker {
config;
athleticDeckCache;
lastAthleticDeckFetchTime;
constructor(config) { constructor(config) {
this.config = config; this.config = config;
} }
...@@ -16,7 +19,7 @@ class AthleticChecker { ...@@ -16,7 +19,7 @@ class AthleticChecker {
return deckText; return deckText;
} }
async getAthleticDecks() { async getAthleticDecks() {
if (this.athleticDeckCache && moment_1.default().diff(this.lastAthleticDeckFetchTime, "seconds") < this.config.ttl) { if (this.athleticDeckCache && (0, moment_1.default)().diff(this.lastAthleticDeckFetchTime, "seconds") < this.config.ttl) {
return this.athleticDeckCache; return this.athleticDeckCache;
} }
const { data } = await axios_1.default.get(this.config.rankURL, { const { data } = await axios_1.default.get(this.config.rankURL, {
...@@ -27,7 +30,7 @@ class AthleticChecker { ...@@ -27,7 +30,7 @@ class AthleticChecker {
}); });
const athleticDecks = data.slice(0, this.config.rankCount).map(m => m.name); const athleticDecks = data.slice(0, this.config.rankCount).map(m => m.name);
this.athleticDeckCache = athleticDecks; this.athleticDeckCache = athleticDecks;
this.lastAthleticDeckFetchTime = moment_1.default(); this.lastAthleticDeckFetchTime = (0, moment_1.default)();
return athleticDecks; return athleticDecks;
} }
async getDeckType(deck) { async getDeckType(deck) {
...@@ -42,7 +45,7 @@ class AthleticChecker { ...@@ -42,7 +45,7 @@ class AthleticChecker {
try { try {
const athleticDecks = await this.getAthleticDecks(); const athleticDecks = await this.getAthleticDecks();
const deckType = await this.getDeckType(deck); const deckType = await this.getDeckType(deck);
const athletic = athleticDecks.includes(deckType); const athletic = athleticDecks.findIndex(d => d === deckType) + 1;
return { success: true, athletic, message: null }; return { success: true, athletic, message: null };
} }
catch (e) { catch (e) {
......
...@@ -21,7 +21,7 @@ interface AthleticDecksReturnData { ...@@ -21,7 +21,7 @@ interface AthleticDecksReturnData {
interface ReturnMessage { interface ReturnMessage {
success: boolean; success: boolean;
athletic?: boolean; athletic?: number;
message: string; message: string;
} }
...@@ -63,8 +63,8 @@ export class AthleticChecker { ...@@ -63,8 +63,8 @@ export class AthleticChecker {
try { try {
const athleticDecks = await this.getAthleticDecks(); const athleticDecks = await this.getAthleticDecks();
const deckType = await this.getDeckType(deck); const deckType = await this.getDeckType(deck);
const athletic = athleticDecks.includes(deckType); const athletic = athleticDecks.findIndex(d => d === deckType) + 1;
return { success: true, athletic, message: null } return { success: true, athletic, message: null };
} catch (e) { } catch (e) {
return { success: false, message: e.toString() }; return { success: false, message: e.toString() };
} }
......
...@@ -40,35 +40,40 @@ const jszip_1 = __importDefault(require("jszip")); ...@@ -40,35 +40,40 @@ const jszip_1 = __importDefault(require("jszip"));
const fs = __importStar(require("fs")); const fs = __importStar(require("fs"));
require("reflect-metadata"); require("reflect-metadata");
class DataManager { class DataManager {
config;
log;
ready;
db;
constructor(config, log) { constructor(config, log) {
this.config = config; this.config = config;
this.ready = false;
this.log = log; this.log = log;
this.ready = false;
} }
async transaction(fun) { async transaction(fun) {
const runner = this.db.createQueryRunner();
await runner.connect();
await runner.startTransaction();
let result = false;
try { try {
result = await fun(runner.manager); // @ts-ignore
if (this.config.type !== 'sqlite') {
this.db.transaction(async (mdb) => {
const result = await fun(mdb);
if (!result) {
throw new Error('Rollback requested.');
}
});
}
else {
await fun(this.db.manager);
}
} }
catch (e) { catch (e) {
result = false; this.log.warn(`Transaction failed: ${e.toString()}`);
this.log.warn(`Failed running transaction: ${e.toString()}`);
}
if (result) {
await runner.commitTransaction();
} }
else {
await runner.rollbackTransaction();
}
await runner.release();
} }
async init() { async init() {
this.db = await typeorm_1.createConnection({ this.db = await (0, typeorm_1.createConnection)({
type: "mysql", type: "mysql",
synchronize: true, synchronize: true,
supportBigNumbers: true,
bigNumberStrings: false,
entities: ["./data-manager/entities/*.js"], entities: ["./data-manager/entities/*.js"],
...this.config ...this.config
}); });
...@@ -76,8 +81,13 @@ class DataManager { ...@@ -76,8 +81,13 @@ class DataManager {
} }
async getCloudReplaysFromKey(key) { async getCloudReplaysFromKey(key) {
try { try {
const replays = await this.db.createQueryBuilder(CloudReplay_1.CloudReplay, "replay") const replaysQuery = this.db.createQueryBuilder(CloudReplay_1.CloudReplay, "replay");
.where("exists (select id from cloud_replay_player where cloud_replay_player.cloudReplayId = replay.id and cloud_replay_player.key = :key)", { key }) const sqb = replaysQuery.subQuery()
.select('splayer.id')
.from(CloudReplayPlayer_1.CloudReplayPlayer, 'splayer')
.where('splayer.cloudReplayId = replay.id')
.andWhere('splayer.key = :key');
const replays = await replaysQuery.where(`exists ${sqb.getQuery()}`, { key })
.orderBy("replay.date", "DESC") .orderBy("replay.date", "DESC")
.limit(10) .limit(10)
.leftJoinAndSelect("replay.players", "player") .leftJoinAndSelect("replay.players", "player")
...@@ -125,7 +135,7 @@ class DataManager { ...@@ -125,7 +135,7 @@ class DataManager {
const replay = new CloudReplay_1.CloudReplay(); const replay = new CloudReplay_1.CloudReplay();
replay.id = id; replay.id = id;
replay.fromBuffer(buffer); replay.fromBuffer(buffer);
replay.date = moment_1.default().toDate(); replay.date = (0, moment_1.default)().toDate();
const players = playerInfos.map(p => { const players = playerInfos.map(p => {
const player = CloudReplayPlayer_1.CloudReplayPlayer.fromPlayerInfo(p); const player = CloudReplayPlayer_1.CloudReplayPlayer.fromPlayerInfo(p);
return player; return player;
...@@ -216,12 +226,12 @@ class DataManager { ...@@ -216,12 +226,12 @@ class DataManager {
if (ban) { if (ban) {
ban.count += count; ban.count += count;
const banTime = ban.count > 3 ? Math.pow(2, ban.count - 3) * 2 : 0; const banTime = ban.count > 3 ? Math.pow(2, ban.count - 3) * 2 : 0;
const banDate = moment_1.default(ban.time); const banDate = (0, moment_1.default)(ban.time);
if (moment_1.default().isAfter(banDate)) { if ((0, moment_1.default)().isAfter(banDate)) {
ban.time = moment_1.default().add(banTime, 'm').toDate(); ban.time = (0, moment_1.default)().add(banTime, 'm').toDate();
} }
else { else {
ban.time = moment_1.default(banDate).add(banTime, 'm').toDate(); ban.time = (0, moment_1.default)(banDate).add(banTime, 'm').toDate();
} }
if (!underscore_1.default.contains(ban.reasons, reason)) { if (!underscore_1.default.contains(ban.reasons, reason)) {
ban.reasons.push(reason); ban.reasons.push(reason);
...@@ -231,7 +241,7 @@ class DataManager { ...@@ -231,7 +241,7 @@ class DataManager {
else { else {
ban = new RandomDuelBan_1.RandomDuelBan(); ban = new RandomDuelBan_1.RandomDuelBan();
ban.ip = ip; ban.ip = ip;
ban.time = moment_1.default().toDate(); ban.time = (0, moment_1.default)().toDate();
ban.count = count; ban.count = count;
ban.reasons = [reason]; ban.reasons = [reason];
ban.needTip = 1; ban.needTip = 1;
...@@ -275,18 +285,24 @@ class DataManager { ...@@ -275,18 +285,24 @@ class DataManager {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount }); queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
} }
if (playerName != null && playerName.length || playerScore != null && !isNaN(playerScore)) { 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 sqb = queryBuilder.subQuery()
.select('splayer.id')
.from(DuelLogPlayer_1.DuelLogPlayer, 'splayer')
.where('splayer.duelLogId = duelLog.id');
//let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams = {}; const innerQueryParams = {};
if (playerName != null && playerName.length) { if (playerName != null && playerName.length) {
//const escapedPlayerName = this.getEscapedString(playerName); //const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName = :playerName"; sqb.andWhere('splayer.realName = :playerName');
//innerQuery += " and duel_log_player.realName = :playerName";
innerQueryParams.playerName = playerName; innerQueryParams.playerName = playerName;
} }
if (playerScore != null && !isNaN(playerScore)) { if (playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore"; //innerQuery += " and duel_log_player.score = :playerScore";
sqb.andWhere('splayer.score = :playerScore');
innerQueryParams.playerScore = playerScore; innerQueryParams.playerScore = playerScore;
} }
queryBuilder.andWhere(`exists (${innerQuery})`, innerQueryParams); queryBuilder.andWhere(`exists ${sqb.getQuery()}`, innerQueryParams);
} }
queryBuilder.orderBy("duelLog.id", "DESC") queryBuilder.orderBy("duelLog.id", "DESC")
.leftJoinAndSelect("duelLog.players", "player"); .leftJoinAndSelect("duelLog.players", "player");
...@@ -313,8 +329,16 @@ class DataManager { ...@@ -313,8 +329,16 @@ class DataManager {
async getDuelLogFromRecoverSearch(realName) { async getDuelLogFromRecoverSearch(realName) {
const repo = this.db.getRepository(DuelLog_1.DuelLog); const repo = this.db.getRepository(DuelLog_1.DuelLog);
try { try {
const duelLogs = await repo.createQueryBuilder("duelLog") const duelLogsQuery = repo.createQueryBuilder("duelLog")
.where("startDeckBuffer is not null and currentDeckBuffer is not null and roomMode != 2 and exists (select id from duel_log_player where duel_log_player.duelLogId = duelLog.id and duel_log_player.realName = :realName)", { realName }) .where('startDeckBuffer is not null')
.andWhere('currentDeckBuffer is not null')
.andWhere('roomMode != 2');
const sqb = duelLogsQuery.subQuery()
.select('splayer.id')
.from(DuelLogPlayer_1.DuelLogPlayer, 'splayer')
.andWhere('splayer.duelLogId = duelLog.id')
.andWhere('splayer.realName = :realName');
const duelLogs = await duelLogsQuery.andWhere(`exists ${sqb.getQuery()}`, { realName })
.orderBy("duelLog.id", "DESC") .orderBy("duelLog.id", "DESC")
.limit(10) .limit(10)
.leftJoinAndSelect("duelLog.players", "player") .leftJoinAndSelect("duelLog.players", "player")
...@@ -392,7 +416,7 @@ class DataManager { ...@@ -392,7 +416,7 @@ class DataManager {
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();
duelLog.name = name; duelLog.name = name;
duelLog.time = moment_1.default().toDate(); duelLog.time = (0, moment_1.default)().toDate();
duelLog.roomId = roomId; duelLog.roomId = roomId;
duelLog.cloudReplayId = cloudReplayId; duelLog.cloudReplayId = cloudReplayId;
duelLog.replayFileName = replayFilename; duelLog.replayFileName = replayFilename;
...@@ -599,11 +623,11 @@ class DataManager { ...@@ -599,11 +623,11 @@ class DataManager {
} }
const keyType = vipKey.type; const keyType = vipKey.type;
const previousDate = user.vipExpireDate; const previousDate = user.vipExpireDate;
if (previousDate && moment_1.default().isBefore(previousDate)) { if (previousDate && (0, moment_1.default)().isBefore(previousDate)) {
user.vipExpireDate = moment_1.default(previousDate).add(keyType, "d").toDate(); user.vipExpireDate = (0, moment_1.default)(previousDate).add(keyType, "d").toDate();
} }
else { else {
user.vipExpireDate = moment_1.default().add(keyType, "d").toDate(); user.vipExpireDate = (0, moment_1.default)().add(keyType, "d").toDate();
} }
user = await mdb.save(user); user = await mdb.save(user);
vipKey.isUsed = 1; vipKey.isUsed = 1;
...@@ -647,7 +671,7 @@ class DataManager { ...@@ -647,7 +671,7 @@ class DataManager {
user = new User_1.User(); user = new User_1.User();
user.key = userKey; user.key = userKey;
} }
user.vipExpireDate = moment_1.default(oldVipUserInfo.expire_date).toDate(); user.vipExpireDate = (0, moment_1.default)(oldVipUserInfo.expire_date).toDate();
user.victory = oldVipUserInfo.victory || null; user.victory = oldVipUserInfo.victory || null;
user.words = oldVipUserInfo.words || null; user.words = oldVipUserInfo.words || null;
user = await mdb.save(user); user = await mdb.save(user);
......
import moment from "moment"; import moment from "moment";
import bunyan from "bunyan"; import bunyan from "bunyan";
import {Connection, ConnectionOptions, createConnection, EntityManager} from "typeorm"; import {Connection, createConnection, EntityManager} from "typeorm";
import {CloudReplay} from "./entities/CloudReplay"; import {CloudReplay} from "./entities/CloudReplay";
import {CloudReplayPlayer} from "./entities/CloudReplayPlayer"; import {CloudReplayPlayer} from "./entities/CloudReplayPlayer";
import {Ban} from "./entities/Ban"; import {Ban} from "./entities/Ban";
...@@ -16,6 +16,7 @@ import {RandomDuelScore} from "./entities/RandomDuelScore"; ...@@ -16,6 +16,7 @@ import {RandomDuelScore} from "./entities/RandomDuelScore";
import JSZip from "jszip"; import JSZip from "jszip";
import * as fs from "fs"; import * as fs from "fs";
import "reflect-metadata"; import "reflect-metadata";
import { MysqlConnectionOptions } from "typeorm/driver/mysql/MysqlConnectionOptions";
interface BasePlayerInfo { interface BasePlayerInfo {
name: string; name: string;
...@@ -42,37 +43,34 @@ export interface DuelLogQuery {roomName: string, duelCount: number, playerName: ...@@ -42,37 +43,34 @@ export interface DuelLogQuery {roomName: string, duelCount: number, playerName:
export class DataManager { export class DataManager {
config: ConnectionOptions;
ready: boolean; ready: boolean;
db: Connection; private db: Connection;
log: bunyan; constructor(private config: MysqlConnectionOptions, private log: bunyan) {
constructor(config: ConnectionOptions, log: bunyan) {
this.config = config;
this.ready = false; this.ready = false;
this.log = log;
} }
private async transaction(fun: (mdb: EntityManager) => Promise<boolean>) { private async transaction(fun: (mdb: EntityManager) => Promise<boolean>) {
const runner = this.db.createQueryRunner();
await runner.connect();
await runner.startTransaction();
let result = false;
try { try {
result = await fun(runner.manager); // @ts-ignore
} catch(e) { if (this.config.type !== 'sqlite') {
result = false; this.db.transaction(async (mdb) => {
this.log.warn(`Failed running transaction: ${e.toString()}`) const result = await fun(mdb);
} if (!result) {
if(result) { throw new Error('Rollback requested.');
await runner.commitTransaction(); }
} else { });
await runner.rollbackTransaction(); } else {
await fun(this.db.manager);
}
} catch (e) {
this.log.warn(`Transaction failed: ${e.toString()}`);
} }
await runner.release();
} }
async init() { async init() {
this.db = await createConnection({ this.db = await createConnection({
type: "mysql", type: "mysql",
synchronize: true, synchronize: true,
supportBigNumbers: true,
bigNumberStrings: false,
entities: ["./data-manager/entities/*.js"], entities: ["./data-manager/entities/*.js"],
...this.config ...this.config
}); });
...@@ -80,8 +78,13 @@ export class DataManager { ...@@ -80,8 +78,13 @@ export class DataManager {
} }
async getCloudReplaysFromKey(key: string) { async getCloudReplaysFromKey(key: string) {
try { try {
const replays = await this.db.createQueryBuilder(CloudReplay, "replay") const replaysQuery = this.db.createQueryBuilder(CloudReplay, "replay");
.where("exists (select id from cloud_replay_player where cloud_replay_player.cloudReplayId = replay.id and cloud_replay_player.key = :key)", { key }) const sqb = replaysQuery.subQuery()
.select('splayer.id')
.from(CloudReplayPlayer, 'splayer')
.where('splayer.cloudReplayId = replay.id')
.andWhere('splayer.key = :key');
const replays = await replaysQuery.where(`exists ${sqb.getQuery()}`, { key })
.orderBy("replay.date", "DESC") .orderBy("replay.date", "DESC")
.limit(10) .limit(10)
.leftJoinAndSelect("replay.players", "player") .leftJoinAndSelect("replay.players", "player")
...@@ -282,19 +285,25 @@ export class DataManager { ...@@ -282,19 +285,25 @@ export class DataManager {
if(duelCount != null && !isNaN(duelCount)) { if(duelCount != null && !isNaN(duelCount)) {
queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount }); queryBuilder.andWhere("duelLog.duelCount = :duelCount", { duelCount });
} }
if(playerName != null && playerName.length || playerScore != null && !isNaN(playerScore)) { 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 sqb = queryBuilder.subQuery()
.select('splayer.id')
.from(DuelLogPlayer, 'splayer')
.where('splayer.duelLogId = duelLog.id');
//let innerQuery = "select id from duel_log_player where duel_log_player.duelLogId = duelLog.id";
const innerQueryParams: any = {}; const innerQueryParams: any = {};
if(playerName != null && playerName.length) { if(playerName != null && playerName.length) {
//const escapedPlayerName = this.getEscapedString(playerName); //const escapedPlayerName = this.getEscapedString(playerName);
innerQuery += " and duel_log_player.realName = :playerName"; sqb.andWhere('splayer.realName = :playerName');
//innerQuery += " and duel_log_player.realName = :playerName";
innerQueryParams.playerName = playerName; innerQueryParams.playerName = playerName;
} }
if(playerScore != null && !isNaN(playerScore)) { if(playerScore != null && !isNaN(playerScore)) {
innerQuery += " and duel_log_player.score = :playerScore"; //innerQuery += " and duel_log_player.score = :playerScore";
sqb.andWhere('splayer.score = :playerScore');
innerQueryParams.playerScore = playerScore; innerQueryParams.playerScore = playerScore;
} }
queryBuilder.andWhere(`exists (${innerQuery})`, innerQueryParams); queryBuilder.andWhere(`exists ${sqb.getQuery()}`, innerQueryParams);
} }
queryBuilder.orderBy("duelLog.id", "DESC") queryBuilder.orderBy("duelLog.id", "DESC")
.leftJoinAndSelect("duelLog.players", "player"); .leftJoinAndSelect("duelLog.players", "player");
...@@ -322,8 +331,16 @@ export class DataManager { ...@@ -322,8 +331,16 @@ export class DataManager {
async getDuelLogFromRecoverSearch(realName: string) { async getDuelLogFromRecoverSearch(realName: string) {
const repo = this.db.getRepository(DuelLog); const repo = this.db.getRepository(DuelLog);
try { try {
const duelLogs = await repo.createQueryBuilder("duelLog") const duelLogsQuery = repo.createQueryBuilder("duelLog")
.where("startDeckBuffer is not null and currentDeckBuffer is not null and roomMode != 2 and exists (select id from duel_log_player where duel_log_player.duelLogId = duelLog.id and duel_log_player.realName = :realName)", { realName }) .where('startDeckBuffer is not null')
.andWhere('currentDeckBuffer is not null')
.andWhere('roomMode != 2');
const sqb = duelLogsQuery.subQuery()
.select('splayer.id')
.from(DuelLogPlayer, 'splayer')
.andWhere('splayer.duelLogId = duelLog.id')
.andWhere('splayer.realName = :realName');
const duelLogs = await duelLogsQuery.andWhere(`exists ${sqb.getQuery()}`, { realName })
.orderBy("duelLog.id", "DESC") .orderBy("duelLog.id", "DESC")
.limit(10) .limit(10)
.leftJoinAndSelect("duelLog.players", "player") .leftJoinAndSelect("duelLog.players", "player")
......
...@@ -17,7 +17,7 @@ function encodeDeck(deck) { ...@@ -17,7 +17,7 @@ function encodeDeck(deck) {
buffer.writeInt32LE(cardCode, pointer); buffer.writeInt32LE(cardCode, pointer);
pointer += 4; pointer += 4;
} }
assert_1.default(pointer === bufferSize, `Invalid buffer size. Expected: ${bufferSize}. Got: ${pointer}`); (0, assert_1.default)(pointer === bufferSize, `Invalid buffer size. Expected: ${bufferSize}. Got: ${pointer}`);
return buffer; return buffer;
} }
exports.encodeDeck = encodeDeck; exports.encodeDeck = encodeDeck;
...@@ -28,7 +28,7 @@ function decodeDeck(buffer) { ...@@ -28,7 +28,7 @@ function decodeDeck(buffer) {
const sideLength = buffer.readInt32LE(pointer); const sideLength = buffer.readInt32LE(pointer);
pointer += 4; pointer += 4;
const correctBufferLength = (2 + mainLength + sideLength) * 4; const correctBufferLength = (2 + mainLength + sideLength) * 4;
assert_1.default(buffer.length >= (2 + mainLength + sideLength) * 4, `Invalid buffer size. Expected: ${correctBufferLength}. Got: ${buffer.length}`); (0, assert_1.default)(buffer.length >= (2 + mainLength + sideLength) * 4, `Invalid buffer size. Expected: ${correctBufferLength}. Got: ${buffer.length}`);
const main = []; const main = [];
const side = []; const side = [];
for (let i = 0; i < mainLength; ++i) { for (let i = 0; i < mainLength; ++i) {
......
...@@ -13,24 +13,27 @@ exports.Ban = void 0; ...@@ -13,24 +13,27 @@ exports.Ban = void 0;
const typeorm_1 = require("typeorm"); const typeorm_1 = require("typeorm");
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let Ban = class Ban extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let Ban = class Ban extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
id;
ip;
name;
}; };
__decorate([ __decorate([
typeorm_1.PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }), (0, typeorm_1.PrimaryGeneratedColumn)({ unsigned: true, type: global.PrimaryKeyType || 'bigint' }),
__metadata("design:type", Number) __metadata("design:type", Number)
], Ban.prototype, "id", void 0); ], Ban.prototype, "id", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column({ type: "varchar", length: 64, nullable: true }), (0, typeorm_1.Column)({ type: "varchar", length: 64, nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], Ban.prototype, "ip", void 0); ], Ban.prototype, "ip", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column({ type: "varchar", length: 20, nullable: true }), (0, typeorm_1.Column)({ type: "varchar", length: 20, nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], Ban.prototype, "name", void 0); ], Ban.prototype, "name", void 0);
Ban = __decorate([ Ban = __decorate([
typeorm_1.Entity(), (0, typeorm_1.Entity)(),
typeorm_1.Unique(["ip", "name"]) (0, typeorm_1.Unique)(["ip", "name"])
], Ban); ], Ban);
exports.Ban = Ban; exports.Ban = Ban;
//# sourceMappingURL=Ban.js.map //# sourceMappingURL=Ban.js.map
\ No newline at end of file
...@@ -4,7 +4,7 @@ import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase"; ...@@ -4,7 +4,7 @@ import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase";
@Entity() @Entity()
@Unique(["ip", "name"]) @Unique(["ip", "name"])
export class Ban extends CreateAndUpdateTimeBase { export class Ban extends CreateAndUpdateTimeBase {
@PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }) @PrimaryGeneratedColumn({ unsigned: true, type: (global as any).PrimaryKeyType as ('bigint' | 'integer') || 'bigint' })
id: number; id: number;
@Index() @Index()
......
...@@ -13,17 +13,20 @@ exports.BasePlayer = void 0; ...@@ -13,17 +13,20 @@ exports.BasePlayer = void 0;
const typeorm_1 = require("typeorm"); const typeorm_1 = require("typeorm");
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
class BasePlayer extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { class BasePlayer extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
id;
name;
pos;
} }
__decorate([ __decorate([
typeorm_1.PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }), (0, typeorm_1.PrimaryGeneratedColumn)({ unsigned: true, type: global.PrimaryKeyType || 'bigint' }),
__metadata("design:type", Number) __metadata("design:type", Number)
], BasePlayer.prototype, "id", void 0); ], BasePlayer.prototype, "id", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "varchar", length: 20 }), (0, typeorm_1.Column)({ type: "varchar", length: 20 }),
__metadata("design:type", String) __metadata("design:type", String)
], BasePlayer.prototype, "name", void 0); ], BasePlayer.prototype, "name", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "tinyint" }), (0, typeorm_1.Column)({ type: "tinyint" }),
__metadata("design:type", Number) __metadata("design:type", Number)
], BasePlayer.prototype, "pos", void 0); ], BasePlayer.prototype, "pos", void 0);
exports.BasePlayer = BasePlayer; exports.BasePlayer = BasePlayer;
......
import {Column, PrimaryGeneratedColumn} from "typeorm"; import {Column, PrimaryGeneratedColumn} from "typeorm";
import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase"; import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase";
export abstract class BasePlayer extends CreateAndUpdateTimeBase { export abstract class BasePlayer extends CreateAndUpdateTimeBase {
@PrimaryGeneratedColumn({unsigned: true, type: "bigint"}) @PrimaryGeneratedColumn({unsigned: true, type: (global as any).PrimaryKeyType as ('bigint' | 'integer') || 'bigint'})
id: number; id: number;
@Column({ type: "varchar", length: 20 }) @Column({ type: "varchar", length: 20 })
...@@ -10,4 +9,4 @@ export abstract class BasePlayer extends CreateAndUpdateTimeBase { ...@@ -10,4 +9,4 @@ export abstract class BasePlayer extends CreateAndUpdateTimeBase {
@Column({ type: "tinyint" }) @Column({ type: "tinyint" })
pos: number; pos: number;
} }
\ No newline at end of file
...@@ -19,15 +19,19 @@ const underscore_1 = __importDefault(require("underscore")); ...@@ -19,15 +19,19 @@ const underscore_1 = __importDefault(require("underscore"));
const moment_1 = __importDefault(require("moment")); const moment_1 = __importDefault(require("moment"));
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let CloudReplay = class CloudReplay extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let CloudReplay = class CloudReplay extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
id;
data;
fromBuffer(buffer) { fromBuffer(buffer) {
this.data = buffer.toString("base64"); this.data = buffer.toString("base64");
} }
toBuffer() { toBuffer() {
return Buffer.from(this.data, "base64"); return Buffer.from(this.data, "base64");
} }
date;
getDateString() { getDateString() {
return moment_1.default(this.date).format('YYYY-MM-DD HH:mm:ss'); return (0, moment_1.default)(this.date).format('YYYY-MM-DD HH:mm:ss');
} }
players;
getPlayerNamesString() { getPlayerNamesString() {
const playerInfos = underscore_1.default.clone(this.players); const playerInfos = underscore_1.default.clone(this.players);
playerInfos.sort((p1, p2) => p1.pos - p2.pos); playerInfos.sort((p1, p2) => p1.pos - p2.pos);
...@@ -38,24 +42,24 @@ let CloudReplay = class CloudReplay extends CreateAndUpdateTimeBase_1.CreateAndU ...@@ -38,24 +42,24 @@ let CloudReplay = class CloudReplay extends CreateAndUpdateTimeBase_1.CreateAndU
} }
}; };
__decorate([ __decorate([
typeorm_1.PrimaryColumn({ unsigned: true, type: "bigint" }), (0, typeorm_1.PrimaryColumn)({ unsigned: true, type: global.PrimaryKeyType || 'bigint' }),
__metadata("design:type", Number) __metadata("design:type", Number)
], CloudReplay.prototype, "id", void 0); ], CloudReplay.prototype, "id", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "text" }), (0, typeorm_1.Column)({ type: "text" }),
__metadata("design:type", String) __metadata("design:type", String)
], CloudReplay.prototype, "data", void 0); ], CloudReplay.prototype, "data", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column({ type: "datetime" }), (0, typeorm_1.Column)({ type: "datetime" }),
__metadata("design:type", Date) __metadata("design:type", Date)
], CloudReplay.prototype, "date", void 0); ], CloudReplay.prototype, "date", void 0);
__decorate([ __decorate([
typeorm_1.OneToMany(() => CloudReplayPlayer_1.CloudReplayPlayer, player => player.cloudReplay), (0, typeorm_1.OneToMany)(() => CloudReplayPlayer_1.CloudReplayPlayer, player => player.cloudReplay),
__metadata("design:type", Array) __metadata("design:type", Array)
], CloudReplay.prototype, "players", void 0); ], CloudReplay.prototype, "players", void 0);
CloudReplay = __decorate([ CloudReplay = __decorate([
typeorm_1.Entity({ (0, typeorm_1.Entity)({
orderBy: { orderBy: {
date: "DESC" date: "DESC"
} }
......
...@@ -10,7 +10,7 @@ import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase"; ...@@ -10,7 +10,7 @@ import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase";
} }
}) })
export class CloudReplay extends CreateAndUpdateTimeBase { export class CloudReplay extends CreateAndUpdateTimeBase {
@PrimaryColumn({ unsigned: true, type: "bigint" }) @PrimaryColumn({ unsigned: true, type: (global as any).PrimaryKeyType as ('bigint' | 'integer') || 'bigint' })
id: number; id: number;
@Column({ type: "text" }) @Column({ type: "text" })
......
...@@ -15,6 +15,8 @@ const typeorm_1 = require("typeorm"); ...@@ -15,6 +15,8 @@ const typeorm_1 = require("typeorm");
const CloudReplay_1 = require("./CloudReplay"); const CloudReplay_1 = require("./CloudReplay");
const BasePlayer_1 = require("./BasePlayer"); const BasePlayer_1 = require("./BasePlayer");
let CloudReplayPlayer = CloudReplayPlayer_1 = class CloudReplayPlayer extends BasePlayer_1.BasePlayer { let CloudReplayPlayer = CloudReplayPlayer_1 = class CloudReplayPlayer extends BasePlayer_1.BasePlayer {
key;
cloudReplay;
static fromPlayerInfo(info) { static fromPlayerInfo(info) {
const p = new CloudReplayPlayer_1(); const p = new CloudReplayPlayer_1();
p.key = info.key; p.key = info.key;
...@@ -24,16 +26,16 @@ let CloudReplayPlayer = CloudReplayPlayer_1 = class CloudReplayPlayer extends Ba ...@@ -24,16 +26,16 @@ let CloudReplayPlayer = CloudReplayPlayer_1 = class CloudReplayPlayer extends Ba
} }
}; };
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column({ type: "varchar", length: 128 }), (0, typeorm_1.Column)({ type: "varchar", length: 128 }),
__metadata("design:type", String) __metadata("design:type", String)
], CloudReplayPlayer.prototype, "key", void 0); ], CloudReplayPlayer.prototype, "key", void 0);
__decorate([ __decorate([
typeorm_1.ManyToOne(() => CloudReplay_1.CloudReplay, replay => replay.players), (0, typeorm_1.ManyToOne)(() => CloudReplay_1.CloudReplay, replay => replay.players),
__metadata("design:type", CloudReplay_1.CloudReplay) __metadata("design:type", CloudReplay_1.CloudReplay)
], CloudReplayPlayer.prototype, "cloudReplay", void 0); ], CloudReplayPlayer.prototype, "cloudReplay", void 0);
CloudReplayPlayer = CloudReplayPlayer_1 = __decorate([ CloudReplayPlayer = CloudReplayPlayer_1 = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], CloudReplayPlayer); ], CloudReplayPlayer);
exports.CloudReplayPlayer = CloudReplayPlayer; exports.CloudReplayPlayer = CloudReplayPlayer;
//# sourceMappingURL=CloudReplayPlayer.js.map //# sourceMappingURL=CloudReplayPlayer.js.map
\ No newline at end of file
...@@ -12,13 +12,15 @@ Object.defineProperty(exports, "__esModule", { value: true }); ...@@ -12,13 +12,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateAndUpdateTimeBase = void 0; exports.CreateAndUpdateTimeBase = void 0;
const typeorm_1 = require("typeorm"); const typeorm_1 = require("typeorm");
class CreateAndUpdateTimeBase { class CreateAndUpdateTimeBase {
createTime;
updateTime;
} }
__decorate([ __decorate([
typeorm_1.CreateDateColumn(), (0, typeorm_1.CreateDateColumn)(),
__metadata("design:type", Date) __metadata("design:type", Date)
], CreateAndUpdateTimeBase.prototype, "createTime", void 0); ], CreateAndUpdateTimeBase.prototype, "createTime", void 0);
__decorate([ __decorate([
typeorm_1.UpdateDateColumn(), (0, typeorm_1.UpdateDateColumn)(),
__metadata("design:type", Date) __metadata("design:type", Date)
], CreateAndUpdateTimeBase.prototype, "updateTime", void 0); ], CreateAndUpdateTimeBase.prototype, "updateTime", void 0);
exports.CreateAndUpdateTimeBase = CreateAndUpdateTimeBase; exports.CreateAndUpdateTimeBase = CreateAndUpdateTimeBase;
......
...@@ -19,16 +19,25 @@ const moment_1 = __importDefault(require("moment")); ...@@ -19,16 +19,25 @@ const moment_1 = __importDefault(require("moment"));
const underscore_1 = __importDefault(require("underscore")); const underscore_1 = __importDefault(require("underscore"));
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let DuelLog = class DuelLog extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let DuelLog = class DuelLog extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
id;
time;
name;
roomId;
cloudReplayId; // not very needed to become a relation
replayFileName;
roomMode;
duelCount;
players;
getViewString() { getViewString() {
const viewPlayers = underscore_1.default.clone(this.players); const viewPlayers = underscore_1.default.clone(this.players);
viewPlayers.sort((p1, p2) => p1.pos - p2.pos); viewPlayers.sort((p1, p2) => p1.pos - p2.pos);
const playerString = viewPlayers[0].realName.split("$")[0] + (viewPlayers[2] ? "+" + viewPlayers[2].realName.split("$")[0] : "") + " VS " + (viewPlayers[1] ? viewPlayers[1].realName.split("$")[0] : "AI") + (viewPlayers[3] ? "+" + viewPlayers[3].realName.split("$")[0] : ""); const playerString = viewPlayers[0].realName.split("$")[0] + (viewPlayers[2] ? "+" + viewPlayers[2].realName.split("$")[0] : "") + " VS " + (viewPlayers[1] ? viewPlayers[1].realName.split("$")[0] : "AI") + (viewPlayers[3] ? "+" + viewPlayers[3].realName.split("$")[0] : "");
return `<${this.id}> ${playerString} ${moment_1.default(this.time).format("YYYY-MM-DD HH-mm-ss")}`; return `<${this.id}> ${playerString} ${(0, moment_1.default)(this.time).format("YYYY-MM-DD HH-mm-ss")}`;
} }
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: (0, 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,
...@@ -47,46 +56,46 @@ let DuelLog = class DuelLog extends CreateAndUpdateTimeBase_1.CreateAndUpdateTim ...@@ -47,46 +56,46 @@ let DuelLog = class DuelLog extends CreateAndUpdateTimeBase_1.CreateAndUpdateTim
} }
}; };
__decorate([ __decorate([
typeorm_1.PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }), (0, typeorm_1.PrimaryGeneratedColumn)({ unsigned: true, type: global.PrimaryKeyType || 'bigint' }),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLog.prototype, "id", void 0); ], DuelLog.prototype, "id", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("datetime"), (0, typeorm_1.Column)("datetime"),
__metadata("design:type", Date) __metadata("design:type", Date)
], DuelLog.prototype, "time", void 0); ], DuelLog.prototype, "time", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column({ type: "varchar", length: 20 }), (0, typeorm_1.Column)({ type: "varchar", length: 20 }),
__metadata("design:type", String) __metadata("design:type", String)
], DuelLog.prototype, "name", void 0); ], DuelLog.prototype, "name", void 0);
__decorate([ __decorate([
typeorm_1.Column("int"), (0, typeorm_1.Column)("int"),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLog.prototype, "roomId", void 0); ], DuelLog.prototype, "roomId", void 0);
__decorate([ __decorate([
typeorm_1.Column("bigint"), (0, typeorm_1.Column)(global.PrimaryKeyType || 'bigint'),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLog.prototype, "cloudReplayId", void 0); ], DuelLog.prototype, "cloudReplayId", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "varchar", length: 256 }), (0, typeorm_1.Column)({ type: "varchar", length: 256 }),
__metadata("design:type", String) __metadata("design:type", String)
], DuelLog.prototype, "replayFileName", void 0); ], DuelLog.prototype, "replayFileName", void 0);
__decorate([ __decorate([
typeorm_1.Column("tinyint", { unsigned: true }), (0, typeorm_1.Column)("tinyint", { unsigned: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLog.prototype, "roomMode", void 0); ], DuelLog.prototype, "roomMode", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("tinyint", { unsigned: true }), (0, typeorm_1.Column)("tinyint", { unsigned: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLog.prototype, "duelCount", void 0); ], DuelLog.prototype, "duelCount", void 0);
__decorate([ __decorate([
typeorm_1.OneToMany(() => DuelLogPlayer_1.DuelLogPlayer, player => player.duelLog), (0, typeorm_1.OneToMany)(() => DuelLogPlayer_1.DuelLogPlayer, player => player.duelLog),
__metadata("design:type", Array) __metadata("design:type", Array)
], DuelLog.prototype, "players", void 0); ], DuelLog.prototype, "players", void 0);
DuelLog = __decorate([ DuelLog = __decorate([
typeorm_1.Entity({ (0, typeorm_1.Entity)({
orderBy: { orderBy: {
id: "DESC" id: "DESC"
} }
......
...@@ -10,7 +10,7 @@ import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase"; ...@@ -10,7 +10,7 @@ import {CreateAndUpdateTimeBase} from "./CreateAndUpdateTimeBase";
} }
}) })
export class DuelLog extends CreateAndUpdateTimeBase { export class DuelLog extends CreateAndUpdateTimeBase {
@PrimaryGeneratedColumn({unsigned: true, type: "bigint"}) @PrimaryGeneratedColumn({unsigned: true, type: (global as any).PrimaryKeyType as ('bigint' | 'integer') || 'bigint'})
id: number; id: number;
@Index() @Index()
...@@ -24,7 +24,7 @@ export class DuelLog extends CreateAndUpdateTimeBase { ...@@ -24,7 +24,7 @@ export class DuelLog extends CreateAndUpdateTimeBase {
@Column("int") @Column("int")
roomId: number; roomId: number;
@Column("bigint") @Column((global as any).PrimaryKeyType as ('bigint' | 'integer') || 'bigint')
cloudReplayId: number; // not very needed to become a relation cloudReplayId: number; // not very needed to become a relation
@Column({type: "varchar", length: 256}) @Column({type: "varchar", length: 256})
...@@ -67,4 +67,4 @@ export class DuelLog extends CreateAndUpdateTimeBase { ...@@ -67,4 +67,4 @@ export class DuelLog extends CreateAndUpdateTimeBase {
} }
return data; return data;
} }
} }
\ No newline at end of file
...@@ -16,26 +16,36 @@ const BasePlayer_1 = require("./BasePlayer"); ...@@ -16,26 +16,36 @@ const BasePlayer_1 = require("./BasePlayer");
const DuelLog_1 = require("./DuelLog"); const DuelLog_1 = require("./DuelLog");
const DeckEncoder_1 = require("../DeckEncoder"); const DeckEncoder_1 = require("../DeckEncoder");
let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.BasePlayer { let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.BasePlayer {
realName;
ip;
isFirst;
score;
lp;
cardCount;
startDeckBuffer;
currentDeckBuffer;
winner;
setStartDeck(deck) { setStartDeck(deck) {
if (deck === null) { if (deck === null) {
this.startDeckBuffer = null; this.startDeckBuffer = null;
return; return;
} }
this.startDeckBuffer = DeckEncoder_1.encodeDeck(deck).toString("base64"); this.startDeckBuffer = (0, DeckEncoder_1.encodeDeck)(deck).toString("base64");
} }
getStartDeck() { getStartDeck() {
return DeckEncoder_1.decodeDeck(Buffer.from(this.startDeckBuffer, "base64")); return (0, DeckEncoder_1.decodeDeck)(Buffer.from(this.startDeckBuffer, "base64"));
} }
setCurrentDeck(deck) { setCurrentDeck(deck) {
if (deck === null) { if (deck === null) {
this.currentDeckBuffer = null; this.currentDeckBuffer = null;
return; return;
} }
this.currentDeckBuffer = DeckEncoder_1.encodeDeck(deck).toString("base64"); this.currentDeckBuffer = (0, DeckEncoder_1.encodeDeck)(deck).toString("base64");
} }
getCurrentDeck() { getCurrentDeck() {
return DeckEncoder_1.decodeDeck(Buffer.from(this.currentDeckBuffer, "base64")); return (0, DeckEncoder_1.decodeDeck)(Buffer.from(this.currentDeckBuffer, "base64"));
} }
duelLog;
static fromDuelLogPlayerInfo(info) { static fromDuelLogPlayerInfo(info) {
const p = new DuelLogPlayer_1(); const p = new DuelLogPlayer_1();
p.name = info.name; p.name = info.name;
...@@ -47,55 +57,55 @@ let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.B ...@@ -47,55 +57,55 @@ let DuelLogPlayer = DuelLogPlayer_1 = class DuelLogPlayer extends BasePlayer_1.B
p.cardCount = info.cardCount; p.cardCount = info.cardCount;
p.isFirst = info.isFirst ? 1 : 0; p.isFirst = info.isFirst ? 1 : 0;
p.winner = info.winner ? 1 : 0; p.winner = info.winner ? 1 : 0;
p.startDeckBuffer = info.startDeckBuffer.toString("base64"); p.startDeckBuffer = info.startDeckBuffer?.toString("base64") || null;
p.setCurrentDeck(info.deck); p.setCurrentDeck(info.deck);
return p; return p;
} }
}; };
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column({ type: "varchar", length: 20 }), (0, typeorm_1.Column)({ type: "varchar", length: 20 }),
__metadata("design:type", String) __metadata("design:type", String)
], DuelLogPlayer.prototype, "realName", void 0); ], DuelLogPlayer.prototype, "realName", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "varchar", length: 64, nullable: true }), (0, typeorm_1.Column)({ type: "varchar", length: 64, nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], DuelLogPlayer.prototype, "ip", void 0); ], DuelLogPlayer.prototype, "ip", void 0);
__decorate([ __decorate([
typeorm_1.Column("tinyint", { unsigned: true }), (0, typeorm_1.Column)("tinyint", { unsigned: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLogPlayer.prototype, "isFirst", void 0); ], DuelLogPlayer.prototype, "isFirst", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("tinyint"), (0, typeorm_1.Column)("tinyint"),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLogPlayer.prototype, "score", void 0); ], DuelLogPlayer.prototype, "score", void 0);
__decorate([ __decorate([
typeorm_1.Column("int", { nullable: true }), (0, typeorm_1.Column)("int", { nullable: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLogPlayer.prototype, "lp", void 0); ], DuelLogPlayer.prototype, "lp", void 0);
__decorate([ __decorate([
typeorm_1.Column("smallint", { nullable: true }), (0, typeorm_1.Column)("smallint", { nullable: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLogPlayer.prototype, "cardCount", void 0); ], DuelLogPlayer.prototype, "cardCount", void 0);
__decorate([ __decorate([
typeorm_1.Column("text", { nullable: true }), (0, typeorm_1.Column)("text", { nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], DuelLogPlayer.prototype, "startDeckBuffer", void 0); ], DuelLogPlayer.prototype, "startDeckBuffer", void 0);
__decorate([ __decorate([
typeorm_1.Column("text", { nullable: true }), (0, typeorm_1.Column)("text", { nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], DuelLogPlayer.prototype, "currentDeckBuffer", void 0); ], DuelLogPlayer.prototype, "currentDeckBuffer", void 0);
__decorate([ __decorate([
typeorm_1.Column("tinyint"), (0, typeorm_1.Column)("tinyint"),
__metadata("design:type", Number) __metadata("design:type", Number)
], DuelLogPlayer.prototype, "winner", void 0); ], DuelLogPlayer.prototype, "winner", void 0);
__decorate([ __decorate([
typeorm_1.ManyToOne(() => DuelLog_1.DuelLog, duelLog => duelLog.players), (0, typeorm_1.ManyToOne)(() => DuelLog_1.DuelLog, duelLog => duelLog.players),
__metadata("design:type", DuelLog_1.DuelLog) __metadata("design:type", DuelLog_1.DuelLog)
], DuelLogPlayer.prototype, "duelLog", void 0); ], DuelLogPlayer.prototype, "duelLog", void 0);
DuelLogPlayer = DuelLogPlayer_1 = __decorate([ DuelLogPlayer = DuelLogPlayer_1 = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], DuelLogPlayer); ], DuelLogPlayer);
exports.DuelLogPlayer = DuelLogPlayer; exports.DuelLogPlayer = DuelLogPlayer;
//# sourceMappingURL=DuelLogPlayer.js.map //# sourceMappingURL=DuelLogPlayer.js.map
\ No newline at end of file
...@@ -73,7 +73,7 @@ export class DuelLogPlayer extends BasePlayer { ...@@ -73,7 +73,7 @@ export class DuelLogPlayer extends BasePlayer {
p.cardCount = info.cardCount; p.cardCount = info.cardCount;
p.isFirst = info.isFirst ? 1 : 0; p.isFirst = info.isFirst ? 1 : 0;
p.winner = info.winner ? 1 : 0; p.winner = info.winner ? 1 : 0;
p.startDeckBuffer = info.startDeckBuffer.toString("base64"); p.startDeckBuffer = info.startDeckBuffer?.toString("base64") || null;
p.setCurrentDeck(info.deck); p.setCurrentDeck(info.deck);
return p; return p;
} }
......
...@@ -13,6 +13,11 @@ exports.RandomDuelBan = void 0; ...@@ -13,6 +13,11 @@ exports.RandomDuelBan = void 0;
const typeorm_1 = require("typeorm"); const typeorm_1 = require("typeorm");
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let RandomDuelBan = class RandomDuelBan extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let RandomDuelBan = class RandomDuelBan extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
ip;
time;
count;
reasons;
needTip;
setNeedTip(need) { setNeedTip(need) {
this.needTip = need ? 1 : 0; this.needTip = need ? 1 : 0;
} }
...@@ -21,27 +26,27 @@ let RandomDuelBan = class RandomDuelBan extends CreateAndUpdateTimeBase_1.Create ...@@ -21,27 +26,27 @@ let RandomDuelBan = class RandomDuelBan extends CreateAndUpdateTimeBase_1.Create
} }
}; };
__decorate([ __decorate([
typeorm_1.PrimaryColumn({ type: "varchar", length: 64 }), (0, typeorm_1.PrimaryColumn)({ type: "varchar", length: 64 }),
__metadata("design:type", String) __metadata("design:type", String)
], RandomDuelBan.prototype, "ip", void 0); ], RandomDuelBan.prototype, "ip", void 0);
__decorate([ __decorate([
typeorm_1.Column("datetime"), (0, typeorm_1.Column)("datetime"),
__metadata("design:type", Date) __metadata("design:type", Date)
], RandomDuelBan.prototype, "time", void 0); ], RandomDuelBan.prototype, "time", void 0);
__decorate([ __decorate([
typeorm_1.Column("smallint"), (0, typeorm_1.Column)("smallint"),
__metadata("design:type", Number) __metadata("design:type", Number)
], RandomDuelBan.prototype, "count", void 0); ], RandomDuelBan.prototype, "count", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "simple-array" }), (0, typeorm_1.Column)({ type: "simple-array" }),
__metadata("design:type", Array) __metadata("design:type", Array)
], RandomDuelBan.prototype, "reasons", void 0); ], RandomDuelBan.prototype, "reasons", void 0);
__decorate([ __decorate([
typeorm_1.Column({ type: "tinyint", unsigned: true }), (0, typeorm_1.Column)({ type: "tinyint", unsigned: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], RandomDuelBan.prototype, "needTip", void 0); ], RandomDuelBan.prototype, "needTip", void 0);
RandomDuelBan = __decorate([ RandomDuelBan = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], RandomDuelBan); ], RandomDuelBan);
exports.RandomDuelBan = RandomDuelBan; exports.RandomDuelBan = RandomDuelBan;
//# sourceMappingURL=RandomDuelBan.js.map //# sourceMappingURL=RandomDuelBan.js.map
\ No newline at end of file
...@@ -13,6 +13,11 @@ exports.RandomDuelScore = void 0; ...@@ -13,6 +13,11 @@ exports.RandomDuelScore = void 0;
const typeorm_1 = require("typeorm"); const typeorm_1 = require("typeorm");
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let RandomDuelScore = class RandomDuelScore extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let RandomDuelScore = class RandomDuelScore extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
name;
winCount;
loseCount;
fleeCount;
winCombo;
getDisplayName() { getDisplayName() {
return this.name.split("$")[0]; return this.name.split("$")[0];
} }
...@@ -44,30 +49,30 @@ let RandomDuelScore = class RandomDuelScore extends CreateAndUpdateTimeBase_1.Cr ...@@ -44,30 +49,30 @@ let RandomDuelScore = class RandomDuelScore extends CreateAndUpdateTimeBase_1.Cr
} }
}; };
__decorate([ __decorate([
typeorm_1.PrimaryColumn({ type: "varchar", length: 20 }), (0, typeorm_1.PrimaryColumn)({ type: "varchar", length: 20 }),
__metadata("design:type", String) __metadata("design:type", String)
], RandomDuelScore.prototype, "name", void 0); ], RandomDuelScore.prototype, "name", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("int", { unsigned: true, default: 0 }), (0, typeorm_1.Column)("int", { unsigned: true, default: 0 }),
__metadata("design:type", Number) __metadata("design:type", Number)
], RandomDuelScore.prototype, "winCount", void 0); ], RandomDuelScore.prototype, "winCount", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("int", { unsigned: true, default: 0 }), (0, typeorm_1.Column)("int", { unsigned: true, default: 0 }),
__metadata("design:type", Number) __metadata("design:type", Number)
], RandomDuelScore.prototype, "loseCount", void 0); ], RandomDuelScore.prototype, "loseCount", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("int", { unsigned: true, default: 0 }), (0, typeorm_1.Column)("int", { unsigned: true, default: 0 }),
__metadata("design:type", Number) __metadata("design:type", Number)
], RandomDuelScore.prototype, "fleeCount", void 0); ], RandomDuelScore.prototype, "fleeCount", void 0);
__decorate([ __decorate([
typeorm_1.Column("int", { unsigned: true, default: 0 }), (0, typeorm_1.Column)("int", { unsigned: true, default: 0 }),
__metadata("design:type", Number) __metadata("design:type", Number)
], RandomDuelScore.prototype, "winCombo", void 0); ], RandomDuelScore.prototype, "winCombo", void 0);
RandomDuelScore = __decorate([ RandomDuelScore = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], RandomDuelScore); ], RandomDuelScore);
exports.RandomDuelScore = RandomDuelScore; exports.RandomDuelScore = RandomDuelScore;
//# sourceMappingURL=RandomDuelScore.js.map //# sourceMappingURL=RandomDuelScore.js.map
\ No newline at end of file
...@@ -19,41 +19,48 @@ const VipKey_1 = require("./VipKey"); ...@@ -19,41 +19,48 @@ const VipKey_1 = require("./VipKey");
const moment_1 = __importDefault(require("moment")); const moment_1 = __importDefault(require("moment"));
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let User = class User extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let User = class User extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
key;
chatColor;
vipExpireDate;
isVip() { isVip() {
return this.vipExpireDate && moment_1.default().isBefore(this.vipExpireDate); return this.vipExpireDate && (0, moment_1.default)().isBefore(this.vipExpireDate);
} }
victory;
words;
dialogues;
usedKeys;
}; };
__decorate([ __decorate([
typeorm_1.PrimaryColumn({ type: "varchar", length: 128 }), (0, typeorm_1.PrimaryColumn)({ type: "varchar", length: 128 }),
__metadata("design:type", String) __metadata("design:type", String)
], User.prototype, "key", void 0); ], User.prototype, "key", void 0);
__decorate([ __decorate([
typeorm_1.Column("varchar", { length: 16, nullable: true }), (0, typeorm_1.Column)("varchar", { length: 16, nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], User.prototype, "chatColor", void 0); ], User.prototype, "chatColor", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("datetime", { nullable: true }), (0, typeorm_1.Column)("datetime", { nullable: true }),
__metadata("design:type", Date) __metadata("design:type", Date)
], User.prototype, "vipExpireDate", void 0); ], User.prototype, "vipExpireDate", void 0);
__decorate([ __decorate([
typeorm_1.Column("text", { nullable: true }), (0, typeorm_1.Column)("text", { nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], User.prototype, "victory", void 0); ], User.prototype, "victory", void 0);
__decorate([ __decorate([
typeorm_1.Column("text", { nullable: true }), (0, typeorm_1.Column)("text", { nullable: true }),
__metadata("design:type", String) __metadata("design:type", String)
], User.prototype, "words", void 0); ], User.prototype, "words", void 0);
__decorate([ __decorate([
typeorm_1.OneToMany(() => UserDialog_1.UserDialog, dialog => dialog.user), (0, typeorm_1.OneToMany)(() => UserDialog_1.UserDialog, dialog => dialog.user),
__metadata("design:type", Array) __metadata("design:type", Array)
], User.prototype, "dialogues", void 0); ], User.prototype, "dialogues", void 0);
__decorate([ __decorate([
typeorm_1.OneToMany(() => VipKey_1.VipKey, vipKey => vipKey.usedBy), (0, typeorm_1.OneToMany)(() => VipKey_1.VipKey, vipKey => vipKey.usedBy),
__metadata("design:type", Array) __metadata("design:type", Array)
], User.prototype, "usedKeys", void 0); ], User.prototype, "usedKeys", void 0);
User = __decorate([ User = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], User); ], User);
exports.User = User; exports.User = User;
//# sourceMappingURL=User.js.map //# sourceMappingURL=User.js.map
\ No newline at end of file
...@@ -13,26 +13,30 @@ exports.UserDialog = void 0; ...@@ -13,26 +13,30 @@ exports.UserDialog = void 0;
const typeorm_1 = require("typeorm"); const typeorm_1 = require("typeorm");
const User_1 = require("./User"); const User_1 = require("./User");
let UserDialog = class UserDialog { let UserDialog = class UserDialog {
id;
cardCode;
text;
user;
}; };
__decorate([ __decorate([
typeorm_1.PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }), (0, typeorm_1.PrimaryGeneratedColumn)({ unsigned: true, type: "bigint" }),
__metadata("design:type", Number) __metadata("design:type", Number)
], UserDialog.prototype, "id", void 0); ], UserDialog.prototype, "id", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("int", { unsigned: true }), (0, typeorm_1.Column)("int", { unsigned: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], UserDialog.prototype, "cardCode", void 0); ], UserDialog.prototype, "cardCode", void 0);
__decorate([ __decorate([
typeorm_1.Column("text"), (0, typeorm_1.Column)("text"),
__metadata("design:type", String) __metadata("design:type", String)
], UserDialog.prototype, "text", void 0); ], UserDialog.prototype, "text", void 0);
__decorate([ __decorate([
typeorm_1.ManyToOne(() => User_1.User, user => user.dialogues), (0, typeorm_1.ManyToOne)(() => User_1.User, user => user.dialogues),
__metadata("design:type", User_1.User) __metadata("design:type", User_1.User)
], UserDialog.prototype, "user", void 0); ], UserDialog.prototype, "user", void 0);
UserDialog = __decorate([ UserDialog = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], UserDialog); ], UserDialog);
exports.UserDialog = UserDialog; exports.UserDialog = UserDialog;
//# sourceMappingURL=UserDialog.js.map //# sourceMappingURL=UserDialog.js.map
\ No newline at end of file
...@@ -14,34 +14,39 @@ const typeorm_1 = require("typeorm"); ...@@ -14,34 +14,39 @@ const typeorm_1 = require("typeorm");
const User_1 = require("./User"); const User_1 = require("./User");
const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase"); const CreateAndUpdateTimeBase_1 = require("./CreateAndUpdateTimeBase");
let VipKey = class VipKey extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase { let VipKey = class VipKey extends CreateAndUpdateTimeBase_1.CreateAndUpdateTimeBase {
id;
key;
type;
isUsed;
usedBy;
toJSON() { toJSON() {
return { key: this.key, type: this.type }; return { key: this.key, type: this.type };
} }
}; };
__decorate([ __decorate([
typeorm_1.PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }), (0, typeorm_1.PrimaryGeneratedColumn)({ unsigned: true, type: "bigint" }),
__metadata("design:type", Number) __metadata("design:type", Number)
], VipKey.prototype, "id", void 0); ], VipKey.prototype, "id", void 0);
__decorate([ __decorate([
typeorm_1.Index({ unique: true }), (0, typeorm_1.Index)({ unique: true }),
typeorm_1.Column("varchar", { length: 30 }), (0, typeorm_1.Column)("varchar", { length: 30 }),
__metadata("design:type", String) __metadata("design:type", String)
], VipKey.prototype, "key", void 0); ], VipKey.prototype, "key", void 0);
__decorate([ __decorate([
typeorm_1.Column("int", { unsigned: true }), (0, typeorm_1.Column)("int", { unsigned: true }),
__metadata("design:type", Number) __metadata("design:type", Number)
], VipKey.prototype, "type", void 0); ], VipKey.prototype, "type", void 0);
__decorate([ __decorate([
typeorm_1.Index(), (0, typeorm_1.Index)(),
typeorm_1.Column("tinyint", { unsigned: true, default: 0 }), (0, typeorm_1.Column)("tinyint", { unsigned: true, default: 0 }),
__metadata("design:type", Number) __metadata("design:type", Number)
], VipKey.prototype, "isUsed", void 0); ], VipKey.prototype, "isUsed", void 0);
__decorate([ __decorate([
typeorm_1.ManyToOne(() => User_1.User, user => user.usedKeys), (0, typeorm_1.ManyToOne)(() => User_1.User, user => user.usedKeys),
__metadata("design:type", User_1.User) __metadata("design:type", User_1.User)
], VipKey.prototype, "usedBy", void 0); ], VipKey.prototype, "usedBy", void 0);
VipKey = __decorate([ VipKey = __decorate([
typeorm_1.Entity() (0, typeorm_1.Entity)()
], VipKey); ], VipKey);
exports.VipKey = VipKey; exports.VipKey = VipKey;
//# sourceMappingURL=VipKey.js.map //# sourceMappingURL=VipKey.js.map
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
"lflist": 0, "lflist": 0,
"rule": 0, "rule": 0,
"mode": 0, "mode": 0,
"comment": "rule: 0=OCGONLY, 1=TCGONLY, 2=OT; mode: 0=SINGLE, 1=MATCH, 2=TAG", "comment": "rule: 0=OCG-ONLY, 1=TCG-ONLY, 2=SC-ONLY, 3=CUSTOM-ONLY, 4=NO-UNIQUE, 5=ALL; mode: 0=SINGLE, 1=MATCH, 2=TAG",
"duel_rule": 5, "duel_rule": 5,
"no_check_deck": false, "no_check_deck": false,
"no_shuffle_deck": false, "no_shuffle_deck": false,
...@@ -66,12 +66,14 @@ ...@@ -66,12 +66,14 @@
"tips": { "tips": {
"enabled": true, "enabled": true,
"split_zh": false, "split_zh": false,
"get": "https://api.moecube.com/biu-tips/tips.json", "get": "https://sapi.moecube.com:444/biu-tips/tips.json",
"get_zh": false "get_zh": false,
"interval": 30000,
"interval_ingame": 120000
}, },
"dialogues": { "dialogues": {
"enabled": true, "enabled": true,
"get_custom": "http://purerosefallen.github.io/ygopro-tips/dialogues-222.json", "get_custom": "https://minio.momobako.com:9000/public/ygopro-tips/dialogues-222.json",
"get": "http://mercury233.me/ygosrv233/dialogues.json" "get": "http://mercury233.me/ygosrv233/dialogues.json"
}, },
"words": { "words": {
...@@ -160,6 +162,7 @@ ...@@ -160,6 +162,7 @@
"post_detailed_score": true, "post_detailed_score": true,
"post_score_midduel": true, "post_score_midduel": true,
"cache_ttl": 60000, "cache_ttl": 60000,
"no_match_mode": false,
"options": { "options": {
"apiKey": "123" "apiKey": "123"
}, },
...@@ -217,6 +220,7 @@ ...@@ -217,6 +220,7 @@
"source": "mycard-athletic" "source": "mycard-athletic"
}, },
"rankCount": 10, "rankCount": 10,
"banCount": 0,
"ttl": 600 "ttl": 600
}, },
"test_mode": { "test_mode": {
......
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
"kick_count_down_arena_part2": " will be evicted for not getting ready or starting the game.", "kick_count_down_arena_part2": " will be evicted for not getting ready or starting the game.",
"chat_order_main": "Mycard YGOPro Server function list", "chat_order_main": "Mycard YGOPro Server function list",
"chat_order_help": "/help show this list", "chat_order_help": "/help show this list",
"chat_order_refresh": "/refresh refresh field when stuck",
"chat_order_roomname": "/roomname show room name", "chat_order_roomname": "/roomname show room name",
"chat_order_windbot": "/ai to add an AI, /ai name to add selected AI ", "chat_order_windbot": "/ai to add an AI, /ai name to add selected AI ",
"chat_order_tip": "/tip show a tip", "chat_order_tip": "/tip show a tip",
...@@ -203,6 +204,10 @@ ...@@ -203,6 +204,10 @@
"auto_death_part2": " minutes.", "auto_death_part2": " minutes.",
"athletic_arena_tip": "During an athletic match, a game quit behavior is regarded as a surrender.", "athletic_arena_tip": "During an athletic match, a game quit behavior is regarded as a surrender.",
"windbot_disable_random_room": "By adding the AI, this random game won't get any new player unless they enter the room name:", "windbot_disable_random_room": "By adding the AI, this random game won't get any new player unless they enter the room name:",
"refresh_success": "Refresh field succeeded.",
"refresh_failed": "Refresh field failed.",
"banned_athletic_deck_part1": "Entertainment Mode does not allow top ",
"banned_athletic_deck_part2": " popular meta decks. Please change your deck.",
"using_athletic_deck": " is using a competitive deck." "using_athletic_deck": " is using a competitive deck."
}, },
"es-es": { "es-es": {
...@@ -437,6 +442,7 @@ ...@@ -437,6 +442,7 @@
"kick_count_down_arena_part2": "若不准备或开始游戏将视为投降", "kick_count_down_arena_part2": "若不准备或开始游戏将视为投降",
"chat_order_main": "Mycard YGOPro Server 指令帮助", "chat_order_main": "Mycard YGOPro Server 指令帮助",
"chat_order_help": "/help 显示这个帮助信息", "chat_order_help": "/help 显示这个帮助信息",
"chat_order_refresh": "/refresh 刷新场面信息,卡顿时用",
"chat_order_roomname": "/roomname 显示当前房间的名字", "chat_order_roomname": "/roomname 显示当前房间的名字",
"chat_order_windbot": "/ai 添加一个AI,/ai 角色名 可指定添加的角色", "chat_order_windbot": "/ai 添加一个AI,/ai 角色名 可指定添加的角色",
"chat_order_tip": "/tip 显示一条提示", "chat_order_tip": "/tip 显示一条提示",
...@@ -555,6 +561,10 @@ ...@@ -555,6 +561,10 @@
"auto_death_part2": "分钟后,将自动进入加时赛。", "auto_death_part2": "分钟后,将自动进入加时赛。",
"athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。", "athletic_arena_tip": "在竞技匹配中,比赛开始前退出游戏也会视为投降。",
"windbot_disable_random_room": "因为添加了AI,本随机对战房间将只能通过房间名加入:", "windbot_disable_random_room": "因为添加了AI,本随机对战房间将只能通过房间名加入:",
"refresh_success": "刷新场面成功。",
"refresh_fail": "刷新场面失败。",
"banned_athletic_deck_part1": "娱乐匹配中禁止使用使用数前",
"banned_athletic_deck_part2": "的竞技卡组。请更换卡组。",
"using_athletic_deck": " 正在使用竞技卡组。" "using_athletic_deck": " 正在使用竞技卡组。"
}, },
"ko-kr": { "ko-kr": {
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
"apps": [ "apps": [
{ {
"name": "ygopro-server", "name": "ygopro-server",
"script": "/ygopro-server/ygopro-server.js", "script": "npm",
"cwd": "/ygopro-server" "cwd": "/ygopro-server",
"args": "start"
}, },
{ {
"name": "windbot", "name": "windbot",
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -11,19 +11,15 @@ ...@@ -11,19 +11,15 @@
], ],
"author": "zh99998 <zh99998@gmail.com>, mercury233 <me@mercury233.me>, Nanahira <78877@qq.com>", "author": "zh99998 <zh99998@gmail.com>, mercury233 <me@mercury233.me>, Nanahira <78877@qq.com>",
"dependencies": { "dependencies": {
"@types/bunyan": "^1.8.6",
"@types/node": "^14.0.13",
"@types/underscore": "^1.10.24",
"async": "^3.2.0", "async": "^3.2.0",
"axios": "^0.19.2", "axios": "^0.19.2",
"bunyan": "^1.8.14", "bunyan": "^1.8.14",
"challonge": "latest", "challonge": "^2.2.0",
"coffeescript": "^2.5.1", "deepmerge": "^4.2.2",
"deepmerge": "latest", "formidable": "^2.0.1",
"formidable": "latest", "geoip-country-lite": "^1.0.0",
"geoip-country-lite": "latest",
"jszip": "^3.5.0", "jszip": "^3.5.0",
"load-json-file": "latest", "load-json-file": "^6.2.0",
"lzma": "^2.3.2", "lzma": "^2.3.2",
"moment": "^2.29.1", "moment": "^2.29.1",
"mysql": "^2.18.1", "mysql": "^2.18.1",
...@@ -32,21 +28,27 @@ ...@@ -32,21 +28,27 @@
"q": "^1.5.1", "q": "^1.5.1",
"querystring": "^0.2.0", "querystring": "^0.2.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"request": "latest", "request": "^2.88.2",
"sqlite3": "latest", "sqlite3": "^5.0.2",
"typeorm": "^0.2.29", "typeorm": "^0.2.29",
"typescript": "^4.0.5",
"underscore": "^1.11.0", "underscore": "^1.11.0",
"underscore.string": "latest", "underscore.string": "^3.3.6",
"ws": "^1.1.1" "ws": "^1.1.1"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
"build": "coffee -c *.coffee && tsc", "build": "coffee -c *.coffee && tsc",
"start": "node ygopro-server.js", "start": "node ygopro-server.js | bunyan",
"tournament": "node ygopro-tournament.js", "tournament": "node ygopro-tournament.js",
"pre": "node ygopro-pre.js", "pre": "node ygopro-pre.js",
"updated": "node ygopro-update.js", "updated": "node ygopro-update.js",
"webhook": "node ygopro-webhook.js" "webhook": "node ygopro-webhook.js"
},
"devDependencies": {
"@types/bunyan": "^1.8.8",
"@types/node": "^17.0.19",
"@types/underscore": "^1.11.4",
"coffeescript": "^2.6.1",
"typescript": "^4.5.5"
} }
} }
This diff is collapsed.
This diff is collapsed.
...@@ -113,4 +113,4 @@ translateHandler = (handler) -> ...@@ -113,4 +113,4 @@ translateHandler = (handler) ->
if client if client
client.system_kicked = true client.system_kicked = true
client.destroy() client.destroy()
return return '_cancel'
...@@ -185,6 +185,7 @@ ...@@ -185,6 +185,7 @@
client.system_kicked = true; client.system_kicked = true;
client.destroy(); client.destroy();
} }
return '_cancel';
}; };
}).call(this); }).call(this);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment