Commit 5442fd83 authored by nanahira's avatar nanahira

Merge branch 'database' into databasen

parents bc7b9de6 529aa459
...@@ -13,6 +13,7 @@ const RandomDuelBan_1 = require("./entities/RandomDuelBan"); ...@@ -13,6 +13,7 @@ const RandomDuelBan_1 = require("./entities/RandomDuelBan");
const underscore_1 = __importDefault(require("underscore")); const underscore_1 = __importDefault(require("underscore"));
const DuelLog_1 = require("./entities/DuelLog"); const DuelLog_1 = require("./entities/DuelLog");
const DuelLogPlayer_1 = require("./entities/DuelLogPlayer"); const DuelLogPlayer_1 = require("./entities/DuelLogPlayer");
const User_1 = require("./entities/User");
class DataManager { class DataManager {
constructor(config, log) { constructor(config, log) {
this.config = config; this.config = config;
...@@ -272,6 +273,71 @@ class DataManager { ...@@ -272,6 +273,71 @@ class DataManager {
} }
}); });
} }
async getUser(key) {
const repo = this.db.getRepository(User_1.User);
try {
const user = await repo.findOne(key);
return user;
}
catch (e) {
this.log.warn(`Failed to fetch user: ${e.toString()}`);
return null;
}
}
async getOrCreateUser(key) {
const user = await this.getUser(key);
if (user) {
return user;
}
const newUser = new User_1.User();
newUser.key = key;
return await this.saveUser(newUser);
}
async saveUser(user) {
const repo = this.db.getRepository(User_1.User);
try {
return await repo.save(user);
}
catch (e) {
this.log.warn(`Failed to save user: ${e.toString()}`);
return null;
}
}
async getUserChatColor(key) {
const user = await this.getUser(key);
return user ? user.chatColor : null;
}
async setUserChatColor(key, color) {
let user = await this.getUser(key);
if (!user) {
user = new User_1.User();
user.key = key;
}
user.chatColor = color;
return await this.saveUser(user);
}
async migrateChatColors(data) {
await this.db.transaction(async (mdb) => {
try {
const users = [];
for (let key in data) {
const chatColor = data[key];
let user = await mdb.findOne(User_1.User, key);
if (!user) {
user = new User_1.User();
user.key = key;
}
user.chatColor = chatColor;
users.push(user);
}
await mdb.save(users);
}
catch (e) {
this.log.warn(`Failed to migrate chat color data: ${e.toString()}`);
return null;
}
});
}
} }
exports.DataManager = DataManager; exports.DataManager = DataManager;
//# sourceMappingURL=DataManager.js.map //# sourceMappingURL=DataManager.js.map
\ No newline at end of file
...@@ -10,6 +10,7 @@ import _ from "underscore"; ...@@ -10,6 +10,7 @@ import _ from "underscore";
import {DuelLog} from "./entities/DuelLog"; import {DuelLog} from "./entities/DuelLog";
import {Deck} from "./DeckEncoder"; import {Deck} from "./DeckEncoder";
import {DuelLogPlayer} from "./entities/DuelLogPlayer"; import {DuelLogPlayer} from "./entities/DuelLogPlayer";
import {User} from "./entities/User";
interface BasePlayerInfo { interface BasePlayerInfo {
name: string; name: string;
...@@ -301,4 +302,68 @@ export class DataManager { ...@@ -301,4 +302,68 @@ export class DataManager {
}); });
} }
async getUser(key: string) {
const repo = this.db.getRepository(User);
try {
const user = await repo.findOne(key);
return user;
} catch (e) {
this.log.warn(`Failed to fetch user: ${e.toString()}`);
return null;
}
}
async getOrCreateUser(key: string) {
const user = await this.getUser(key);
if(user) {
return user;
}
const newUser = new User();
newUser.key = key;
return await this.saveUser(newUser);
}
async saveUser(user: User) {
const repo = this.db.getRepository(User);
try {
return await repo.save(user);
} catch (e) {
this.log.warn(`Failed to save user: ${e.toString()}`);
return null;
}
}
async getUserChatColor(key: string) {
const user = await this.getUser(key);
return user ? user.chatColor : null;
}
async setUserChatColor(key: string, color: string) {
let user = await this.getUser(key);
if(!user) {
user = new User();
user.key = key;
}
user.chatColor = color;
return await this.saveUser(user);
}
async migrateChatColors(data: any) {
await this.db.transaction(async (mdb) => {
try {
const users: User[] = [];
for(let key in data) {
const chatColor: string = data[key];
let user = await mdb.findOne(User, key);
if(!user) {
user = new User();
user.key = key;
}
user.chatColor = chatColor;
users.push(user);
}
await mdb.save(users);
} catch (e) {
this.log.warn(`Failed to migrate chat color data: ${e.toString()}`);
return null;
}
});
}
} }
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.User = void 0;
const typeorm_1 = require("typeorm");
let User = class User {
};
__decorate([
typeorm_1.PrimaryColumn({ type: "varchar", length: 128 }),
__metadata("design:type", String)
], User.prototype, "key", void 0);
__decorate([
typeorm_1.Column("varchar", { length: 16, nullable: true }),
__metadata("design:type", String)
], User.prototype, "chatColor", void 0);
User = __decorate([
typeorm_1.Entity()
], User);
exports.User = User;
//# sourceMappingURL=User.js.map
\ No newline at end of file
import {Column, Entity, PrimaryColumn} from "typeorm";
@Entity()
export class User {
@PrimaryColumn({type: "varchar", length: 128})
key: string;
@Column("varchar", {length: 16, nullable: true})
chatColor: string;
}
...@@ -44,28 +44,6 @@ ...@@ -44,28 +44,6 @@
] ]
} }
}, },
"duel_log": {
"file": "./config/duel_log.json",
"duel_log": []
},
"chat_color": {
"file": "./config/chat_color.json",
"save_list": {}
},
"vip_info": {
"file": "./config/vip_info.json",
"cdkeys": {
"365": [],
"180": [],
"90": [],
"30": [],
"15": [],
"7": [],
"3": [],
"1": []
},
"players": {}
},
"users": { "users": {
"file": "./config/admin_user.json", "file": "./config/admin_user.json",
"permission_examples": { "permission_examples": {
......
...@@ -264,6 +264,7 @@ athleticChecker = null ...@@ -264,6 +264,7 @@ athleticChecker = null
users_cache = {} users_cache = {}
geoip = null geoip = null
dataManager = null dataManager = null
windbots = []
disconnect_list = {} # {old_client, old_server, room_id, timeout, deckbuf} disconnect_list = {} # {old_client, old_server, room_id, timeout, deckbuf}
challonge = null challonge = null
...@@ -383,6 +384,24 @@ init = () -> ...@@ -383,6 +384,24 @@ init = () ->
#finish #finish
if imported if imported
await setting_save(settings) await setting_save(settings)
if settings.modules.mysql.enabled
DataManager = require('./data-manager/DataManager.js').DataManager
dataManager = global.dataManager = new DataManager(settings.modules.mysql.db, log)
await dataManager.init()
else
log.warn("Some functions may be limited without MySQL .")
if settings.modules.cloud_replay.enabled
settings.modules.cloud_replay.enabled = false
await setting_save(settings)
log.warn("Cloud replay cannot be enabled because no MySQL.")
if settings.modules.enable_recover.enabled
settings.modules.enable_recover.enabled = false
await setting_save(settings)
log.warn("Recover mode cannot be enabled because no MySQL.")
if settings.modules.chat_color.enabled
settings.modules.chat_color.enabled = false
await setting_save(settings)
log.warn("Chat color cannot be enabled because no MySQL.")
# 读取数据 # 读取数据
default_data = await loadJSONAsync('./data/default_data.json') default_data = await loadJSONAsync('./data/default_data.json')
try try
...@@ -410,12 +429,14 @@ init = () -> ...@@ -410,12 +429,14 @@ init = () ->
catch catch
badwords = global.badwords = default_data.badwords badwords = global.badwords = default_data.badwords
await setting_save(badwords) await setting_save(badwords)
if settings.modules.chat_color.enabled if settings.modules.chat_color.enabled and await checkFileExists('./config/chat_color.json')
try try
chat_color = global.chat_color = await loadJSONAsync('./config/chat_color.json') chat_color = await loadJSONAsync('./config/chat_color.json')
if chat_color
await dataManager.migrateChatColors(chat_color.save_list);
await fs.promises.unlink('./config/chat_color.json')
log.info("Chat color migrated.")
catch catch
chat_color = global.chat_color = default_data.chat_color
await setting_save(chat_color)
try try
cppversion = parseInt(await fs.promises.readFile('ygopro/gframe/game.cpp', 'utf8').match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16') cppversion = parseInt(await fs.promises.readFile('ygopro/gframe/game.cpp', 'utf8').match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16')
await setting_change(settings, "version", cppversion) await setting_change(settings, "version", cppversion)
...@@ -428,7 +449,7 @@ init = () -> ...@@ -428,7 +449,7 @@ init = () ->
await loadLFList('ygopro/lflist.conf') await loadLFList('ygopro/lflist.conf')
if settings.modules.windbot.enabled if settings.modules.windbot.enabled
windbots = global.windbots = await loadJSONAsync(settings.modules.windbot.botlist).windbots windbots = global.windbots = (await loadJSONAsync(settings.modules.windbot.botlist)).windbots
real_windbot_server_ip = global.real_windbot_server_ip = settings.modules.windbot.server_ip real_windbot_server_ip = global.real_windbot_server_ip = settings.modules.windbot.server_ip
if !settings.modules.windbot.server_ip.includes("127.0.0.1") if !settings.modules.windbot.server_ip.includes("127.0.0.1")
dns = require('dns') dns = require('dns')
...@@ -447,24 +468,6 @@ init = () -> ...@@ -447,24 +468,6 @@ init = () ->
roomlist = global.roomlist = require './roomlist.js' roomlist = global.roomlist = require './roomlist.js'
if settings.modules.i18n.auto_pick if settings.modules.i18n.auto_pick
geoip = require('geoip-country-lite') geoip = require('geoip-country-lite')
if settings.modules.mysql.enabled
DataManager = require('./data-manager/DataManager.js').DataManager
dataManager = global.dataManager = new DataManager(settings.modules.mysql.db, log)
await dataManager.init()
else
log.warn("Some functions may be limited without MySQL .")
if settings.modules.cloud_replay.enabled
settings.modules.cloud_replay.enabled = false
await setting_save(settings)
log.warn("Cloud replay cannot be enabled because no MySQL.")
if settings.modules.enable_recover.enabled
settings.modules.enable_recover.enabled = false
await setting_save(settings)
log.warn("Recover mode cannot be enabled because no MySQL.")
if settings.modules.chat_color.enabled
settings.modules.chat_color.enabled = false
await setting_save(settings)
log.warn("Chat color cannot be enabled because no MySQL.")
if settings.modules.mycard.enabled if settings.modules.mycard.enabled
pgClient = require('pg').Client pgClient = require('pg').Client
...@@ -584,18 +587,19 @@ init = () -> ...@@ -584,18 +587,19 @@ init = () ->
scores_by_win = _.sortBy(scores_by_lose, (score)-> return score[1].win).reverse() # 然后胜场由低到高,再逆转,就是先排胜场再排败场 scores_by_win = _.sortBy(scores_by_lose, (score)-> return score[1].win).reverse() # 然后胜场由低到高,再逆转,就是先排胜场再排败场
scores = _.first(scores_by_win, 10) scores = _.first(scores_by_win, 10)
#log.info scores #log.info scores
request.post { url : settings.modules.random_duel.post_match_scores , form : {
try
await axios.post(settings.modules.random_duel.post_match_scores, {
headers: { 'content-type': 'application/x-www-form-urlencoded' },
data: qs.stringify({
accesskey: settings.modules.random_duel.post_match_accesskey, accesskey: settings.modules.random_duel.post_match_accesskey,
rank: JSON.stringify(scores) rank: JSON.stringify(scores)
}}, (error, response, body)=> responseType: "json"
if error })
log.warn 'RANDOM SCORE POST ERROR', error })
else catch e
if response.statusCode != 204 and response.statusCode != 200 log.warn 'RANDOM SCORE POST ERROR', e.toString()
log.warn 'RANDOM SCORE POST FAIL', response.statusCode, response.statusMessage, body
#else
# log.info 'RANDOM SCORE POST OK', response.statusCode, response.statusMessage
return
return return
, 60000) , 60000)
...@@ -632,7 +636,6 @@ init = () -> ...@@ -632,7 +636,6 @@ init = () ->
CLIENT_kick(room.waiting_for_player) CLIENT_kick(room.waiting_for_player)
else if time_passed >= (settings.modules.random_duel.hang_timeout - 20) and not (time_passed % 10) else if time_passed >= (settings.modules.random_duel.hang_timeout - 20) and not (time_passed % 10)
ygopro.stoc_send_chat_to_room(room, "#{room.waiting_for_player.name} ${afk_warn_part1}#{settings.modules.random_duel.hang_timeout - time_passed}${afk_warn_part2}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat_to_room(room, "#{room.waiting_for_player.name} ${afk_warn_part1}#{settings.modules.random_duel.hang_timeout - time_passed}${afk_warn_part2}", ygopro.constants.COLORS.RED)
return
if true # settings.modules.arena_mode.punish_quit_before_match if true # settings.modules.arena_mode.punish_quit_before_match
for room in ROOM_all when room and room.arena and room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.get_playing_player().length < 2 for room in ROOM_all when room and room.arena and room.duel_stage == ygopro.constants.DUEL_STAGE.BEGIN and room.get_playing_player().length < 2
...@@ -707,6 +710,8 @@ init = () -> ...@@ -707,6 +710,8 @@ init = () ->
require(plugin_path) require(plugin_path)
log.info("Plugin loaded:", plugin_filename) log.info("Plugin loaded:", plugin_filename)
return
# 获取可用内存 # 获取可用内存
memory_usage = global.memory_usage = 0 memory_usage = global.memory_usage = 0
get_memory_usage = global.get_memory_usage = ()-> get_memory_usage = global.get_memory_usage = ()->
...@@ -3344,27 +3349,18 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3344,27 +3349,18 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
for cname,cvalue of ygopro.constants.COLORS when cvalue > 10 for cname,cvalue of ygopro.constants.COLORS when cvalue > 10
ygopro.stoc_send_chat(client, cname, cvalue) ygopro.stoc_send_chat(client, cname, cvalue)
else if cmsg.toLowerCase() == "default" else if cmsg.toLowerCase() == "default"
if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip await dataManager.setUserChatColor(cip, null)
delete vip_info.players[client.name].chat_color
setting_save(vip_info)
else
delete chat_color.save_list[cip]
setting_save(chat_color)
ygopro.stoc_send_chat(client, "${set_chat_color_default}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${set_chat_color_default}", ygopro.constants.COLORS.BABYBLUE)
else else
ccolor = cmsg.toUpperCase() ccolor = cmsg.toUpperCase()
if ygopro.constants.COLORS[ccolor] and ygopro.constants.COLORS[ccolor] > 10 and ygopro.constants.COLORS[ccolor] < 20 if ygopro.constants.COLORS[ccolor] and ygopro.constants.COLORS[ccolor] > 10 and ygopro.constants.COLORS[ccolor] < 20
if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip await dataManager.setUserChatColor(cip, ccolor)
vip_info.players[client.name].chat_color = ccolor
setting_save(vip_info)
else
chat_color.save_list[cip] = ccolor
setting_save(chat_color)
ygopro.stoc_send_chat(client, "${set_chat_color_part1}" + ccolor + "${set_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${set_chat_color_part1}" + ccolor + "${set_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE)
else else
ygopro.stoc_send_chat(client, "${color_not_found_part1}" + ccolor + "${color_not_found_part2}", ygopro.constants.COLORS.RED) ygopro.stoc_send_chat(client, "${color_not_found_part1}" + ccolor + "${color_not_found_part2}", ygopro.constants.COLORS.RED)
else else
if color = (if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip then vip_info.players[client.name].chat_color else chat_color.save_list[cip]) color = await dataManager.getUserChatColor(cip)
if color
ygopro.stoc_send_chat(client, "${get_chat_color_part1}" + color + "${get_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${get_chat_color_part1}" + color + "${get_chat_color_part2}", ygopro.constants.COLORS.BABYBLUE)
else else
ygopro.stoc_send_chat(client, "${get_chat_color_default}", ygopro.constants.COLORS.BABYBLUE) ygopro.stoc_send_chat(client, "${get_chat_color_default}", ygopro.constants.COLORS.BABYBLUE)
...@@ -3742,8 +3738,8 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3742,8 +3738,8 @@ ygopro.stoc_follow 'CHAT', true, (buffer, info, client, server, datas)->
pid = 1 - pid pid = 1 - pid
for player in room.players when player and player.pos == pid for player in room.players when player and player.pos == pid
tplayer = player tplayer = player
return unless tplayer and (!(settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip) or tplayer.vip) return unless tplayer
tcolor = if settings.modules.vip.enabled and settings.modules.chat_color.restrict_to_vip then vip_info.players[tplayer.name].chat_color else chat_color.save_list[CLIENT_get_authorize_key(tplayer)] tcolor = await dataManager.getUserChatColor(CLIENT_get_authorize_key(tplayer));
if tcolor if tcolor
ygopro.stoc_send client, 'CHAT', { ygopro.stoc_send client, 'CHAT', {
player: ygopro.constants.COLORS[tcolor] player: ygopro.constants.COLORS[tcolor]
...@@ -4071,15 +4067,13 @@ if true ...@@ -4071,15 +4067,13 @@ if true
response.writeHead(404) response.writeHead(404)
response.end("bad filename") response.end("bad filename")
return return
fs.readFile(settings.modules.tournament_mode.replay_path + filename, (error, buffer)-> try
if error buffer = await fs.promises.readFile(settings.modules.tournament_mode.replay_path + filename)
response.writeHead(404)
response.end("未找到文件 " + filename)
else
response.writeHead(200, { "Content-Type": "application/octet-stream", "Content-Disposition": "attachment" }) response.writeHead(200, { "Content-Type": "application/octet-stream", "Content-Disposition": "attachment" })
response.end(buffer) response.end(buffer)
return catch e
) response.writeHead(404)
response.end("未找到文件 " + filename)
else if u.pathname == '/api/message' else if u.pathname == '/api/message'
#if !pass_validated #if !pass_validated
......
This diff is collapsed.
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