forked from Hri7566/mpp-server-dev2
Add kickban, improve command line
This commit is contained in:
parent
275ad3823f
commit
2f3311be1f
|
@ -11,6 +11,7 @@ crown:
|
||||||
normal:
|
normal:
|
||||||
a: 600
|
a: 600
|
||||||
m: 50
|
m: 50
|
||||||
|
ch: 1000
|
||||||
chains:
|
chains:
|
||||||
userset:
|
userset:
|
||||||
interval: 1800000,
|
interval: 1800000,
|
||||||
|
@ -19,6 +20,7 @@ admin:
|
||||||
normal:
|
normal:
|
||||||
a: 120
|
a: 120
|
||||||
m: 16.6666666667
|
m: 16.6666666667
|
||||||
|
ch: 100
|
||||||
chains:
|
chains:
|
||||||
userset:
|
userset:
|
||||||
interval: 1800000,
|
interval: 1800000,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import EventEmitter from "events";
|
import EventEmitter, { on } from "events";
|
||||||
import { Logger } from "../util/Logger";
|
import { Logger } from "../util/Logger";
|
||||||
import {
|
import {
|
||||||
ChannelSettingValue,
|
ChannelSettingValue,
|
||||||
|
@ -15,12 +15,19 @@ import Crown from "./Crown";
|
||||||
import { ChannelList } from "./ChannelList";
|
import { ChannelList } from "./ChannelList";
|
||||||
import { config } from "./config";
|
import { config } from "./config";
|
||||||
|
|
||||||
|
interface CachedKickban {
|
||||||
|
userId: string;
|
||||||
|
startTime: number;
|
||||||
|
endTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class Channel extends EventEmitter {
|
export class Channel extends EventEmitter {
|
||||||
private settings: Partial<IChannelSettings> = config.defaultSettings;
|
private settings: Partial<IChannelSettings> = config.defaultSettings;
|
||||||
private ppl = new Array<Participant>();
|
private ppl = new Array<Participant>();
|
||||||
|
|
||||||
public logger: Logger;
|
public logger: Logger;
|
||||||
public chatHistory = new Array<ClientEvents["a"]>();
|
public chatHistory = new Array<ClientEvents["a"]>();
|
||||||
|
public bans = new Array<CachedKickban>();
|
||||||
|
|
||||||
public crown?: Crown;
|
public crown?: Crown;
|
||||||
|
|
||||||
|
@ -233,7 +240,7 @@ export class Channel extends EventEmitter {
|
||||||
* @param socket Socket that is joining
|
* @param socket Socket that is joining
|
||||||
* @returns undefined
|
* @returns undefined
|
||||||
*/
|
*/
|
||||||
public join(socket: Socket) {
|
public join(socket: Socket): void {
|
||||||
//! /!\ Players are forced to join the same channel on two different tabs!
|
//! /!\ Players are forced to join the same channel on two different tabs!
|
||||||
//? TODO Should this be a bug or a feature?
|
//? TODO Should this be a bug or a feature?
|
||||||
|
|
||||||
|
@ -243,6 +250,18 @@ export class Channel extends EventEmitter {
|
||||||
let hasChangedChannel = false;
|
let hasChangedChannel = false;
|
||||||
let oldChannelID = socket.currentChannelID;
|
let oldChannelID = socket.currentChannelID;
|
||||||
|
|
||||||
|
// Is user banned?
|
||||||
|
if (this.isBanned(part._id)) {
|
||||||
|
// Send user to ban channel instead
|
||||||
|
// TODO Send notification for ban
|
||||||
|
const chs = ChannelList.getList();
|
||||||
|
for (const ch of chs) {
|
||||||
|
if (ch.getID() == config.fullChannel) {
|
||||||
|
return ch.join(socket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Is user in this channel?
|
// Is user in this channel?
|
||||||
if (this.hasUser(part._id)) {
|
if (this.hasUser(part._id)) {
|
||||||
// Alreay in channel, don't add to list, but tell them they're here
|
// Alreay in channel, don't add to list, but tell them they're here
|
||||||
|
@ -370,10 +389,11 @@ export class Channel extends EventEmitter {
|
||||||
* Get this channel's information
|
* Get this channel's information
|
||||||
* @returns Channel info object (includes ID, number of users, settings, and the crown)
|
* @returns Channel info object (includes ID, number of users, settings, and the crown)
|
||||||
*/
|
*/
|
||||||
public getInfo() {
|
public getInfo(_id?: string) {
|
||||||
return {
|
return {
|
||||||
_id: this.getID(),
|
_id: this.getID(),
|
||||||
id: this.getID(),
|
id: this.getID(),
|
||||||
|
banned: _id ? this.isBanned(_id) : false,
|
||||||
count: this.ppl.length,
|
count: this.ppl.length,
|
||||||
settings: this.settings,
|
settings: this.settings,
|
||||||
crown: this.crown
|
crown: this.crown
|
||||||
|
@ -561,6 +581,57 @@ export class Channel extends EventEmitter {
|
||||||
this.emit("update", this);
|
this.emit("update", this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kickban a poor soul for t milliseconds.
|
||||||
|
* @param _id User ID to ban
|
||||||
|
* @param t Time in millseconds to ban for
|
||||||
|
**/
|
||||||
|
public kickban(_id: string, t: number = 1000 * 60 * 30) {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
if (!this.hasUser(_id)) return;
|
||||||
|
|
||||||
|
const part = this.ppl.find(p => p._id == _id);
|
||||||
|
if (!part) return;
|
||||||
|
|
||||||
|
this.bans.push({
|
||||||
|
userId: _id,
|
||||||
|
startTime: now,
|
||||||
|
endTime: now + t
|
||||||
|
});
|
||||||
|
|
||||||
|
const socket = findSocketByPartID(part.id);
|
||||||
|
if (!socket) return;
|
||||||
|
|
||||||
|
const banChannel = ChannelList.getList().find(
|
||||||
|
ch => ch.getID() == config.fullChannel
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!banChannel) return;
|
||||||
|
banChannel.join(socket);
|
||||||
|
|
||||||
|
this.emit("update", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public isBanned(_id: string) {
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
for (const ban of this.bans) {
|
||||||
|
if (ban.endTime <= now) {
|
||||||
|
// Remove old ban and skip
|
||||||
|
this.bans.splice(this.bans.indexOf(ban), 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if they are banned
|
||||||
|
if (ban.userId == _id) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Channel;
|
export default Channel;
|
||||||
|
|
|
@ -18,6 +18,14 @@ const onChannelUpdate = (channel: Channel) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const part = channel.getParticipantList().find(p => p.id == partId);
|
||||||
|
|
||||||
|
if (part) {
|
||||||
|
info.banned = channel.isBanned(part._id);
|
||||||
|
} else {
|
||||||
|
info.banned = false;
|
||||||
|
}
|
||||||
|
|
||||||
socket.sendChannelList([info], false);
|
socket.sendChannelList([info], false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,8 +39,7 @@ export function createColor(ip: string) {
|
||||||
createHash("sha256")
|
createHash("sha256")
|
||||||
.update(ip)
|
.update(ip)
|
||||||
.update(env.SALT)
|
.update(env.SALT)
|
||||||
.update("color")
|
|
||||||
.digest("hex")
|
.digest("hex")
|
||||||
.substring(0, 24 + 6)
|
.substring(24, 24 + 6)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,33 @@
|
||||||
|
import { ChannelList } from "../../channel/ChannelList";
|
||||||
|
import { deleteUser } from "../../data/user";
|
||||||
import Command from "./Command";
|
import Command from "./Command";
|
||||||
|
|
||||||
Command.addCommand(
|
Command.addCommand(
|
||||||
new Command(["help", "h", "commands", "cmds"], "help", msg => {
|
new Command(["help", "h", "commands", "cmds"], "help", msg => {
|
||||||
|
if (!msg.args[1]) {
|
||||||
return (
|
return (
|
||||||
"Commands: " +
|
"Commands: " +
|
||||||
Command.commands.map(cmd => cmd.aliases[0]).join(" | ")
|
Command.commands.map(cmd => cmd.aliases[0]).join(" | ")
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
let foundCommand: Command | undefined;
|
||||||
|
|
||||||
|
for (const command of Command.commands) {
|
||||||
|
for (const alias of command.aliases) {
|
||||||
|
if (msg.args[1] == alias) {
|
||||||
|
foundCommand = command;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundCommand) return `No such command "${msg.args[1]}"`;
|
||||||
|
return "Usage: " + foundCommand.usage;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
Command.addCommand(
|
Command.addCommand(
|
||||||
new Command(["memory", "mem"], "mem", msg => {
|
new Command(["memory", "mem"], "memory", msg => {
|
||||||
const mem = process.memoryUsage();
|
const mem = process.memoryUsage();
|
||||||
return `Memory: ${(mem.heapUsed / 1000 / 1000).toFixed(2)} MB used / ${(
|
return `Memory: ${(mem.heapUsed / 1000 / 1000).toFixed(2)} MB used / ${(
|
||||||
mem.heapTotal /
|
mem.heapTotal /
|
||||||
|
@ -25,3 +42,20 @@ Command.addCommand(
|
||||||
process.exit();
|
process.exit();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Command.addCommand(
|
||||||
|
new Command(["userdel", "deluser"], "userdel <id>", async msg => {
|
||||||
|
await deleteUser(msg.args[1]);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
Command.addCommand(
|
||||||
|
new Command(["list", "ls"], "list", async msg => {
|
||||||
|
return (
|
||||||
|
"Channels:\n- " +
|
||||||
|
ChannelList.getList()
|
||||||
|
.map(ch => ch.getID())
|
||||||
|
.join("\n- ")
|
||||||
|
);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
|
@ -55,7 +55,10 @@ export class Socket extends EventEmitter {
|
||||||
public currentChannelID: string | undefined;
|
public currentChannelID: string | undefined;
|
||||||
private cursorPos: Vector2<CursorValue> = { x: 200, y: 100 };
|
private cursorPos: Vector2<CursorValue> = { x: 200, y: 100 };
|
||||||
|
|
||||||
constructor(private ws: ServerWebSocket<unknown>, public socketID: string) {
|
constructor(
|
||||||
|
private ws: ServerWebSocket<unknown>,
|
||||||
|
public socketID: string
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this.ip = ws.remoteAddress; // Participant ID
|
this.ip = ws.remoteAddress; // Participant ID
|
||||||
|
|
||||||
|
@ -406,7 +409,7 @@ export class Socket extends EventEmitter {
|
||||||
public subscribeToChannelList() {
|
public subscribeToChannelList() {
|
||||||
ChannelList.subscribe(this.id);
|
ChannelList.subscribe(this.id);
|
||||||
|
|
||||||
const firstList = ChannelList.getPublicList().map(v => v.getInfo());
|
const firstList = ChannelList.getPublicList().map(v => v.getInfo(this._id));
|
||||||
this.sendChannelList(firstList);
|
this.sendChannelList(firstList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,6 +448,16 @@ export class Socket extends EventEmitter {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public kickban(_id: string, ms: number) {
|
||||||
|
const channel = this.getCurrentChannel();
|
||||||
|
|
||||||
|
if (!channel) return;
|
||||||
|
|
||||||
|
if (this.isOwner()) {
|
||||||
|
channel.kickban(_id, ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const socketsBySocketID = new Map<string, Socket>();
|
export const socketsBySocketID = new Map<string, Socket>();
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ServerEventListener } from "../../../../util/types";
|
||||||
|
|
||||||
|
export const kickban: ServerEventListener<"kickban"> = {
|
||||||
|
id: "kickban",
|
||||||
|
callback: (msg, socket) => {
|
||||||
|
// Kickban asshole from channel
|
||||||
|
if (!msg._id) return;
|
||||||
|
if (!msg.ms) return;
|
||||||
|
socket.kickban(msg._id, msg.ms);
|
||||||
|
}
|
||||||
|
};
|
|
@ -13,6 +13,7 @@ import { plus_ls } from "./handlers/+ls";
|
||||||
import { minus_ls } from "./handlers/-ls";
|
import { minus_ls } from "./handlers/-ls";
|
||||||
import { admin_message } from "./handlers/admin_message";
|
import { admin_message } from "./handlers/admin_message";
|
||||||
import { chset } from "./handlers/chset";
|
import { chset } from "./handlers/chset";
|
||||||
|
import { kickban } from "./handlers/kickban";
|
||||||
|
|
||||||
// Imagine not having an "addMany" function...
|
// Imagine not having an "addMany" function...
|
||||||
|
|
||||||
|
@ -40,7 +41,8 @@ EVENTGROUP_USER.addMany(
|
||||||
plus_ls,
|
plus_ls,
|
||||||
minus_ls,
|
minus_ls,
|
||||||
admin_message,
|
admin_message,
|
||||||
chset
|
chset,
|
||||||
|
kickban
|
||||||
);
|
);
|
||||||
|
|
||||||
eventGroups.push(EVENTGROUP_USER);
|
eventGroups.push(EVENTGROUP_USER);
|
||||||
|
|
Loading…
Reference in New Issue