const moment = require('moment') const rp = require('request-promise') const UUID = require('uuid-1345') const translation = require("./translation").translation(); module.exports.server = function (serv) { serv.ban = (uuid, reason) => { serv.bannedPlayers[uuid] = { time: +moment(), reason: reason || translation.defaults.ban } } serv.banIP = (IP, reason) => { serv.bannedIPs[IP] = { time: +moment(), reason: reason || translation.defaults.banIp } Object.keys(serv.players) .filter(uuid => serv.players[uuid]._client.socket.remoteAddress === IP) .forEach(uuid => serv.players[uuid].kick(serv.bannedIPs[serv.players[uuid]._client.socket.remoteAddress].reason)) } function uuidInParts (plainUUID) { return UUID.stringify(UUID.parse(plainUUID)) } serv.getUUIDFromUsername = username => { return rp('https://api.mojang.com/users/profiles/minecraft/' + username) .then((body) => { if (!body) throw new Error('username not found') return uuidInParts(JSON.parse(body).id) }) .catch(err => { throw err }) } serv.banUsername = (username, reason) => { return serv.getUUIDFromUsername(username) .then(uuid => serv.ban(uuid, reason)) } serv.pardonUsername = (username) => { return serv.getUUIDFromUsername(username) .then(pardon) } serv.pardonIP = (IP) => { return serv.bannedIPs[IP] ? delete serv.bannedIPs[IP] : false } function pardon (uuid) { if (serv.bannedPlayers[uuid]) { delete serv.bannedPlayers[uuid] return true } return false } serv.bannedPlayers = {} serv.bannedIPs = {} } module.exports.player = function (player, serv) { player.kick = (reason) => player._client.end(reason || translation.commands.kick) player.ban = reason => { reason = reason || translation.commands.ban player.kick(reason) const uuid = player.uuid serv.ban(uuid, reason) } player.banIP = reason => { reason = reason || translation.commands.banIp player.kick(reason) serv.banIP(player._client.socket.remoteAddress) } player.pardon = () => serv.pardon(player.uuid) player.commands.add({ base: 'kick', info: 'to kick a player', usage: '/kick [reason]', permissions: "commands.kick", parse (str) { if (!str.match(/([a-zA-Z0-9_]+)(?: (.*))?/)) { return false } const parts = str.split(' ') return { username: parts.shift(), reason: parts.join(' ') } }, action ({ username, reason }) { const kickPlayer = serv.getPlayer(username) if (!kickPlayer) { player.chat(translation.errors.playerExists.replace("%1", username)) } else { kickPlayer.kick(reason) kickPlayer.emit('kicked', player, reason) } } }) player.commands.add({ base: 'ban', info: 'to ban a player', usage: '/ban [reason]', permissions: "commands.ban", parse (str) { if (!str.match(/([a-zA-Z0-9_]+)(?: (.*))?/)) { return false } const parts = str.split(' ') return { username: parts.shift(), reason: parts.join(' ') } }, action ({ username, reason }) { const banPlayer = serv.getPlayer(username) if (!banPlayer) { serv.banUsername(username, reason) .then(() => { serv.emit('banned', player, username, reason) player.chat(translation.commands.banB.replace("%1",username)) }) .catch(err => { if (err) { // This tricks eslint player.chat(translation.errros.playerExists.replace("%1",username)) } }) } else { banPlayer.ban(reason) serv.emit('banned', player, username, reason) } } }) player.commands.add({ base: 'ban-ip', info: 'bans a specific IP', usage: '/ban-ip [reason]', permissions: "commands.banip", parse (str) { const argv = str.split(' ') if (argv.length < 1) return return { IP: argv.shift(), reason: argv.shift() } }, action ({ IP, reason }) { serv.banIP(IP, reason) player.chat('' + IP + ' was IP banned') } }) player.commands.add({ base: 'pardon-ip', info: 'to pardon a player by ip', usage: '/pardon-ip ', permissions: "commands.pardon", action (IP) { const result = serv.pardonIP(IP) player.chat(result ? IP + ' was IP pardoned' : IP + ' is not banned') } }) player.commands.add({ base: 'pardon', info: 'to pardon a player', usage: '/pardon ', permissions: "commands.pardon", parse (str) { if (!str.match(/([a-zA-Z0-9_]+)/)) { return false } return str }, action (nick) { serv.pardonUsername(nick) .then(() => player.chat(nick + ' is unbanned')) .catch(err => { if (err) { // This tricks eslint player.chat(nick + ' is not banned') } }) } }) player.commands.add({ base: 'op', info: 'op any player', usage: '/op ', op: true, parse (str) { if (!str.match(/([a-zA-Z0-9_]+)/)) return false return str }, action (username) { const user = serv.getPlayer(username) if (!user) return 'That player is not on the server.' user.op = true player.chat(username + ' is opped') } }) player.commands.add({ base: 'deop', info: 'deop any player', usage: '/deop ', op: true, parse (str) { if (!str.match(/([a-zA-Z0-9_]+)/)) return false return str }, action (username) { const user = serv.getPlayer(username) if (!user) return 'That player is not on the server.' user.op = false player.chat(username + ' is deopped') } }) }