Commit 9b6ebc77 authored by nanahira's avatar nanahira

move ban to mysql

parent ca04a1e9
......@@ -8,6 +8,7 @@ const moment_1 = __importDefault(require("moment"));
const typeorm_1 = require("typeorm");
const CloudReplay_1 = require("./entities/CloudReplay");
const CloudReplayPlayer_1 = require("./entities/CloudReplayPlayer");
const Ban_1 = require("./entities/Ban");
class DataManager {
constructor(config, log) {
this.config = config;
......@@ -51,9 +52,8 @@ class DataManager {
try {
return await this.db.createQueryBuilder(CloudReplay_1.CloudReplay, "replay")
.orderBy("rand()")
.limit(4)
.limit(4) //there may be 4 players
.leftJoinAndSelect("replay.players", "player")
.printSql()
.getOne();
}
catch (e) {
......@@ -83,6 +83,48 @@ class DataManager {
}
});
}
async checkBan(field, value) {
const banQuery = {};
banQuery[field] = value;
try {
return await this.db.getRepository(Ban_1.Ban).findOne(banQuery);
}
catch (e) {
this.log.warn(`Failed to load ban ${field} ${value}: ${e.toString()}`);
return null;
}
}
async checkBanWithNameAndIP(name, ip) {
try {
return await this.db.getRepository(Ban_1.Ban).findOne({ name, ip });
}
catch (e) {
this.log.warn(`Failed to load ban ${name} ${ip}: ${e.toString()}`);
return null;
}
}
getBan(name, ip) {
const ban = new Ban_1.Ban();
ban.ip = ip;
ban.name = name;
return ban;
}
async banPlayer(ban) {
try {
const repo = this.db.getRepository(Ban_1.Ban);
if (await repo.findOne({
ip: ban.ip,
name: ban.name
})) {
return;
}
return await repo.save(ban);
}
catch (e) {
this.log.warn(`Failed to update ban ${JSON.stringify(ban)}: ${e.toString()}`);
return null;
}
}
}
exports.DataManager = DataManager;
//# sourceMappingURL=DataManager.js.map
\ No newline at end of file
......@@ -2,8 +2,9 @@ import moment from "moment";
import { Moment } from "moment";
import bunyan from "bunyan";
import { Connection, ConnectionOptions, createConnection, Transaction } from "typeorm";
import { CloudReplay} from "./entities/CloudReplay";
import { CloudReplay } from "./entities/CloudReplay";
import { CloudReplayPlayer } from "./entities/CloudReplayPlayer";
import { Ban } from "./entities/Ban";
export interface CloudReplayPlayerInfo {
......@@ -34,22 +35,22 @@ export class DataManager {
async getCloudReplaysFromKey(key: string) {
try {
const replays = await 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 })
.orderBy("replay.date", "DESC")
.limit(10)
.leftJoinAndSelect("replay.players", "player")
.getMany();
.where("exists (select id from cloud_replay_player where cloud_replay_player.cloudReplayId = replay.id and cloud_replay_player.key = :key)", { key })
.orderBy("replay.date", "DESC")
.limit(10)
.leftJoinAndSelect("replay.players", "player")
.getMany();
return replays;
} catch (e) {
this.log.warn(`Failed to load replay of ${key}: ${e.toString()}`);
return [];
}
}
async getCloudReplayFromId(id: number) {
try {
return await this.db.getRepository(CloudReplay).findOne(id, {relations: ["players"]});
return await this.db.getRepository(CloudReplay).findOne(id, { relations: ["players"] });
} catch (e) {
this.log.warn(`Failed to load replay R#${id}: ${e.toString()}`);
return null;
......@@ -91,4 +92,46 @@ export class DataManager {
});
}
async checkBan(field: string, value: string) {
const banQuery: any = {};
banQuery[field] = value;
try {
return await this.db.getRepository(Ban).findOne(banQuery);
} catch (e) {
this.log.warn(`Failed to load ban ${field} ${value}: ${e.toString()}`);
return null;
}
}
async checkBanWithNameAndIP(name: string, ip: string) {
try {
return await this.db.getRepository(Ban).findOne({ name, ip });
} catch (e) {
this.log.warn(`Failed to load ban ${name} ${ip}: ${e.toString()}`);
return null;
}
}
getBan(name: string, ip: string) {
const ban = new Ban();
ban.ip = ip;
ban.name = name;
return ban;
}
async banPlayer(ban: Ban) {
try {
const repo = this.db.getRepository(Ban);
if (await repo.findOne({
ip: ban.ip,
name: ban.name
})) {
return;
}
return await repo.save(ban);
} catch (e) {
this.log.warn(`Failed to update ban ${JSON.stringify(ban)}: ${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.Ban = void 0;
const typeorm_1 = require("typeorm");
let Ban = /** @class */ (() => {
let Ban = class Ban {
};
__decorate([
typeorm_1.PrimaryGeneratedColumn({ unsigned: true, type: "bigint" }),
__metadata("design:type", Number)
], Ban.prototype, "id", void 0);
__decorate([
typeorm_1.Index(),
typeorm_1.Column({ type: "varchar", length: 64, nullable: true }),
__metadata("design:type", String)
], Ban.prototype, "ip", void 0);
__decorate([
typeorm_1.Index(),
typeorm_1.Column({ type: "varchar", length: 20, nullable: true }),
__metadata("design:type", String)
], Ban.prototype, "name", void 0);
Ban = __decorate([
typeorm_1.Entity()
], Ban);
return Ban;
})();
exports.Ban = Ban;
//# sourceMappingURL=Ban.js.map
\ No newline at end of file
import { Column, Entity, Index, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class Ban {
@PrimaryGeneratedColumn({ unsigned: true, type: "bigint" })
id: number;
@Index()
@Column({ type: "varchar", length: 64, nullable: true })
ip: string;
@Index()
@Column({ type: "varchar", length: 20, nullable: true })
name: string;
}
......@@ -320,8 +320,6 @@
}
},
"ban": {
"banned_user": [],
"banned_ip": [],
"illegal_id": [
"^Lv\\.-*\\d+\\s*(.*)",
"^VIP\\.\\d+\\s*(.*)"
......
......@@ -330,8 +330,13 @@ users_cache = {}
if settings.modules.mysql.enabled
DataManager = require('./data-manager/DataManager.js').DataManager
dataManager = new DataManager(settings.modules.mysql.db, log)
dataManager = global.dataManager = new DataManager(settings.modules.mysql.db, log)
dataManager.init().then(() -> log.info("Database ready."))
else
if settings.modules.cloud_replay.enabled
settings.modules.cloud_replay.enabled = false
setting_save(settings)
log.warn("Cloud replay cannot be enabled because no MySQL.")
if settings.modules.mycard.enabled
pgClient = require('pg').Client
......@@ -484,27 +489,18 @@ ROOM_connected_ip = global.ROOM_connected_ip = {}
ROOM_bad_ip = global.ROOM_bad_ip = {}
# ban a user manually and permanently
ban_user = global.ban_user = (name, callback) ->
settings.ban.banned_user.push(name)
setting_save(settings)
bad_ip = []
_async.each(ROOM_all, (room, done)->
if !(room and room.established)
done()
return
_async.each(["players", "watchers"], (player_type, _done)->
_async.each(room[player_type], (player, __done)->
if player and (player.name == name or bad_ip.indexOf(player.ip) != -1)
bad_ip.push(player.ip)
ROOM_bad_ip[bad_ip]=99
settings.ban.banned_ip.push(player.ip)
ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
CLIENT_send_replays(player, room)
CLIENT_kick(player)
__done()
, _done)
, done)
, callback)
ban_user = global.ban_user = (name) ->
bans = [dataManager.getBan(name, null)]
for room in ROOM_all when room and room.established
for playerType in ["players", "watchers"]
for player in room[playerType] when player.name == name or bans.find(ban => player.ip == ban.ip)
bans.push(dataManager.getBan(name, player.ip))
ROOM_bad_ip[player.ip]=99
ygopro.stoc_send_chat_to_room(room, "#{player.name} ${kicked_by_system}", ygopro.constants.COLORS.RED)
CLIENT_send_replays(player, room)
CLIENT_kick(player)
for ban in bans
await dataManager.banPlayer(ban)
return
# automatically ban user to use random duel
......@@ -2254,13 +2250,15 @@ ygopro.ctos_follow 'JOIN_GAME', true, (buffer, info, client, server, datas)->
log.warn("MULTI LOGIN", client.name, client.ip)
ygopro.stoc_die(client, "${too_much_connection}" + client.ip)
else if _.indexOf(settings.ban.banned_user, client.name) > -1 #账号被封
settings.ban.banned_ip.push(client.ip)
setting_save(settings)
else if settings.modules.mysql.enabled and await dataManager.checkBan("name", client.name) #账号被封
exactBan = await dataManager.checkBanWithNameAndIP(client.name, client.ip)
if !exactBan
exactBan = dataManager.getBan(client.name, client.ip)
await dataManager.banPlayer(exactBan)
log.warn("BANNED USER LOGIN", client.name, client.ip)
ygopro.stoc_die(client, "${banned_user_login}")
else if _.indexOf(settings.ban.banned_ip, client.ip) > -1 #IP被封
else if settings.modules.mysql.enabled and await dataManager.checkBan("ip", client.ip) #IP被封
log.warn("BANNED IP LOGIN", client.name, client.ip)
ygopro.stoc_die(client, "${banned_ip_login}")
......@@ -3885,13 +3883,15 @@ if settings.modules.http
response.writeHead(200)
response.end(addCallback(u.query.callback, "['密码错误', 0]"))
return
ban_user(u.query.ban, (err)->
try
await ban_user(u.query.ban)
catch e
log.warn("ban fail", e.toString())
response.writeHead(200)
if(err)
response.end(addCallback(u.query.callback, "['ban fail', '" + u.query.ban + "']"))
else
response.end(addCallback(u.query.callback, "['ban ok', '" + u.query.ban + "']"))
)
response.end(addCallback(u.query.callback, "['ban fail', '" + u.query.ban + "']"))
return
response.writeHead(200)
response.end(addCallback(u.query.callback, "['ban ok', '" + u.query.ban + "']"))
else if u.query.kick
if !await auth.auth(u.query.username, u.query.pass, "kick_user", "kick_user")
......
......@@ -426,10 +426,16 @@
if (settings.modules.mysql.enabled) {
DataManager = require('./data-manager/DataManager.js').DataManager;
dataManager = new DataManager(settings.modules.mysql.db, log);
dataManager = global.dataManager = new DataManager(settings.modules.mysql.db, log);
dataManager.init().then(function() {
return log.info("Database ready.");
});
} else {
if (settings.modules.cloud_replay.enabled) {
settings.modules.cloud_replay.enabled = false;
setting_save(settings);
log.warn("Cloud replay cannot be enabled because no MySQL.");
}
}
if (settings.modules.mycard.enabled) {
......@@ -633,30 +639,36 @@
ROOM_bad_ip = global.ROOM_bad_ip = {};
// ban a user manually and permanently
ban_user = global.ban_user = function(name, callback) {
var bad_ip;
settings.ban.banned_user.push(name);
setting_save(settings);
bad_ip = [];
_async.each(ROOM_all, function(room, done) {
if (!(room && room.established)) {
done();
return;
}
return _async.each(["players", "watchers"], function(player_type, _done) {
return _async.each(room[player_type], function(player, __done) {
if (player && (player.name === name || bad_ip.indexOf(player.ip) !== -1)) {
bad_ip.push(player.ip);
ROOM_bad_ip[bad_ip] = 99;
settings.ban.banned_ip.push(player.ip);
ban_user = global.ban_user = async function(name) {
var ban, bans, len3, len4, len5, len6, n, o, p, player, playerType, q, ref3, ref4, room;
bans = [dataManager.getBan(name, null)];
for (n = 0, len3 = ROOM_all.length; n < len3; n++) {
room = ROOM_all[n];
if (room && room.established) {
ref3 = ["players", "watchers"];
for (o = 0, len4 = ref3.length; o < len4; o++) {
playerType = ref3[o];
ref4 = room[playerType];
for (p = 0, len5 = ref4.length; p < len5; p++) {
player = ref4[p];
if (!(player.name === name || bans.find(ban(() => {
return player.ip === ban.ip;
})))) {
continue;
}
bans.push(dataManager.getBan(name, player.ip));
ROOM_bad_ip[player.ip] = 99;
ygopro.stoc_send_chat_to_room(room, `${player.name} \${kicked_by_system}`, ygopro.constants.COLORS.RED);
CLIENT_send_replays(player, room);
CLIENT_kick(player);
}
return __done();
}, _done);
}, done);
}, callback);
}
}
}
for (q = 0, len6 = bans.length; q < len6; q++) {
ban = bans[q];
await dataManager.banPlayer(ban);
}
};
// automatically ban user to use random duel
......@@ -2313,7 +2325,6 @@
ygopro.stoc_die(client, "${cloud_replay_no}");
return;
}
console.log(replay.players);
buffer = replay.toBuffer();
replay_buffer = null;
try {
......@@ -2506,7 +2517,7 @@
});
ygopro.ctos_follow('JOIN_GAME', true, async function(buffer, info, client, server, datas) {
var available_logs, check_buffer_indentity, create_room_with_action, index, len3, len4, len5, n, name, o, p, pre_room, recover_match, ref3, ref4, replay, replay_id, replays, room, struct;
var available_logs, check_buffer_indentity, create_room_with_action, exactBan, index, len3, len4, len5, n, name, o, p, pre_room, recover_match, ref3, ref4, replay, replay_id, replays, room, struct;
//log.info info
info.pass = info.pass.trim();
client.pass = info.pass;
......@@ -2975,12 +2986,15 @@
} else if (ROOM_connected_ip[client.ip] > 5) {
log.warn("MULTI LOGIN", client.name, client.ip);
ygopro.stoc_die(client, "${too_much_connection}" + client.ip);
} else if (_.indexOf(settings.ban.banned_user, client.name) > -1) { //账号被封
settings.ban.banned_ip.push(client.ip);
setting_save(settings);
} else if (settings.modules.mysql.enabled && (await dataManager.checkBan("name", client.name))) { //账号被封
exactBan = (await dataManager.checkBanWithNameAndIP(client.name, client.ip));
if (!exactBan) {
exactBan = dataManager.getBan(client.name, client.ip);
await dataManager.banPlayer(exactBan);
}
log.warn("BANNED USER LOGIN", client.name, client.ip);
ygopro.stoc_die(client, "${banned_user_login}");
} else if (_.indexOf(settings.ban.banned_ip, client.ip) > -1) { //IP被封
} else if (settings.modules.mysql.enabled && (await dataManager.checkBan("ip", client.ip))) { //IP被封
log.warn("BANNED IP LOGIN", client.name, client.ip);
ygopro.stoc_die(client, "${banned_ip_login}");
} else if (!settings.modules.tournament_mode.enabled && !settings.modules.challonge.enabled && _.any(badwords.level3, function(badword) {
......@@ -5163,14 +5177,17 @@
response.end(addCallback(u.query.callback, "['密码错误', 0]"));
return;
}
ban_user(u.query.ban, function(err) {
try {
await ban_user(u.query.ban);
} catch (error1) {
e = error1;
log.warn("ban fail", e.toString());
response.writeHead(200);
if (err) {
return response.end(addCallback(u.query.callback, "['ban fail', '" + u.query.ban + "']"));
} else {
return response.end(addCallback(u.query.callback, "['ban ok', '" + u.query.ban + "']"));
}
});
response.end(addCallback(u.query.callback, "['ban fail', '" + u.query.ban + "']"));
return;
}
response.writeHead(200);
response.end(addCallback(u.query.callback, "['ban ok', '" + u.query.ban + "']"));
} else if (u.query.kick) {
if (!(await auth.auth(u.query.username, u.query.pass, "kick_user", "kick_user"))) {
response.writeHead(200);
......
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