mirror of
https://github.com/danbulant/flying-squid
synced 2026-07-07 04:00:46 +00:00
Add permissions and few other fixes
This commit is contained in:
parent
1b519708bc
commit
e4aacc4351
23 changed files with 314 additions and 102 deletions
BIN
.DS_Store
vendored
Normal file
BIN
.DS_Store
vendored
Normal file
Binary file not shown.
|
|
@ -1,18 +0,0 @@
|
||||||
version: 2
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
parallelism: 2
|
|
||||||
docker:
|
|
||||||
- image: circleci/node:10
|
|
||||||
steps:
|
|
||||||
- checkout
|
|
||||||
- restore_cache:
|
|
||||||
key: dependency-cache-{{ checksum "package.json" }}
|
|
||||||
- run: npm i
|
|
||||||
- save_cache:
|
|
||||||
key: dependency-cache-{{ checksum "package.json" }}
|
|
||||||
paths:
|
|
||||||
- ./node_modules
|
|
||||||
- run: npm run lint
|
|
||||||
- run: npm test
|
|
||||||
4
app.js
Normal file → Executable file
4
app.js
Normal file → Executable file
|
|
@ -22,4 +22,6 @@ module.exports = mcServer.createMCServer(settings)
|
||||||
|
|
||||||
process.on('unhandledRejection', err => {
|
process.on('unhandledRejection', err => {
|
||||||
console.log(err.stack)
|
console.log(err.stack)
|
||||||
})
|
});
|
||||||
|
|
||||||
|
console.log("MC Server running as " + process.pid);
|
||||||
1
config/permissions.json
Normal file
1
config/permissions.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"groups":{"default":{"perms":["world.*","chat.*", "info.*"],"noPerms":["op.*"]}, "admin":{"noPerms": [], "perms": ["*.*"], "prefix": "&4[Admin]&r"}},"players":{"TechmandanCZ": {"group":"admin"}}}
|
||||||
25
config/translation.json
Normal file
25
config/translation.json
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"disconnected": "&ePlayer %1 disconnected",
|
||||||
|
"disconnectedPrefix": true,
|
||||||
|
"particles": "Emitting %1 particles (count: %2, size: %3)"
|
||||||
|
},
|
||||||
|
"defaults": {
|
||||||
|
"ban": "You've been banned from this server!",
|
||||||
|
"banIp": "Your IP have been banned from this server!"
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"ban": "You were banned from this server!",
|
||||||
|
"banB": "Player %1 was banned from this server!",
|
||||||
|
"kick": "You were kicked from this server!",
|
||||||
|
"kickB": "Player %1 was kicked!"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"perms": "You don't have permission to do that!",
|
||||||
|
"maxParticle": "You can't spawn more than %1 particles",
|
||||||
|
"playerExists": "Player %1 is not on this server"
|
||||||
|
},
|
||||||
|
"info": {
|
||||||
|
"particle": "Emit a particle at position"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
const mcServer = require('flying-squid')
|
|
||||||
|
|
||||||
mcServer.createMCServer({
|
|
||||||
'motd': 'A Minecraft Server \nRunning flying-squid',
|
|
||||||
'port': 25565,
|
|
||||||
'max-players': 10,
|
|
||||||
'online-mode': true,
|
|
||||||
'logging': true,
|
|
||||||
'gameMode': 1,
|
|
||||||
'generation': {
|
|
||||||
'name': 'diamond_square',
|
|
||||||
'options': {
|
|
||||||
'worldHeight': 80
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'kickTimeout': 10000,
|
|
||||||
'plugins': {
|
|
||||||
|
|
||||||
},
|
|
||||||
'modpe': false,
|
|
||||||
'view-distance': 10
|
|
||||||
})
|
|
||||||
51
src/index.js
51
src/index.js
|
|
@ -1,14 +1,15 @@
|
||||||
const mc = require('minecraft-protocol')
|
const mc = require('minecraft-protocol');
|
||||||
const EventEmitter = require('events').EventEmitter
|
const EventEmitter = require('events').EventEmitter;
|
||||||
const path = require('path')
|
const path = require('path');
|
||||||
const requireIndex = require('./lib/requireindex')
|
const requireIndex = require('./lib/requireindex');
|
||||||
const supportedVersions = require('./lib/version').supportedVersions
|
const supportedVersions = require('./lib/version').supportedVersions;
|
||||||
require('emit-then').register()
|
require('emit-then').register();
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'dev') {
|
if (process.env.NODE_ENV === 'dev') {
|
||||||
require('longjohn')
|
require('longjohn')
|
||||||
}
|
}
|
||||||
|
|
||||||
const supportFeature = require('./lib/supportFeature')
|
const supportFeature = require('./lib/supportFeature');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createMCServer: createMCServer,
|
createMCServer: createMCServer,
|
||||||
|
|
@ -19,36 +20,40 @@ module.exports = {
|
||||||
UserError: require('./lib/user_error'),
|
UserError: require('./lib/user_error'),
|
||||||
portal_detector: require('./lib/portal_detector'),
|
portal_detector: require('./lib/portal_detector'),
|
||||||
supportedVersions
|
supportedVersions
|
||||||
}
|
};
|
||||||
|
|
||||||
function createMCServer (options) {
|
function createMCServer (options) {
|
||||||
options = options || {}
|
options = options || {};
|
||||||
const mcServer = new MCServer()
|
const mcServer = new MCServer();
|
||||||
mcServer.connect(options)
|
mcServer.connect(options);
|
||||||
return mcServer
|
return mcServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MCServer extends EventEmitter {
|
class MCServer extends EventEmitter {
|
||||||
constructor () {
|
constructor () {
|
||||||
super()
|
super();
|
||||||
this._server = null
|
this._server = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect (options) {
|
connect (options) {
|
||||||
const version = require('minecraft-data')(options.version).version
|
const version = require('minecraft-data')(options.version).version;
|
||||||
if (supportedVersions.indexOf(version.majorVersion) === -1) {
|
if (supportedVersions.indexOf(version.majorVersion) === -1) {
|
||||||
throw new Error(`Version ${version.minecraftVersion} is not supported.`)
|
throw new Error(`Version ${version.minecraftVersion} is not supported.`);
|
||||||
}
|
}
|
||||||
this.supportFeature = feature => supportFeature(feature, version.majorVersion)
|
this.supportFeature = feature => supportFeature(feature, version.majorVersion);
|
||||||
|
|
||||||
const plugins = requireIndex(path.join(__dirname, 'lib', 'plugins'))
|
const plugins = requireIndex(path.join(__dirname, 'lib', 'plugins'));
|
||||||
this._server = mc.createServer(options)
|
this._server = mc.createServer(options)
|
||||||
|
|
||||||
Object.keys(plugins)
|
Object.keys(plugins)
|
||||||
.filter(pluginName => plugins[pluginName].server !== undefined)
|
.filter(pluginName => plugins[pluginName].server !== undefined)
|
||||||
.forEach(pluginName => plugins[pluginName].server(this, options))
|
.forEach(pluginName => plugins[pluginName].server(this, options));
|
||||||
if (options.logging === true) this.createLog()
|
|
||||||
this._server.on('error', error => this.emit('error', error))
|
if (options.logging === true) this.createLog();
|
||||||
this._server.on('listening', () => this.emit('listening', this._server.socketServer.address().port))
|
|
||||||
this.emit('asap')
|
this._server.on('error', error => this.emit('error', error));
|
||||||
|
this._server.on('listening', () => this.emit('listening', this._server.socketServer.address().port));
|
||||||
|
|
||||||
|
this.emit('init')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
const permissions = require("./plugins/permissions").permissions();
|
||||||
|
|
||||||
class Command {
|
class Command {
|
||||||
constructor (params, parent, hash) {
|
constructor (params, parent, hash) {
|
||||||
this.params = params
|
this.params = params
|
||||||
|
|
@ -18,18 +20,19 @@ class Command {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
async use (command, op = true) {
|
async use (command, op = true, username = null) {
|
||||||
let res = this.find(command)
|
let res = this.find(command)
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
let [com, pars] = res
|
let [com, pars] = res
|
||||||
if (com.params.op && !op) return 'You do not have permission to use this command'
|
if (!op && com.params.permission && !permissions.hasPermission(username, com.params.permission)) return 'You do not have permission to use this command';
|
||||||
|
if (com.params.op && !op) return 'You do not have permission to use this command';
|
||||||
const parse = com.params.parse
|
const parse = com.params.parse
|
||||||
if (parse) {
|
if (parse) {
|
||||||
if (typeof parse === 'function') {
|
if (typeof parse === 'function') {
|
||||||
pars = parse(pars)
|
pars = parse(pars)
|
||||||
if (pars === false) {
|
if (pars === false) {
|
||||||
return com.params.usage ? 'Usage: ' + com.params.usage : 'Bad syntax'
|
return com.params.usage ? 'Usage: ' + com.params.usage : 'Bad syntax';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pars = pars.match(parse)
|
pars = pars.match(parse)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
const permissions = require("./permissions").permissions();
|
||||||
|
|
||||||
module.exports.server = function (serv) {
|
module.exports.server = function (serv) {
|
||||||
serv.broadcast = (message, { whitelist = serv.players, blacklist = [], system = false } = {}) => {
|
serv.broadcast = (message, { whitelist = serv.players, blacklist = [], system = false } = {}) => {
|
||||||
if (whitelist.type === 'player') whitelist = [whitelist]
|
if (whitelist.type === 'player') whitelist = [whitelist]
|
||||||
|
|
@ -122,11 +124,15 @@ module.exports.server = function (serv) {
|
||||||
module.exports.player = function (player, serv) {
|
module.exports.player = function (player, serv) {
|
||||||
player._client.on('chat', ({ message } = {}) => {
|
player._client.on('chat', ({ message } = {}) => {
|
||||||
if (message[0] === '/') {
|
if (message[0] === '/') {
|
||||||
|
if(!permissions.hasPermission(player.username, "commands.use"))return player.chat("You don't have permission to use commands");
|
||||||
|
|
||||||
player.behavior('command', { command: message.slice(1) }, ({ command }) => player.handleCommand(command))
|
player.behavior('command', { command: message.slice(1) }, ({ command }) => player.handleCommand(command))
|
||||||
} else {
|
} else {
|
||||||
|
if(!permissions.hasPermission(player.username, "chat.send"))return player.chat("You don't have permission to use chat");
|
||||||
|
|
||||||
player.behavior('chat', {
|
player.behavior('chat', {
|
||||||
message: message,
|
message: message,
|
||||||
prefix: '<' + player.username + '> ',
|
prefix: permissions.getPrefix(player.username) + player.username + permissions.getSuffix(player.username) + permissions.getSeparator(),
|
||||||
text: message,
|
text: message,
|
||||||
whitelist: serv.players,
|
whitelist: serv.players,
|
||||||
blacklist: []
|
blacklist: []
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
const UserError = require('flying-squid').UserError
|
const UserError = require('flying-squid').UserError
|
||||||
|
const permissions = require("./permissions");
|
||||||
|
|
||||||
module.exports.player = function (player, serv, { version }) {
|
module.exports.player = function (player, serv, { version }) {
|
||||||
player.commands.add({
|
player.commands.add({
|
||||||
base: 'help',
|
base: 'help',
|
||||||
info: 'to show all commands',
|
info: 'to show all commands',
|
||||||
usage: '/help [command]',
|
usage: '/help [command]',
|
||||||
|
permission: "commands.help",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const params = str.split(' ')
|
const params = str.split(' ')
|
||||||
const page = parseInt(params[params.length - 1])
|
const page = parseInt(params[params.length - 1])
|
||||||
|
|
@ -24,7 +26,7 @@ module.exports.player = function (player, serv, { version }) {
|
||||||
|
|
||||||
if (found.length === 0) { // None found
|
if (found.length === 0) { // None found
|
||||||
return 'Could not find any matches'
|
return 'Could not find any matches'
|
||||||
} else if (found.length === 1) { // Single command found, giev info on command
|
} else if (found.length === 1) { // Single command found, give info on command
|
||||||
const cmd = hash[found[0]]
|
const cmd = hash[found[0]]
|
||||||
const usage = (cmd.params && cmd.params.usage) || cmd.base
|
const usage = (cmd.params && cmd.params.usage) || cmd.base
|
||||||
const info = (cmd.params && cmd.params.info) || 'No info'
|
const info = (cmd.params && cmd.params.info) || 'No info'
|
||||||
|
|
@ -69,6 +71,7 @@ module.exports.player = function (player, serv, { version }) {
|
||||||
base: 'modpe',
|
base: 'modpe',
|
||||||
info: 'for modpe commands',
|
info: 'for modpe commands',
|
||||||
usage: '/modpe <params>',
|
usage: '/modpe <params>',
|
||||||
|
permissions: "mod.pe",
|
||||||
parse (str) { return str || false },
|
parse (str) { return str || false },
|
||||||
action (str) {
|
action (str) {
|
||||||
player.emit('modpe', str)
|
player.emit('modpe', str)
|
||||||
|
|
@ -79,8 +82,9 @@ module.exports.player = function (player, serv, { version }) {
|
||||||
base: 'version',
|
base: 'version',
|
||||||
info: 'to get version of the server',
|
info: 'to get version of the server',
|
||||||
usage: '/version',
|
usage: '/version',
|
||||||
|
permissions: "info.version",
|
||||||
action () {
|
action () {
|
||||||
return 'This server is running flying-squid version ' + version
|
return 'This server is running nodecraft version ' + version
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -88,8 +92,9 @@ module.exports.player = function (player, serv, { version }) {
|
||||||
base: 'bug',
|
base: 'bug',
|
||||||
info: 'to bug report',
|
info: 'to bug report',
|
||||||
usage: '/bug',
|
usage: '/bug',
|
||||||
|
permissions: "info.bug",
|
||||||
action () {
|
action () {
|
||||||
return 'Report bugs / issues here: https://github.com/PrismarineJS/flying-squid/issues'
|
return 'Report bugs / issues here: https://github.com/PrismarineJS/flying-squid/issues unless related to permissions, in which case contact developer TechamdanCZ#0135 on discord.'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -109,7 +114,7 @@ module.exports.player = function (player, serv, { version }) {
|
||||||
|
|
||||||
player.handleCommand = async (str) => {
|
player.handleCommand = async (str) => {
|
||||||
try {
|
try {
|
||||||
const res = await player.commands.use(str, player.op)
|
const res = await player.commands.use(str, player.op, player.username)
|
||||||
if (res) player.chat(serv.color.red + res)
|
if (res) player.chat(serv.color.red + res)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.userError) player.chat(serv.color.red + 'Error: ' + err.message)
|
if (err.userError) player.chat(serv.color.red + 'Error: ' + err.message)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const Vec3 = require('vec3').Vec3
|
const Vec3 = require('vec3').Vec3
|
||||||
|
const permissions = require("./permissions").permissions();
|
||||||
|
|
||||||
module.exports.player = function (player, serv) {
|
module.exports.player = function (player, serv) {
|
||||||
function cancelDig ({ position, block }) {
|
function cancelDig ({ position, block }) {
|
||||||
|
|
@ -6,6 +7,7 @@ module.exports.player = function (player, serv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
player._client.on('block_dig', async ({ location, status, face }) => {
|
player._client.on('block_dig', async ({ location, status, face }) => {
|
||||||
|
if(!permissions.hasPermission(player.username, "world.dig"))return;
|
||||||
let pos = new Vec3(location.x, location.y, location.z)
|
let pos = new Vec3(location.x, location.y, location.z)
|
||||||
|
|
||||||
const directionVector = directionToVector[face]
|
const directionVector = directionToVector[face]
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ module.exports.server = function (serv, settings) {
|
||||||
if (serv.plugins[p].server) f.call(serv.plugins[p], serv, settings)
|
if (serv.plugins[p].server) f.call(serv.plugins[p], serv, settings)
|
||||||
})
|
})
|
||||||
|
|
||||||
serv.on('asap', () => {
|
serv.on('ready', () => {
|
||||||
Object.keys(serv.plugins).map(p => serv.log('[PLUGINS] Loaded "' + serv.plugins[p].name + '"'))
|
Object.keys(serv.plugins).map(p => serv.log('[PLUGINS] Loaded "' + serv.plugins[p].name + '"'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
const once = require('event-promise')
|
const once = require('event-promise')
|
||||||
|
const permissions = require("./permissions").permissions();
|
||||||
|
const translation = require("./translation").translation();
|
||||||
|
|
||||||
module.exports.server = function (serv) {
|
module.exports.server = function (serv) {
|
||||||
serv.quit = async (reason = 'Going down') => {
|
serv.quit = async (reason = 'Going down') => {
|
||||||
|
|
@ -18,7 +20,10 @@ module.exports.player = function (player, serv) {
|
||||||
|
|
||||||
player._client.on('end', () => {
|
player._client.on('end', () => {
|
||||||
if (player && player.username) {
|
if (player && player.username) {
|
||||||
serv.broadcast(serv.color.yellow + player.username + ' quit the game.')
|
var user = player.username;
|
||||||
|
if(translation.server.disconnectedPrefix) user = permissions.getPrefix(player.username) + player.username + permissions.getSuffix(player.username);
|
||||||
|
|
||||||
|
serv.broadcast(translation.server.disconnected.replace("%1", user));
|
||||||
player._writeOthers('player_info', {
|
player._writeOthers('player_info', {
|
||||||
action: 4,
|
action: 4,
|
||||||
data: [{
|
data: [{
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
const moment = require('moment')
|
const moment = require('moment')
|
||||||
const rp = require('request-promise')
|
const rp = require('request-promise')
|
||||||
const UUID = require('uuid-1345')
|
const UUID = require('uuid-1345')
|
||||||
|
const translation = require("./translation").translation();
|
||||||
|
|
||||||
module.exports.server = function (serv) {
|
module.exports.server = function (serv) {
|
||||||
serv.ban = (uuid, reason) => {
|
serv.ban = (uuid, reason) => {
|
||||||
serv.bannedPlayers[uuid] = {
|
serv.bannedPlayers[uuid] = {
|
||||||
time: +moment(),
|
time: +moment(),
|
||||||
reason: reason || 'Your account is banned!'
|
reason: reason || translation.defaults.ban
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serv.banIP = (IP, reason) => {
|
serv.banIP = (IP, reason) => {
|
||||||
serv.bannedIPs[IP] = {
|
serv.bannedIPs[IP] = {
|
||||||
time: +moment(),
|
time: +moment(),
|
||||||
reason: reason || 'Your IP is banned!'
|
reason: reason || translation.defaults.banIp
|
||||||
}
|
}
|
||||||
Object.keys(serv.players)
|
Object.keys(serv.players)
|
||||||
.filter(uuid => serv.players[uuid]._client.socket.remoteAddress === IP)
|
.filter(uuid => serv.players[uuid]._client.socket.remoteAddress === IP)
|
||||||
|
|
@ -59,17 +60,17 @@ module.exports.server = function (serv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.player = function (player, serv) {
|
module.exports.player = function (player, serv) {
|
||||||
player.kick = (reason = 'You were kicked!') =>
|
player.kick = (reason) =>
|
||||||
player._client.end(reason)
|
player._client.end(reason || translation.commands.kick)
|
||||||
|
|
||||||
player.ban = reason => {
|
player.ban = reason => {
|
||||||
reason = reason || 'You were banned!'
|
reason = reason || translation.commands.ban
|
||||||
player.kick(reason)
|
player.kick(reason)
|
||||||
const uuid = player.uuid
|
const uuid = player.uuid
|
||||||
serv.ban(uuid, reason)
|
serv.ban(uuid, reason)
|
||||||
}
|
}
|
||||||
player.banIP = reason => {
|
player.banIP = reason => {
|
||||||
reason = reason || 'You were IP banned!'
|
reason = reason || translation.commands.banIp
|
||||||
player.kick(reason)
|
player.kick(reason)
|
||||||
serv.banIP(player._client.socket.remoteAddress)
|
serv.banIP(player._client.socket.remoteAddress)
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +81,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'kick',
|
base: 'kick',
|
||||||
info: 'to kick a player',
|
info: 'to kick a player',
|
||||||
usage: '/kick <player> [reason]',
|
usage: '/kick <player> [reason]',
|
||||||
op: true,
|
permissions: "commands.kick",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
if (!str.match(/([a-zA-Z0-9_]+)(?: (.*))?/)) { return false }
|
if (!str.match(/([a-zA-Z0-9_]+)(?: (.*))?/)) { return false }
|
||||||
const parts = str.split(' ')
|
const parts = str.split(' ')
|
||||||
|
|
@ -92,7 +93,7 @@ module.exports.player = function (player, serv) {
|
||||||
action ({ username, reason }) {
|
action ({ username, reason }) {
|
||||||
const kickPlayer = serv.getPlayer(username)
|
const kickPlayer = serv.getPlayer(username)
|
||||||
if (!kickPlayer) {
|
if (!kickPlayer) {
|
||||||
player.chat(username + ' is not on this server!')
|
player.chat(translation.errors.playerExists.replace("%1", username))
|
||||||
} else {
|
} else {
|
||||||
kickPlayer.kick(reason)
|
kickPlayer.kick(reason)
|
||||||
kickPlayer.emit('kicked', player, reason)
|
kickPlayer.emit('kicked', player, reason)
|
||||||
|
|
@ -104,7 +105,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'ban',
|
base: 'ban',
|
||||||
info: 'to ban a player',
|
info: 'to ban a player',
|
||||||
usage: '/ban <player> [reason]',
|
usage: '/ban <player> [reason]',
|
||||||
op: true,
|
permissions: "commands.ban",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
if (!str.match(/([a-zA-Z0-9_]+)(?: (.*))?/)) { return false }
|
if (!str.match(/([a-zA-Z0-9_]+)(?: (.*))?/)) { return false }
|
||||||
const parts = str.split(' ')
|
const parts = str.split(' ')
|
||||||
|
|
@ -120,11 +121,11 @@ module.exports.player = function (player, serv) {
|
||||||
serv.banUsername(username, reason)
|
serv.banUsername(username, reason)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
serv.emit('banned', player, username, reason)
|
serv.emit('banned', player, username, reason)
|
||||||
player.chat(username + ' was banned')
|
player.chat(translation.commands.banB.replace("%1",username))
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
if (err) { // This tricks eslint
|
if (err) { // This tricks eslint
|
||||||
player.chat(username + ' is not a valid player!')
|
player.chat(translation.errros.playerExists.replace("%1",username))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -138,7 +139,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'ban-ip',
|
base: 'ban-ip',
|
||||||
info: 'bans a specific IP',
|
info: 'bans a specific IP',
|
||||||
usage: '/ban-ip <ip> [reason]',
|
usage: '/ban-ip <ip> [reason]',
|
||||||
op: true,
|
permissions: "commands.banip",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const argv = str.split(' ')
|
const argv = str.split(' ')
|
||||||
if (argv.length < 1) return
|
if (argv.length < 1) return
|
||||||
|
|
@ -158,7 +159,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'pardon-ip',
|
base: 'pardon-ip',
|
||||||
info: 'to pardon a player by ip',
|
info: 'to pardon a player by ip',
|
||||||
usage: '/pardon-ip <ip>',
|
usage: '/pardon-ip <ip>',
|
||||||
op: true,
|
permissions: "commands.pardon",
|
||||||
action (IP) {
|
action (IP) {
|
||||||
const result = serv.pardonIP(IP)
|
const result = serv.pardonIP(IP)
|
||||||
player.chat(result ? IP + ' was IP pardoned' : IP + ' is not banned')
|
player.chat(result ? IP + ' was IP pardoned' : IP + ' is not banned')
|
||||||
|
|
@ -169,7 +170,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'pardon',
|
base: 'pardon',
|
||||||
info: 'to pardon a player',
|
info: 'to pardon a player',
|
||||||
usage: '/pardon <player>',
|
usage: '/pardon <player>',
|
||||||
op: true,
|
permissions: "commands.pardon",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
if (!str.match(/([a-zA-Z0-9_]+)/)) { return false }
|
if (!str.match(/([a-zA-Z0-9_]+)/)) { return false }
|
||||||
return str
|
return str
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const Vec3 = require('vec3').Vec3
|
const Vec3 = require('vec3').Vec3
|
||||||
|
const translation = require("./translation").translation();
|
||||||
|
|
||||||
module.exports.server = function (serv) {
|
module.exports.server = function (serv) {
|
||||||
serv.emitParticle = (particle, world, position, { whitelist, blacklist = [], radius = 32, longDistance = true, size = new Vec3(1, 1, 1), count = 1 } = {}) => {
|
serv.emitParticle = (particle, world, position, { whitelist, blacklist = [], radius = 32, longDistance = true, size = new Vec3(1, 1, 1), count = 1 } = {}) => {
|
||||||
|
|
@ -27,9 +28,9 @@ module.exports.server = function (serv) {
|
||||||
module.exports.player = function (player, serv) {
|
module.exports.player = function (player, serv) {
|
||||||
player.commands.add({
|
player.commands.add({
|
||||||
base: 'particle',
|
base: 'particle',
|
||||||
info: 'emit a particle at a position',
|
info: translation.info.particle,
|
||||||
usage: '/particle <id> [amount] [<sizeX> <sizeY> <sizeZ>]',
|
usage: '/particle <id> [amount] [<sizeX> <sizeY> <sizeZ>]',
|
||||||
op: true,
|
permission: "world.emitParticle",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const results = str.match(/(\d+)(?: (\d+))?(?: (\d+))?(?: (\d+))?(?: (\d+))?(?: (\d+))?/)
|
const results = str.match(/(\d+)(?: (\d+))?(?: (\d+))?(?: (\d+))?(?: (\d+))?(?: (\d+))?/)
|
||||||
if (!results) return false
|
if (!results) return false
|
||||||
|
|
@ -41,10 +42,10 @@ module.exports.player = function (player, serv) {
|
||||||
},
|
},
|
||||||
action ({ particle, amount, size }) {
|
action ({ particle, amount, size }) {
|
||||||
if (amount >= 100000) {
|
if (amount >= 100000) {
|
||||||
player.chat('You cannot emit more than 100,000 particles!')
|
player.chat(translation.errors.maxParticle)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
player.chat('Emitting "' + particle + '" (count: ' + amount + ', size: ' + size.toString() + ')')
|
player.chat(translation.server.particles.replace("%1", particle).replace("%2", amount).replace("%3", size.toString()));
|
||||||
serv.emitParticle(particle, player.world, player.position, { count: amount, size: size })
|
serv.emitParticle(particle, player.world, player.position, { count: amount, size: size })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
152
src/lib/plugins/permissions.js
Normal file
152
src/lib/plugins/permissions.js
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
module.exports.player = (player, serv)=>{
|
||||||
|
player.commands.add({
|
||||||
|
base: "perms",
|
||||||
|
info: "Permission commands",
|
||||||
|
usage: "/perms ?",
|
||||||
|
permissions: "commands.permissions",
|
||||||
|
action (cmd) {
|
||||||
|
var c = cmd.substr(cmd.indexOf(" ") == -1 ? 0 : cmd.indexOf(" "));
|
||||||
|
|
||||||
|
switch(c){
|
||||||
|
case "?":
|
||||||
|
case "h":
|
||||||
|
case "help":
|
||||||
|
player.chat("Help to be done");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "Command couldn't be found. Try /perms ?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
player.commands.add({
|
||||||
|
base: "broadcast",
|
||||||
|
info: "Broadcast message",
|
||||||
|
usage: "/broadcast <message>",
|
||||||
|
permission: "commands.broadcast",
|
||||||
|
action(cmd){
|
||||||
|
serv.broadcast(cmd);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.permissions = ()=>{
|
||||||
|
if(!fs.existsSync(__dirname + "/../../../config/permissions.json")){
|
||||||
|
console.log("Permission config file doesn't exist, creating one");
|
||||||
|
var defaultPerms = {
|
||||||
|
groups: {
|
||||||
|
default: {
|
||||||
|
perms: ["world.*", "chat.*", "info.*"],
|
||||||
|
noPerms: ["world.difficulty", "world.changeGamemode"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
players: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(__dirname + "/../../../config/permissions.json", JSON.stringify(defaultPerms, null, 2));
|
||||||
|
}
|
||||||
|
global.permissions = JSON.parse(fs.readFileSync(__dirname + "/../../../config/permissions.json", 'utf8'));
|
||||||
|
|
||||||
|
var permissions = {};
|
||||||
|
permissions.getSeparator = ()=>"> ";
|
||||||
|
permissions._getProperty = (player, property)=>{
|
||||||
|
var group = "default";
|
||||||
|
var perms = global.permissions;
|
||||||
|
|
||||||
|
if(perms.players[player]){
|
||||||
|
if(perms.players[player].group)group = perms.players[player].group;
|
||||||
|
if(perms.players[player][property])return perms.players[player][property];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!perms.groups[group]){
|
||||||
|
if(perms.groups.default)group = "default";
|
||||||
|
else throw Error("No default permission group. Cannot continue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return perms.groups[group][property] | "";
|
||||||
|
}
|
||||||
|
permissions.getPrefix = (player)=>{
|
||||||
|
return permissions._getProperty(player, "prefix");
|
||||||
|
}
|
||||||
|
permissions.getSuffix = (player)=>{
|
||||||
|
return permissions._getProperty(player, "suffix");
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions.hasPermission = (player, permission)=>{
|
||||||
|
var permArr = permission.split(".");
|
||||||
|
var group = "default";
|
||||||
|
var perms = global.permissions;
|
||||||
|
|
||||||
|
if(!perms.players)perms.players = {};
|
||||||
|
if(!perms.groups)perms.groups = {};
|
||||||
|
|
||||||
|
if(perms.players[player]){
|
||||||
|
if(perms.players[player].group)group = perms.players[player].group;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!perms.groups[group]){
|
||||||
|
if(perms.groups.default)group = "default";
|
||||||
|
else throw Error("No default permission group. Cannot continue.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowed = perms.groups[group].perms || [];
|
||||||
|
var hasPermission = false;
|
||||||
|
|
||||||
|
if(!Array.isArray(allowed)){
|
||||||
|
console.warn("perms in group " + group + " is of wrong type");
|
||||||
|
console.log(perms);
|
||||||
|
console.log(perms.groups[group]);
|
||||||
|
console.log(perms.groups[group].perms);
|
||||||
|
console.log(allowed);
|
||||||
|
allowed = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var perm of allowed){
|
||||||
|
var p = perm.split(".");
|
||||||
|
var isSame = true;
|
||||||
|
for(var i in p){
|
||||||
|
if(p[i] != permArr[i] && p[i] != "*"){
|
||||||
|
isSame = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isSame){
|
||||||
|
hasPermission = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var disallowed = perms.groups[group].noPerms || [];
|
||||||
|
|
||||||
|
if(!Array.isArray(disallowed)){
|
||||||
|
console.warn("noperms in group " + group + " is of wrong type");
|
||||||
|
disallowed = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var perm of disallowed){
|
||||||
|
var p = perm.split(".");
|
||||||
|
var isSame = true;
|
||||||
|
for(var i in p){
|
||||||
|
if(p[i] != permArr[i] && p[i] != "*"){
|
||||||
|
isSame = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isSame){
|
||||||
|
hasPermission = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions.loadState = ()=>{
|
||||||
|
global.permissions = fs.readFileSync(__dirname + "/../../../config/permissions.json", 'utf8');
|
||||||
|
return global.permissions;
|
||||||
|
}
|
||||||
|
permissions.saveState = ()=>{
|
||||||
|
return fs.writeSync(__dirname + "/../../../config/permissions.json", JSON.stringify(global.permission));
|
||||||
|
}
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
const Vec3 = require('vec3').Vec3
|
const Vec3 = require('vec3').Vec3
|
||||||
|
const permissions = require("./permissions").permissions();
|
||||||
const materialToSound = {
|
const materialToSound = {
|
||||||
undefined: 'stone',
|
undefined: 'stone',
|
||||||
'rock': 'stone',
|
'rock': 'stone',
|
||||||
|
|
@ -14,6 +14,8 @@ module.exports.player = function (player, serv, { version }) {
|
||||||
const blocks = require('minecraft-data')(version).blocks
|
const blocks = require('minecraft-data')(version).blocks
|
||||||
|
|
||||||
player._client.on('block_place', ({ direction, location } = {}) => {
|
player._client.on('block_place', ({ direction, location } = {}) => {
|
||||||
|
if(!permissions.hasPermission(player.username, "world.place"))return;
|
||||||
|
|
||||||
const heldItem = player.inventory.slots[36 + player.heldItemSlot]
|
const heldItem = player.inventory.slots[36 + player.heldItemSlot]
|
||||||
if (heldItem === undefined) return
|
if (heldItem === undefined) return
|
||||||
if (direction === -1 || heldItem.type === -1 || !blocks[heldItem.type]) return
|
if (direction === -1 || heldItem.type === -1 || !blocks[heldItem.type]) return
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ module.exports.player = function (player, serv) {
|
||||||
aliases: ['gm'],
|
aliases: ['gm'],
|
||||||
info: 'to change game mode',
|
info: 'to change game mode',
|
||||||
usage: '/gamemode <0-3>',
|
usage: '/gamemode <0-3>',
|
||||||
op: true,
|
permission: 'world.changeGamemode',
|
||||||
parse (str) {
|
parse (str) {
|
||||||
if (!str.match(/^([0-3])$/)) { return false }
|
if (!str.match(/^([0-3])$/)) { return false }
|
||||||
return parseInt(str)
|
return parseInt(str)
|
||||||
|
|
@ -32,7 +32,7 @@ module.exports.player = function (player, serv) {
|
||||||
aliases: ['diff'],
|
aliases: ['diff'],
|
||||||
info: 'Sets the difficulty level',
|
info: 'Sets the difficulty level',
|
||||||
usage: '/difficulty <difficulty>',
|
usage: '/difficulty <difficulty>',
|
||||||
op: true,
|
permission: "world.difficulty",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
if (!str.match(/^([0-3])$/)) { return false }
|
if (!str.match(/^([0-3])$/)) { return false }
|
||||||
return parseInt(str)
|
return parseInt(str)
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'kill',
|
base: 'kill',
|
||||||
info: 'Kill entities',
|
info: 'Kill entities',
|
||||||
usage: '/kill <selector>',
|
usage: '/kill <selector>',
|
||||||
op: true,
|
permission: "mod.kill",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
return str || false
|
return str || false
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ module.exports.player = function (player, serv, options) {
|
||||||
base: 'summon',
|
base: 'summon',
|
||||||
info: 'Summon an entity',
|
info: 'Summon an entity',
|
||||||
usage: '/summon <entity_name>',
|
usage: '/summon <entity_name>',
|
||||||
op: true,
|
permission: "world.summon",
|
||||||
action (name) {
|
action (name) {
|
||||||
if (Object.keys(serv.entities).length > options['max-entities']) { throw new UserError('Too many mobs !') }
|
if (Object.keys(serv.entities).length > options['max-entities']) { throw new UserError('Too many mobs !') }
|
||||||
const entity = entitiesByName[name]
|
const entity = entitiesByName[name]
|
||||||
|
|
@ -108,7 +108,7 @@ module.exports.player = function (player, serv, options) {
|
||||||
base: 'summonMany',
|
base: 'summonMany',
|
||||||
info: 'Summon many entities',
|
info: 'Summon many entities',
|
||||||
usage: '/summonMany <number> <entity_name>',
|
usage: '/summonMany <number> <entity_name>',
|
||||||
op: true,
|
permission: "world.summonMany",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const args = str.split(' ')
|
const args = str.split(' ')
|
||||||
if (args.length !== 2) { return false }
|
if (args.length !== 2) { return false }
|
||||||
|
|
@ -140,7 +140,7 @@ module.exports.player = function (player, serv, options) {
|
||||||
base: 'pile',
|
base: 'pile',
|
||||||
info: 'make a pile of entities',
|
info: 'make a pile of entities',
|
||||||
usage: '/pile <entities types>',
|
usage: '/pile <entities types>',
|
||||||
op: true,
|
permission: "world.pile",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const args = str.split(' ')
|
const args = str.split(' ')
|
||||||
if (args.length === 0) { return false }
|
if (args.length === 0) { return false }
|
||||||
|
|
@ -172,7 +172,7 @@ module.exports.player = function (player, serv, options) {
|
||||||
base: 'attach',
|
base: 'attach',
|
||||||
info: 'attach an entity on an other entity',
|
info: 'attach an entity on an other entity',
|
||||||
usage: '/attach <carrier> <attached>',
|
usage: '/attach <carrier> <attached>',
|
||||||
op: true,
|
permission: "world.attach",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const args = str.split(' ')
|
const args = str.split(' ')
|
||||||
if (args.length !== 2) { return false }
|
if (args.length !== 2) { return false }
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ module.exports.player = (player, serv) => {
|
||||||
aliases: ['tp'],
|
aliases: ['tp'],
|
||||||
info: 'to teleport a player',
|
info: 'to teleport a player',
|
||||||
usage: '/teleport [target player] <destination player or x> [y] [z]',
|
usage: '/teleport [target player] <destination player or x> [y] [z]',
|
||||||
op: true,
|
permission: "mod.tp",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
return str.match(/^(((.* )?~?-?\d* ~?-?\d* ~?-?\d*)|(.+ .+))$/) ? str.split(' ') : false
|
return str.match(/^(((.* )?~?-?\d* ~?-?\d* ~?-?\d*)|(.+ .+))$/) ? str.split(' ') : false
|
||||||
},
|
},
|
||||||
|
|
|
||||||
42
src/lib/plugins/translation.js
Normal file
42
src/lib/plugins/translation.js
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
const fs = require("fs");
|
||||||
|
module.exports = {};
|
||||||
|
|
||||||
|
module.exports.translation = ()=>{
|
||||||
|
|
||||||
|
if(global.trans)return global.trans;
|
||||||
|
|
||||||
|
var trans = {
|
||||||
|
server: {
|
||||||
|
disconnected: "&ePlayer %1 disconnected",
|
||||||
|
disconnectedPrefix: true,
|
||||||
|
particles: "Emitting %1 particles (count: %2, size: %3)"
|
||||||
|
},
|
||||||
|
defaults: {
|
||||||
|
ban: "You've been banned from this server!",
|
||||||
|
banIp: "Your IP have been banned from this server!",
|
||||||
|
},
|
||||||
|
commands: {
|
||||||
|
ban: "You were banned from this server!",
|
||||||
|
banB: "Player %1 was banned from this server!",
|
||||||
|
kick: "You were kicked from this server!",
|
||||||
|
kickB: "Player %1 was kicked!"
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
perms: "You don't have permission to do that!",
|
||||||
|
maxParticle: "You can't spawn more than %1 particles",
|
||||||
|
playerExists: "Player %1 is not on this server"
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
particle: "Emit a particle at position"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(!fs.existsSync(__dirname + "/../../../config/translation.json")){
|
||||||
|
fs.writeFileSync(__dirname + "/../../../config/translation.json", JSON.stringify(trans, null, 2));
|
||||||
|
} else {
|
||||||
|
trans = JSON.parse(fs.readFileSync(__dirname + "/../../../config/translation.json", "utf8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
global.trans = trans;
|
||||||
|
return trans;
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ module.exports.player = function (player, serv) {
|
||||||
base: 'weather',
|
base: 'weather',
|
||||||
info: 'Sets the weather.',
|
info: 'Sets the weather.',
|
||||||
usage: '/weather <clear|rain>',
|
usage: '/weather <clear|rain>',
|
||||||
op: true,
|
permission: "world.changeWeather",
|
||||||
parse (str) {
|
parse (str) {
|
||||||
const args = str.split(' ')
|
const args = str.split(' ')
|
||||||
if (args.length !== 1) { return false }
|
if (args.length !== 1) { return false }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue