From 843fa1ffa23e421b4894d6f88163b0182eecd194 Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Mon, 7 Dec 2015 01:21:45 -0800 Subject: [PATCH] Starting selectors (incomplete) --- src/lib/plugins/commands.js | 95 +++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/lib/plugins/commands.js b/src/lib/plugins/commands.js index 6f20440..8867c45 100644 --- a/src/lib/plugins/commands.js +++ b/src/lib/plugins/commands.js @@ -84,3 +84,98 @@ module.exports.player=function(player) { } } }; + +module.exports.server = function(serv) { + serv.selector = (type, opt) => { + if (['all', 'random', 'near', 'entity'].indexOf(type) == -1) + return new Error('serv.selector(): type must be either [all, random, near, or entity]'); + + var count = typeof opt.count != 'undefined' ? + count : + (type == 'all' || type == 'entity' ?serv.entities.length : 1); + var pos = opt.pos; + var sample; + if (type == 'all') sample = serv.players; + else if (type == 'random' || type == 'near') sample.players.filter(p => p.health != 0); + else if (type == 'entity') sample = Object.keys(serv.entities).map(k => serv.entities[k]); + + var checkOption = (val, compare) => { + var not = val[0] == '!'; + var v = val; + if (not) v = v.slice(1, v.length); + if (not && compare == v) return false; + if (!not && compare != v) return false; + return true; + } + + sample.filter(s => { + if ((opt.radius && s.position.distanceTo(pos) > opt.radius) || + (opt.minRadius && s.position.distanceTo(pos) < opt.minRadius) || + (opt.gameMode && s.gameMode != opt.gameMode) || + (opt.level && s.level > opt.level) || + (opt.minLevel && s.level < opt.minLevel) || + (opt.yaw && s.yaw > opt.yaw) || + (opt.minYaw && s.yaw < opt.minYaw) || + (opt.pitch && s.pitch > opt.pitch) || + (opt.minPitch && s.pitch < opt.minPitch)) + return false; + + if (!checkOption(opt.team, s.team)) return false; + if (!checkOption(opt.name, s.username)) return false; + if (!checkOption(opt.type, s.type)) return false; // "type" option of selector needs fixing + }); + } + + serv.selectorString = (str, pos) => { + pos = pos.clone(); + var player = serv.getPlayer(str); + if (!player && str[0] != '@') return null; + var match = str.match(/^@([a,r,p,e])(\[[^\]]+\])?$/); + if (match == null) return new Error('Invalid selector format'); + var typeConversion = { + a: 'all', + r: 'random', + p: 'near', + e: 'entity' + }; + var type = typeConversion[match[1]]; + var opt = match[2].split(','); + var optPair = []; + var err; + opt.forEach(o => { + var match = o.match(/^([^=]+)=([^=]+)$/); + if (match == null) err = new Error('Invalid selector option format: "' + o + '"'); + else optPair.push({key: match[1], val: match[2]}); + }); + if (err) return err; + + var optConversion = { + type: 'type', + r: 'radius', + rm: 'minRadius', + m: 'gameMode', + c: 'count', + l: 'level', + lm: 'minLevel', + team: 'team', + name: 'name', + rx: 'yaw', + rxm: 'minYaw', + ry: 'pitch', + rym: 'minPitch' + }; + + var data = { + pos: pos + }; + + optPair.forEach(({key,val}) => { + if (['x', 'y', 'z'].indexOf(key) != -1) pos[key] = val; + else { + data[optConversion[key]] = val; + } + }); + + return serv.selector(data); + } +} \ No newline at end of file