249 lines
6.6 KiB
JavaScript
249 lines
6.6 KiB
JavaScript
/* @flow */
|
|
|
|
|
|
import logger from './logger';
|
|
import redis from '../data/redis';
|
|
import User from '../data/models/User';
|
|
import webSockets from '../socket/websockets';
|
|
|
|
import { CHAT_CHANNELS } from './constants';
|
|
|
|
export class ChatProvider {
|
|
/*
|
|
* TODO:
|
|
* history really be saved in redis
|
|
*/
|
|
history: Array;
|
|
|
|
constructor() {
|
|
this.history = [];
|
|
for (let i = 0; i < CHAT_CHANNELS.length; i += 1) {
|
|
this.history.push([]);
|
|
}
|
|
this.caseCheck = /^[A-Z !.]*$/;
|
|
this.filters = [
|
|
{
|
|
regexp: /ADMIN/gi,
|
|
matches: 4,
|
|
},
|
|
{
|
|
regexp: /ADMlN/gi,
|
|
matches: 4,
|
|
},
|
|
{
|
|
regexp: /ADMlN/gi,
|
|
matches: 4,
|
|
},
|
|
{
|
|
regexp: /FUCK/gi,
|
|
matches: 4,
|
|
},
|
|
];
|
|
this.substitutes = [
|
|
{
|
|
regexp: /http[s]?:\/\/(old.)?pixelplanet\.fun\/#/g,
|
|
replace: '#',
|
|
},
|
|
];
|
|
this.mutedCountries = [];
|
|
}
|
|
|
|
addMessage(name, message, country, channelId = 0) {
|
|
const channelHistory = this.history[channelId];
|
|
if (channelHistory.length > 20) {
|
|
channelHistory.shift();
|
|
}
|
|
channelHistory.push([name, message, country]);
|
|
}
|
|
|
|
async sendMessage(user, message, channelId: number = 0) {
|
|
const name = (user.regUser) ? user.regUser.name : null;
|
|
const country = user.country || 'xx';
|
|
let displayCountry = (name.endsWith('berg') || name.endsWith('stein'))
|
|
? 'il'
|
|
: country;
|
|
|
|
if (!name) {
|
|
// eslint-disable-next-line max-len
|
|
return 'Couldn\'t send your message, pls log out and back in again.';
|
|
}
|
|
if (!user.regUser.verified) {
|
|
return 'Your mail has to be verified in order to chat';
|
|
}
|
|
if (name === 'Aquila') {
|
|
displayCountry = 'ug';
|
|
}
|
|
|
|
if (message.length > 2
|
|
&& message === message.toUpperCase()
|
|
&& message !== message.toLowerCase()
|
|
) {
|
|
return 'Stop shouting';
|
|
}
|
|
|
|
for (let i = 0; i < this.filters.length; i += 1) {
|
|
const filter = this.filters[i];
|
|
const count = (message.match(filter.regexp) || []).length;
|
|
if (count >= filter.matches) {
|
|
ChatProvider.mute(name, channelId, 30);
|
|
return 'Ow no! Spam protection decided to mute you';
|
|
}
|
|
}
|
|
|
|
for (let i = 0; i < this.substitutes.length; i += 1) {
|
|
const subsitute = this.substitutes[i];
|
|
message = message.replace(subsitute.regexp, subsitute.replace);
|
|
}
|
|
|
|
if (message.includes('http')) {
|
|
return 'no shitty links pls';
|
|
}
|
|
|
|
if (message.length > 200) {
|
|
// eslint-disable-next-line max-len
|
|
return 'You can\'t send a message this long :(';
|
|
}
|
|
|
|
if (user.isAdmin() && message.charAt(0) === '/') {
|
|
// admin commands
|
|
const cmdArr = message.split(' ');
|
|
const cmd = cmdArr[0].substr(1);
|
|
const args = cmdArr.slice(1);
|
|
if (cmd === 'mute') {
|
|
const timeMin = Number(args.slice(-1));
|
|
if (Number.isNaN(timeMin)) {
|
|
return ChatProvider.mute(args.join(' '), channelId);
|
|
}
|
|
return ChatProvider.mute(
|
|
args.slice(0, -1).join(' '),
|
|
channelId,
|
|
timeMin,
|
|
);
|
|
} if (cmd === 'unmute') {
|
|
return ChatProvider.unmute(args.join(' '), channelId);
|
|
} if (cmd === 'mutec' && args[0]) {
|
|
const cc = args[0].toLowerCase();
|
|
this.mutedCountries.push(cc);
|
|
webSockets.broadcastChatMessage(
|
|
'info',
|
|
`Country ${cc} has been muted`,
|
|
channelId,
|
|
);
|
|
return null;
|
|
} if (cmd === 'unmutec' && args[0]) {
|
|
const cc = args[0].toLowerCase();
|
|
if (!this.mutedCountries.includes(cc)) {
|
|
return `Country ${cc} is not muted`;
|
|
}
|
|
this.mutedCountries = this.mutedCountries.filter((c) => c !== cc);
|
|
webSockets.broadcastChatMessage(
|
|
'info',
|
|
`Country ${cc} has been unmuted`,
|
|
channelId,
|
|
);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
if (this.mutedCountries.includes(country)) {
|
|
return 'Your country is temporary muted from chat';
|
|
}
|
|
|
|
const muted = await ChatProvider.checkIfMuted(user);
|
|
if (muted === -1) {
|
|
return 'You are permanently muted, join our discord to apppeal the mute';
|
|
}
|
|
if (muted > 0) {
|
|
if (muted > 120) {
|
|
const timeMin = Math.round(muted / 60);
|
|
return `You are muted for another ${timeMin} minutes`;
|
|
}
|
|
return `You are muted for another ${muted} seconds`;
|
|
}
|
|
this.addMessage(name, message, displayCountry, channelId);
|
|
webSockets.broadcastChatMessage(name, message, displayCountry, channelId);
|
|
return null;
|
|
}
|
|
|
|
broadcastChatMessage(
|
|
name,
|
|
message,
|
|
country: string = 'xx',
|
|
channelId: number = 0,
|
|
sendapi: boolean = true,
|
|
) {
|
|
if (message.length > 250) {
|
|
return;
|
|
}
|
|
this.addMessage(name, message, country, channelId);
|
|
webSockets.broadcastChatMessage(name, message, country, channelId, sendapi);
|
|
}
|
|
|
|
static automute(name, channelId = 0) {
|
|
ChatProvider.mute(name, channelId, 60);
|
|
webSockets.broadcastChatMessage(
|
|
'info',
|
|
`${name} has been muted for spam for 60min`,
|
|
channelId,
|
|
);
|
|
}
|
|
|
|
static async checkIfMuted(user) {
|
|
const key = `mute:${user.id}`;
|
|
const ttl: number = await redis.ttlAsync(key);
|
|
return ttl;
|
|
}
|
|
|
|
static async mute(plainName, channelId = 0, timeMin = null) {
|
|
const name = (plainName.startsWith('@')) ? plainName.substr(1) : plainName;
|
|
const id = await User.name2Id(name);
|
|
if (!id) {
|
|
return `Couldn't find user ${name}`;
|
|
}
|
|
const key = `mute:${id}`;
|
|
if (timeMin) {
|
|
const ttl = timeMin * 60;
|
|
await redis.setAsync(key, '', 'EX', ttl);
|
|
if (timeMin !== 600 && timeMin !== 60) {
|
|
webSockets.broadcastChatMessage(
|
|
'info',
|
|
`${name} has been muted for ${timeMin}min`,
|
|
channelId,
|
|
);
|
|
}
|
|
} else {
|
|
await redis.setAsync(key, '');
|
|
webSockets.broadcastChatMessage(
|
|
'info',
|
|
`${name} has been muted forever`,
|
|
channelId,
|
|
);
|
|
}
|
|
logger.info(`Muted user ${id}`);
|
|
return null;
|
|
}
|
|
|
|
static async unmute(plainName, channelId = 0) {
|
|
const name = (plainName.startsWith('@')) ? plainName.substr(1) : plainName;
|
|
const id = await User.name2Id(name);
|
|
if (!id) {
|
|
return `Couldn't find user ${name}`;
|
|
}
|
|
const key = `mute:${id}`;
|
|
const delKeys = await redis.delAsync(key);
|
|
if (delKeys !== 1) {
|
|
return `User ${name} is not muted`;
|
|
}
|
|
webSockets.broadcastChatMessage(
|
|
'info',
|
|
`${name} has been unmuted`,
|
|
channelId,
|
|
);
|
|
logger.info(`Unmuted user ${id}`);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const chatProvider = new ChatProvider();
|
|
export default chatProvider;
|