ztavern/node-server-manager/Plugins/Global/DiscordBot.js
2024-10-18 00:19:19 +00:00

1012 lines
40 KiB
JavaScript

const path = require('path')
const configName = path.join(__dirname, `../../Configuration/NSMConfiguration.json`)
const config = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`))
const Discord = require('discord.js')
const bot = new Discord.Client()
const Utils = new (require(path.join(__dirname, '../../Utils/Utils.js')))()
const token = config.discordBotToken
const fs = require('fs')
const wait = require('delay')
const moment = require('moment')
const Permissions = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)).Permissions
const Localization = require(path.join(__dirname, `../../Configuration/Localization-${process.env.LOCALE}.json`)).lookup
const clamp = (num, min, max) => Math.min(Math.max(num, min), max)
const colors = ['#FF3131', '#86C000', '#FFAD22', '#0082BA', '#25BDF1', '#9750DD']
var databaseCache = {}
const color = () => colors[Utils.getRandomInt(0, colors.length)]
const stringInsert = (string, index, length, substr) => {
var left = string.slice(0, index)
var right = string.slice(index + length, string.length)
left += substr
left += right
return left
}
const trySend = async (channel, msg) => {
try {
return await channel.send(msg)
}
catch (e) {}
}
const getAllClients = (Managers) => {
var Clients = []
Managers.forEach(Manager => {
Clients = Clients.concat(Manager.Server.getClients())
})
return Clients
}
const formatColors = (string) => {
var open = false
for (var i = 0; i < string.length; i++) {
if (string[i] == '^' && string[i + 1] && string[i + 1].match(/[0-9]/g)) {
if (string[i + 1] == '7') {
open = false
string = stringInsert(string, i, 2, '\u200B**\u200B')
continue
}
string = stringInsert(string, i, 2, open ? '\u200B**\u200B**\u200B' : '\u200B**\u200B')
open = true
}
}
if (open) {
string += '\u200B**\u200B'
}
return string
}
const pagedMessage = async (original, callback, options) => {
var defaultOptions = {timeout: 60 * 1000, max: 0}
options = {...defaultOptions, ...options}
var page = 0
var msg = await trySend(original.channel, callback(page))
if (!msg) {
return
}
const backward = '⬅'
const forward = '➡'
const fastforward = '⏩'
const rewind = '⏪'
await msg.react(rewind)
await msg.react(backward)
await msg.react(forward)
await msg.react(fastforward)
var onReaction = async (reaction, user) => {
if (user.id == bot.user.id) {
return
}
if (reaction.message.id != msg.id) {
return
}
if (user.id != original.author.id) {
reaction.users.remove(user.id)
return
}
switch (reaction.emoji.name) {
case (fastforward):
previous = page
page = options.max
previous != page && msg.edit(callback(page))
break
case (rewind):
previous = page
page = 0
previous != page && msg.edit(callback(page))
break
case (backward):
previous = page
page = clamp(--page, 0, options.max)
previous != page && msg.edit(callback(page))
break
case (forward):
previous = page
page = clamp(++page, 0, options.max)
previous != page && msg.edit(callback(page))
break
}
reaction.users.remove(user.id)
}
bot.on('messageReactionAdd', onReaction)
setTimeout(() => {
bot.removeListener('messageReactionAdd', onReaction)
}, options.timeout)
return msg
}
var discordUsers = {}
class Plugin {
constructor(Managers) {
this.Managers = Managers
this.Manager = Managers[0]
this.Server = this.Manager.Server
this.clientCache = {}
this.commands = {
'help': async (msg, user, args) => {
var commands = Object.entries({...this.Manager.commands, ...this.Manager.Commands.Commands})
.filter(command => {
return !command[1].isMiddleware && (Permissions.Levels[command[1].Permission] == 0 || command[1].PermissionLevel == 0)
})
var chunkedCommands = Utils.chunkArray(commands, 5)
pagedMessage(msg, (page) => {
let embed = new Discord.MessageEmbed()
.setTitle(`Page ${page + 1} / ${chunkedCommands.length}`)
.setColor(color())
for (var i = 0; i < chunkedCommands[page].length; i++) {
embed.addField(
chunkedCommands[page][i][0],
Localization[`COMMAND_${chunkedCommands[page][i][0].toLocaleUpperCase()}`],
false
)
}
return embed
}, {max: chunkedCommands.length - 1})
},
'find': async (msg, user, args) => {
var name = args.splice(1).join(' ')
var matches = await this.Server.DB.getClientByName(name, 20)
if (matches.length <= 0) {
msg.author.tell(Localization['COMMAND_CLIENT_NOT_FOUND'])
return
}
user.lastMatches = matches
var chunkedMatches = Utils.chunkArray(matches, 5)
pagedMessage(msg, (page) => {
let embed = new Discord.MessageEmbed()
.setTitle(`Page ${page + 1} / ${chunkedMatches.length}`)
.setColor(color())
for (var i = 0; i < chunkedMatches[page].length; i++) {
var text = formatColors(Utils.formatString(Localization['COMMAND_FIND_FORMAT'], {
index: page * 5 + i + 1,
Name: chunkedMatches[page][i].Name,
ClientId: chunkedMatches[page][i].ClientId,
Role: Utils.stripString(Utils.getRoleFrom(chunkedMatches[page][i].PermissionLevel, 1).Name),
Active: moment(chunkedMatches[page][i].LastConnection).calendar(),
Joined: moment(chunkedMatches[page][i].FirstConnection).calendar()
}, '%')[0])
embed.addField(
'\u200B',
text,
false
)
}
return embed
}, {max: chunkedMatches.length - 1})
},
'servers': async (msg, user, args) => {
if (this.Managers.length <= 0) {
return
}
var chunkedManagers = Utils.chunkArray(this.Managers.concat().filter(m => m.Server.dvarsLoaded), 5)
pagedMessage(msg, (page) => {
let embed = new Discord.MessageEmbed()
.setTitle(`Page ${page + 1} / ${chunkedManagers.length}`)
.setColor(color())
for (var i = 0; i < chunkedManagers[page].length; i++) {
embed.addField(
`${Utils.stripString(chunkedManagers[page][i].Server.Hostname)} - ${chunkedManagers[page][i].Server.externalIP}`,
`${chunkedManagers[page][i].Server.getMapname().Alias} - ${chunkedManagers[page][i].Server.getClients().length} / ${chunkedManagers[page][i].Server.Clients.length}`,
false
)
}
return embed
}, {max: chunkedManagers.length - 1})
},
'players': async (msg, user, args) => {
var allClients = getAllClients(this.Managers)
user.lastMatches = allClients
if (!allClients.length) {
msg.author.tell(Localization['NO_PLAYERS_ONLINE'])
return
}
var chunkedClients = Utils.chunkArray(allClients, 10)
pagedMessage(msg, (page) => {
let embed = new Discord.MessageEmbed()
.setTitle(`Page ${page + 1} / ${chunkedClients.length}`)
.setColor(color())
var buffer = []
var i = 0; chunkedClients[page].forEach(Client => {
const role = Utils.stripString(Utils.getRoleFrom(Client.PermissionLevel, 1).Name)
const hostname = formatColors(Client.Server.Hostname)
buffer.push(`#${page * 10 + i++ + 1} - [[${role}] **${Client.Name}**](${process.env.webfrontUrl}/id/${Client.ClientId}) - ${hostname}`)
})
embed.addField(`\u200B`, buffer.join('\n').substr(0, 1020), false)
return embed
}, {max: chunkedClients.length - 1})
}
}
this.commands['f'] = this.commands['find']
if (!token) return
this.discordBot()
}
async updateActivity() {
bot.user.setStatus('online')
bot.user.setActivity(Utils.formatString(Localization['DISCORD_BOT_ACTIVITY'], {
totalSlots: this.Managers.reduce((a, {Server}) => a + Server.Clients.length, 0),
onlineClients: this.Managers.reduce((a, {Server}) => a + Server.getClients().length, 0),
totalServers: this.Managers.filter(m => m.Server.Rcon.isRunning).length
}, '%')[0], {
type: 'WATCHING',
url: process.env.webfrontUrl
})
}
discordBot() {
bot.login(token)
bot.on('shardError', (e) => {})
bot.on('ready', async () => {
var guilds = bot.guilds.cache.map(guild => guild)
guilds.forEach(async (guild) => {
this.guildInit(guild)
})
bot.on('message', async (msg) => {
if (msg.author.bot) return
var Manager = this.Managers.find(Manager => Manager && Manager.Server.channel && Manager.Server.channel.id == msg.channel.id)
if (msg.content.includes("Bruh"))
await msg.react('1081765884588212274')
if (msg.content.includes("Turbo tastic"))
await msg.react('1081767190237294632')
if (msg.channel.id == "1072133169811296357") //Claim Rank
{
if (msg.content.includes('@'))
{
msg.content = msg.content.replace('@', '')
var client = await this.Server.DB.getClient(msg.content)
if (!client)
{
await msg.react("❌")
trySend(msg.channel, "ID not found. Type **.id** in game and write it here with the **@**. Example : *@25478*")
return
}
else
{
this.RankClaim(msg, msg.content)
}
return
}
var matches = await this.Server.DB.getClientByName(msg.content, 3)
if (matches.length <= 0) {
await msg.react("❌")
trySend(msg.channel, "**Invalid name** / Never connected to Z-Tavern. You can also type **.id** in game and paste it in a new message. Example : *@25478*")
return
}
if (matches.length > 1)
{
await msg.react("❌")
trySend(msg.channel, "Problem with your account, type **.id** in game and write it in a new message with the **@**. Example : **@25478**")
return
}
this.RankClaim(msg, matches[0].ClientId)
return
}
if (msg.channel.id == "1047317564264550530") //Claim 200k
{
if (msg.content.includes('@'))
{
msg.content = msg.content.replace('@', '')
var client = await this.Server.DB.getClient(msg.content)
if (!client)
{
await msg.react("❌")
trySend(msg.channel, "ID not found. Type **.id** in game and write it here with the **@**. Example : *@25478*")
return
}
else
{
this.isClaimed(msg, msg.content)
}
return
}
var matches = await this.Server.DB.getClientByName(msg.content, 3)
if (matches.length <= 0) {
await msg.react("❌")
trySend(msg.channel, "**Invalid name** / Never connected to Z-Tavern. You can also type **.id** in game and paste it in a new message. Example : *@25478*")
return
}
if (matches.length > 1)
{
await msg.react("❌")
trySend(msg.channel, "Problem with your account, type **.id** in game and write it in a new message with the **@**. Example : **@25478**")
return
}
this.isClaimed(msg, matches[0].ClientId)
return
}
if (!Manager && config.commandPrefixes.includes(msg.content[0]) && (msg.channel.id == "1082001659691016372" || msg.channel.id == "1137834755950399679")) {
this.onCommand(msg)
return
}
Manager && Manager.Server.emit('discord_message', msg)
})
setInterval(() => {
this.updateActivity()
}, 5000)
setInterval(() => {
databaseCache = {}
}, 60 * 1000 * 5)
})
}
async RankClaim(msg, clientId)
{
var fRank = msg.guild.roles.cache.find(role => role.name === "F Rank")
var eRank = msg.guild.roles.cache.find(role => role.name === "E Rank")
var dRank = msg.guild.roles.cache.find(role => role.name === "D Rank")
var cRank = msg.guild.roles.cache.find(role => role.name === "C Rank")
var bRank = msg.guild.roles.cache.find(role => role.name === "B Rank")
var aRank = msg.guild.roles.cache.find(role => role.name === "A Rank")
var sRank = msg.guild.roles.cache.find(role => role.name === "S Rank")
var ssRank = msg.guild.roles.cache.find(role => role.name === "SS Rank")
var sssRank = msg.guild.roles.cache.find(role => role.name === "SSS Rank")
var iRank = msg.guild.roles.cache.find(role => role.name === "Awakened I")
var iiRank = msg.guild.roles.cache.find(role => role.name === "Awakened II")
var iiiRank = msg.guild.roles.cache.find(role => role.name === "Awakened III")
var ivRank = msg.guild.roles.cache.find(role => role.name === "Awakened IV")
var vRank = msg.guild.roles.cache.find(role => role.name === "Awakened V")
var viRank = msg.guild.roles.cache.find(role => role.name === "Awakened VI")
var viiRank = msg.guild.roles.cache.find(role => role.name === "Awakened VII")
var iixRank = msg.guild.roles.cache.find(role => role.name === "Awakened IIX")
var ixRank = msg.guild.roles.cache.find(role => role.name === "Awakened IX")
var xRank = msg.guild.roles.cache.find(role => role.name === "Awakened X")
msg.guild.members.cache.get(msg.author.id).roles.remove(fRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(eRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(dRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(cRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(bRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(aRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(sRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(ssRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(sssRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(iRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(iiRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(iiiRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(ivRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(vRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(viRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(viiRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(iixRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(ixRank)
msg.guild.members.cache.get(msg.author.id).roles.remove(xRank)
var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', clientId)
if (!customTag)
{
await msg.react("❌")
trySend(msg.channel, "Error, please contact Admin")
return
}
if (customTag.Value.includes("F"))
{
var role = msg.guild.roles.cache.find(role => role.name === "F Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("E"))
{
var role = msg.guild.roles.cache.find(role => role.name === "E Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("D"))
{
var role = msg.guild.roles.cache.find(role => role.name === "D Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("C"))
{
var role = msg.guild.roles.cache.find(role => role.name === "C Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("B"))
{
var role = msg.guild.roles.cache.find(role => role.name === "B Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("A"))
{
var role = msg.guild.roles.cache.find(role => role.name === "A Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("SSS"))
{
var role = msg.guild.roles.cache.find(role => role.name === "SSS Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("SS"))
{
var role = msg.guild.roles.cache.find(role => role.name === "SS Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value.includes("S"))
{
var role = msg.guild.roles.cache.find(role => role.name === "S Rank")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^6 I ^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened I")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^6II^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened II")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^6III^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened III")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^5IV^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened IV")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^5V^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened V")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^5VI^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened VI")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^5VII^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened VII")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^1IIX^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened IIX")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^1IX^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened IX")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
if (customTag.Value == "^1-X-^7")
{
var role = msg.guild.roles.cache.find(role => role.name === "Awakened X")
msg.guild.members.cache.get(msg.author.id).roles.add(role)
await msg.react("✅")
return
}
}
async isClaimed(msg, clientId)
{
var claimed = await this.Server.DB.metaService.getPersistentMeta('claimed', clientId)
if (!claimed)
{
await this.Server.DB.metaService.addPersistentMeta('claimed', '200000', clientId)
var totalMoney = (await this.getZMStats(clientId)).Money
this.setPlayerMoney(clientId, parseInt(totalMoney) + 200000)
await msg.react("✅")
}
else
{
await msg.react("❌")
trySend(msg.channel, "One claim only.")
}
}
async setPlayerMoney(ClientId, Money) {
await this.Server.DB.Models.NSMZombiesStats.update({
Money : Money }, {
where: {ClientId: ClientId
}
})
}
async getZMStats(ClientId) {
if (ClientId == 1) {
return {
Money: Infinity,
LockerWeapon: 'none'
}
}
var ZMStats = await this.Server.DB.Models.NSMZombiesStats.findAll({
where: {
ClientId: ClientId
}
})
return ZMStats.length > 0 ?ZMStats[0].dataValues : false
}
async saveConfig() {
fs.writeFile(configName, JSON.stringify(config, null, 4), (err) => {
if (err) {
console.log(err)
return
}
})
}
stripMentions(string) {
return string.replace(new RegExp(/((<@(.*?)>)|(@(.*?)))/g), '(@)')
}
getServerIcon(Server) {
var imgPath = path.join(__dirname, `../../Webfront/Public/img/maps/${Server.Gamename.toLocaleLowerCase()}/${Server.Mapname}.jpg`)
return fs.existsSync(imgPath) ? imgPath : path.join(__dirname, `../../Webfront/Public/img/maps/default.png`)
}
getServerIconName(Server) {
var imgPath = path.join(__dirname, `../../Webfront/Public/img/maps/${Server.Gamename.toLocaleLowerCase()}/${Server.Mapname}.jpg`)
return fs.existsSync(imgPath) ? `${Server.Mapname}.jpg` : `default.png`
}
async serverLogger(category, guild, Server) {
this.updateActivity()
Server.on('message', async (Player, Message) => {
var discordUser = await this.getDiscordUser(Player.ClientId)
var msg = Utils.stripString(this.stripMentions(Message))
if (!msg.length) return
Server.channel.webhook.send(msg, {
username: Player.Name,
avatarURL: discordUser ? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png` : `https://cdn.discordapp.com/embed/avatars/0.png`
})
})
Server.on('penalty', async (Type, Target, Reason, Origin, Duration = -1) => {
if (`${Utils.stripString(this.stripMentions(Reason))}` == "VPN detected")
{
return;
}
if (Reason.includes("rank"))
return;
let embed = new Discord.MessageEmbed()
.setTitle(`:hammer: Penalty`)
.setDescription(Utils.formatString(Localization['DISCORD_BOT_PENALTY'], {
target: Target.Name,
targetUrl: `${process.env.webfrontUrl}/id/${Target.ClientId}`,
penaltyName: `**${Localization[Type].toLocaleLowerCase()}**`,
origin: Origin.Name,
originUrl: `${process.env.webfrontUrl}/id/${Origin.ClientId}`,
duration: Duration > 0 ? `(${Utils.time2str(Duration)})` : '',
reason: `**${Utils.stripString(this.stripMentions(Reason))}**`
}))
.addField('Target', `[${Target.Name}](${process.env.webfrontUrl}/id/${Target.ClientId})`, true)
.addField('Origin', `[${Origin.Name}](${process.env.webfrontUrl}/id/${Origin.ClientId})`, true)
.addField('Reason', Utils.stripString(Reason), true)
.setTimestamp()
.setColor(colors[Utils.getRandomInt(0, colors.length)])
Duration > 0 && embed.addField('Duration', Utils.time2str(Duration), true)
trySend(guild.eventChannel, embed)
})
Server.on('report', async (Origin, Target, Reason) => {
var modRoles = config[guild.id]['modRoles'].map(role => `<@&${role}>`)
let embed = new Discord.MessageEmbed()
.setTitle(':triangular_flag_on_post: Report')
.setDescription(Utils.formatString(Localization['DISCORD_BOT_REPORT'], {
target: Target.Name,
targetUrl: `${process.env.webfrontUrl}/id/${Target.ClientId}`,
origin: Origin.Name,
originUrl: `${process.env.webfrontUrl}/id/${Origin.ClientId}`,
reason: `**${Utils.stripString(this.stripMentions(Reason))}**`
}))
.addField('Target', `[${Target.Name}](${process.env.webfrontUrl}/id/${Target.ClientId})`, true)
.addField('Origin', `[${Origin.Name}](${process.env.webfrontUrl}/id/${Origin.ClientId})`, true)
.addField('Reason', Utils.stripString(Reason), true)
.addField('Server', Utils.stripString(Server.Hostname), true)
.setTimestamp()
.setColor(colors[Utils.getRandomInt(0, colors.length)])
modRoles.join(' ').length && await guild.eventChannel.send(modRoles.join(' '))
var r_text = new Array ();
r_text[0] = "<@&1128454277686374471> DEFCON 5! DEFCON 5!";
r_text[1] = "<@&1128454277686374471> That's gotta be a yellow card at least";
r_text[2] = "<@&1128454277686374471> I swear if its another dood who box emp..";
r_text[3] = "<@&1128454277686374471> Fun fact, someone send a report because he couldnt get a spin at the box :skull:";
r_text[4] = "<@&1128454277686374471> He have brought malice and dishonor to this battlefield. In turn, you shall bring him justice. Justice with well maintained six-pack abs and toned biceps. You shall strike him down where he stand.";
r_text[5] = "<@&1128454277686374471> These messages are a great use of my time, no cap";
r_text[6] = "<@&1128454277686374471> Just how many of these messages are there? Man could've fixed .afk & MOTD & release the RPG update in half that time!";
var i = Math.floor(7*Math.random())
trySend(guild.eventChannel, r_text[i])
trySend(guild.eventChannel, embed)
})
Server.on('round_start', async (roundNumber) => {
let embed = new Discord.MessageEmbed()
.setTitle('Round started')
.addField(roundNumber, '\u200B', true)
.setColor(colors[Utils.getRandomInt(0, colors.length)])
.attachFiles([this.getServerIcon(Server)])
.setThumbnail(`attachment://${this.getServerIconName(Server)}`)
.setTimestamp()
.setFooter(`${Server.getClients().length} / ${Server.Clients.length}`)
trySend(Server.channel, embed)
})
Server.on('disconnect', async (Player) => {
var discordUser = await this.getDiscordUser(Player.ClientId)
let embed = new Discord.MessageEmbed()
.setURL(`${process.env.webfrontUrl}/id/${Player.ClientId}`)
.setColor(colors[Utils.getRandomInt(0, colors.length)])
.setTimestamp()
.setAuthor(`${Player.Name} disconnected`, discordUser ? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png` : `https://cdn.discordapp.com/embed/avatars/0.png`)
.setFooter(`${Server.getClients().length} / ${Server.Clients.length}`)
trySend(Server.channel, embed)
this.updateActivity()
})
Server.on('connect', async (Player) => {
var discordUser = await this.getDiscordUser(Player.ClientId)
let embed = new Discord.MessageEmbed()
.setURL(`${process.env.webfrontUrl}/id/${Player.ClientId}`)
.setColor(colors[Utils.getRandomInt(0, colors.length)])
.setTimestamp()
.setAuthor(`${Player.Name} connected`, discordUser ? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png` : `https://cdn.discordapp.com/embed/avatars/0.png`)
.setFooter(`${Server.getClients().length} / ${Server.Clients.length}`)
trySend(Server.channel, embed)
this.updateActivity()
})
Server.on('map_loaded', () => {
let embed = new Discord.MessageEmbed()
.setTitle('Map rotated')
.addField('Mapname', `${Server.getMapname().Alias}`, true)
.addField('Gametype', `${Server.getGametype().Alias}`, true)
.setColor(colors[Utils.getRandomInt(0, colors.length)])
.attachFiles([this.getServerIcon(Server)])
.setThumbnail(`attachment://${this.getServerIconName(Server)}`)
.setTimestamp()
.setFooter(`${Server.getClients().length} / ${Server.Clients.length}`)
trySend(Server.channel, embed)
this.updateActivity()
})
Server.on('discord_message', async (msg) => {
if (msg.channel.id == "1137834755950399679")
{
msg.reply("Link your account [here](http://149.202.93.80:8000)")
return
}
if (!Server.channel
|| msg.channel.id != Server.channel.id
|| msg.author.id == bot.user.id
|| msg.author.bot) return
var Client = await this.getClientByDiscord(msg.author.id)
if (!Client.Name) {
msg.reply(Utils.formatString(Localization['DISCORD_ACC_NOT_CONNECTED'], {
url: process.env.webfrontUrl
}, '%'))
return
}
Server.Broadcast(Utils.formatString(Localization['SOCKET_MSG_FORMAT'], {
name: Client.Name,
message: msg.content
}))
})
}
async initServer(category, guild, Server) {
var channel = guild.channels.cache.find(channel => config.Servers[Server.Id][guild.id] && channel.id == config.Servers[Server.Id][guild.id].channelId)
if (!channel) {
await wait(500)
var channel = await guild.channels.create(Utils.stripString(Server.Hostname))
config.Servers[Server.Id][guild.id] = { ...config.Servers[Server.Id][guild.id], channelId: channel.id }
this.saveConfig()
}
channel.setParent(category.id)
var webhook = await channel.fetchWebhooks()
webhook = webhook.first()
if (!webhook) {
var webhook = await channel.createWebhook('NSM Bot')
}
channel.webhook = webhook
Server.channel = channel
Server.emit('discord_ready')
this.serverLogger(category, guild, Server)
}
async guildInit(guild) {
var category = guild.channels.cache.find(channel => config[guild.id] && channel.type == 'category' && channel.id == config[guild.id].categoryId)
if (!category) {
var category = await guild.channels.create('Game-Servers', {
type: 'category'
})
config[guild.id] = { categoryId: category.id }
this.saveConfig()
}
var eventChannel = guild.channels.cache.find(channel => config[guild.id]['eventChannelId'] && channel.type == 'text' && channel.id == config[guild.id]['eventChannelId'])
!config[guild.id]['modRoles'] && (config[guild.id]['modRoles'] = [], this.saveConfig())
if (!eventChannel) {
var eventChannel = await guild.channels.create('Events')
eventChannel.setParent(category.id)
eventChannel.setPosition(0, 0)
eventChannel.updateOverwrite(guild.roles.everyone, { SEND_MESSAGES: false })
eventChannel.overwritePermissions([
{
id: guild.id,
deny: ['SEND_MESSAGES'],
}
])
config[guild.id]['eventChannelId'] = eventChannel.id
this.saveConfig()
}
guild.eventChannel = eventChannel
for (var i = 0; i < this.Managers.length; i++) {
if (Utils.stripString(this.Managers[i].Server.Hostname).includes("PRIVATE") == false)
{
if (this.Managers[i].Server.dvarsLoaded) {
this.initServer(category, guild, this.Managers[i].Server)
continue
}
this.Managers[i].Server.on('dvars_loaded', async (Server) => {
this.initServer(category, guild, Server)
console.log()
})
}
}
}
async getDiscordUser(ClientId) {
if (databaseCache[ClientId]) return databaseCache[ClientId]
var discordUser = await this.Server.DB.metaService.getPersistentMeta('discord_user', ClientId)
databaseCache[ClientId] = discordUser ? JSON.parse(discordUser.Value) : false
return databaseCache[ClientId]
}
async getClientByDiscord(clientId) {
var ClientId = await this.Server.DB.metaService.reversePersistentMeta('discord_id', clientId)
var discordUser = ClientId ? await this.Server.DB.metaService.getPersistentMeta('discord_user', ClientId) : false
var Client = ClientId ? await this.Server.DB.getClient(ClientId.ClientId) : false
return {...discordUser, ...Client}
}
censorIp(string) {
return string.replace(new RegExp(/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\:?([0-9]{1,5})?/g), '**[redacted]**')
.replace(new RegExp(/\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b/g), '**[redacted]**')
}
async onCommand(msg) {
try {
var ClientId = await this.Server.DB.metaService.reversePersistentMeta('discord_id', msg.author.id)
var Client = ClientId ? await this.Server.DB.getClient(ClientId.ClientId) : false
if (!discordUsers[msg.author.id.toString()]) {
discordUsers[msg.author.id.toString()] = {}
}
var user = discordUsers[msg.author.id.toString()]
if (user.lastMatches) {
msg.content = msg.content.replace(new RegExp(/#([0-9]+)/g), (n) => {
var num = Math.max(parseInt(n.substr(1)), 1) - 1
if (user.lastMatches[num]) {
return `@${user.lastMatches[num].ClientId}`
}
return n
})
}
var args = msg.content.substr(1).split(/\s+/g)
var buffer = []
if (this.commands[args[0].toLocaleLowerCase()]) {
msg.author.tell = (text) => {
let embed = new Discord.MessageEmbed()
.setColor(colors[Utils.getRandomInt(0, colors.length)])
.addField('\u200B', `${text.substr(0, 1000)}`, true)
trySend(msg.channel, embed)
}
this.commands[args[0].toLocaleLowerCase()](msg, user, args)
return
}
var Player = {
PermissionLevel: 0,
discordUser: msg.author.id,
ClientId: 0,
inGame: false,
Tell: (msg) => {
buffer.push(this.censorIp(Utils.stripString(msg.toString())))
}
}
Client && (Player = {...Player, ...Client})
var end = () => {
try {
let embed = new Discord.MessageEmbed()
.setColor(colors[Utils.getRandomInt(0, colors.length)])
.addField('\u200B', `${buffer.join('\n').substr(0, 1000)}`, true)
trySend(msg.channel, embed)
}
catch (e) {}
}
var executedMiddleware = await this.Manager.Commands.executeMiddleware(args[0], Player, args)
if (await this.Manager.Commands.execute(args[0], Player, args)) {
end()
return
}
var command = Utils.getCommand(this.Manager.commands, args[0])
switch (true) {
case (!this.Manager.commands[command]):
case (this.Manager.commands[command].gameTypeExclusions && this.Manager.commands[command].gameTypeExclusions.includes(this.Server.Gametype)):
!executedMiddleware && Player.Tell(Localization['COMMAND_NOT_FOUND'])
end()
return
case (this.Manager.commands[command].inGame || this.Manager.commands[command].inGame == undefined):
Player.Tell(Localization['COMMAND_ENV_ERROR'])
end()
return
case (Player.PermissionLevel < Permissions.Levels[this.Manager.commands[command].Permission]):
Player.Tell(Localization['COMMAND_FORBIDDEN'])
end()
return
case (args.length - 1 < this.Manager.commands[command].ArgumentLength):
Player.Tell(Localization['COMMAND_ARGUMENT_ERROR'])
Player.Tell(Utils.formatString(Localization['COMMAND_COMMAND_USAGE'], {
prefix: config.commandPrefixes[0],
usage: Localization[`USAGE_${command.toLocaleUpperCase()}`]
}))
end()
return
}
await this.Manager.commands[command].callback(Player, args, false)
end()
}
catch (e) {}
}
}
module.exports = Plugin