Implemented kicking and banning, as well as /kick and /ban

This commit is contained in:
DemiPixel 2015-09-05 23:28:30 -07:00 committed by Romain Beaumont
parent 82447972cd
commit 3118823520
6 changed files with 196 additions and 2 deletions

View file

@ -13,6 +13,7 @@
- [serv.uuidToPlayer](#servuuidtoplayer)
- [serv.world](#servworld)
- [serv.entities](#serventities)
- [serv.bannedPlayers](#servbannedplayers)
- [Events](#events)
- ["error" (error)](#error-error)
- ["listening" (port)](#listening-port)
@ -22,6 +23,12 @@
- [serv.log(message)](#servlogmessage)
- [serv.broadcast(message[,color])](#servbroadcastmessagecolor)
- [serv.setBlock(position,blockType)](#servsetblockpositionblocktype)
- [serv.getPlayer(username)](#servgetplayerusername)
- [server.banUsername(username,reason,callback)](#serverbanusernameusernamereasoncallback)
- [server.ban(uuid,reason)](#serverbanuuidreason)
- [server.pardonUsername(username,callback)](#serverpardonusernameusernamecallback)
- [server.pardon(uuid)](#serverpardonuuid)
- [server.getUUIDFromUsername(username,callback)](#servergetuuidfromusernameusernamecallback)
- [Player](#player)
- [Properties](#properties-1)
- [player.entity](#playerentity)
@ -43,6 +50,8 @@
- [player.setGameMode(gameMode)](#playersetgamemodegamemode)
- [player.handleCommand(command)](#playerhandlecommandcommand)
- [player.updateHealth(health)](#playerupdatehealthhealth)
- [player.kick(reason)](#playerkickreason)
- [player.ban(banReason,kickReason)](#playerbanbanreasonkickreason)
- [Low level properties](#low-level-properties)
- [player._client](#player_client)
- [Low level methods](#low-level-methods)
@ -87,6 +96,18 @@ The map
All of the entities
#### serv.bannedPlayers
Object of players that are banned, key is their uuid. Use `serv.getUUIDFromUsername()` if you only have their username.
Example player:
```
{
time: <time in epoch>,
reason: <reason given>
}
```
### Events
#### "error" (error)
@ -119,6 +140,36 @@ broadcasts `message` to all the players with the optional `color`.
Saves block in world and sends block update to all players.
#### serv.getPlayer(username)
Returns player object with that username or, if no such player is on the server, null.
#### server.banUsername(username,reason,callback)
Bans players given a username. Mainly used if player is not online, otherwise use `player.ban()`.
Callback first argument returns `true` if there is a UUID for that username, `false` otherwise.
#### server.ban(uuid,reason)
Ban player given a uuid. If the player is online, using `player.ban()`. Bans with reason or `You are banned!`.
#### server.pardonUsername(username,callback)
Pardons a player given a username.
Callback returns `false` if UUID does not exist or player is not banned. It returns `true` otherwise.
#### server.pardon(uuid)
Pardons a player given their uuid. Returns `false` if they are not banned.
#### server.getUUIDFromUsername(username,callback)
Gets UUID from username. Since it needs to fetch from mojang servers, it is not immediate.
Arguments in format: `callback(uuid)`. `uuid` is null if no such username exists.
## Player
### Properties
@ -199,6 +250,14 @@ handle `command`
update the player health.
#### player.kick(reason)
Kicks a player with the reason given or `You were kicked!`.
#### player.ban(banReason,kickReason)
Kicks the player with `kickReason`, then bans them with reason `banReason`.
### Low level properties
#### player._client

View file

@ -29,6 +29,59 @@ function inject(serv, player, options)
serv.setBlock(new Vec3(results[1], results[2], results[3]), results[4]);
}
}
else if(results=command.match(/^kick/)) {
results = command.match(/^kick ([a-zA-Z0-9]+) ?(.*)/);
if (!results) {
player.chat("Usage: /kick <player> [reason]");
}
else {
var kickPlayer = serv.getPlayer(results[1]);
if (!kickPlayer) {
player.chat(results[1] + " is not on this server!");
}
else {
kickPlayer.kick(results[2] ? "\"" + results[2] + "\"" : "Kicked from server.");
serv.log(player.username + " kicked " + results[1] + (results[2] ? " (" + results[2] + ")" : ""));
}
}
}
else if(results=command.match(/^ban/)) {
results = command.match(/^ban ([a-zA-Z0-9]+) ?(.*)/);
if (!results) {
player.chat("Usage: /ban <player> [reason]");
}
else {
var banPlayer = serv.getPlayer(results[1]);
var kickReason = "You were banned!" + (results[2] ? " Reason: " + results[2] : "");
var banReason = "You are banned!" + (results[2] ? " Reason: " + results[2] : "");
if (banPlayer) banPlayer.ban(banReason, kickReason);
else {
serv.banUsername(results[1], banReason, function(success) {
if (success) {
serv.log(player.username + " banned " + results[1] + (results[2] ? " (" + results[2] + ")" : ""));
player.chat(results[1] + " was banned");
} else {
player.chat(results[1] + " is not a valid player!");
}
});
}
}
}
else if(results=command.match(/^pardon/)) {
results = command.match(/^pardon ([a-zA-Z0-9]+)/);
if (!results) {
player.chat("Usage: /pardon <player>");
}
else {
serv.pardonUsername(results[1], function(success) {;
if (success) {
player.chat(results[1] + " is unbanned");
} else {
player.chat(results[1] + " is not banned");
}
});
}
}
else
player.chat("Invalid command.");
}

View file

@ -1,5 +1,6 @@
var Entity=require("prismarine-entity");
var vec3 = require("vec3");
var moment = require("moment");
module.exports=inject;
@ -8,6 +9,11 @@ function transformUuid(s)
return s.split("-").map(function(item) { return parseInt(item, 16); });
}
function plainUuid(s)
{
return s.replace(/-/g, '');
}
function toFixedPosition(p)
{
return new vec3(Math.floor(p.x*32),Math.floor(p.y*32),Math.floor(p.z*32))
@ -93,6 +99,18 @@ function inject(serv,player)
});
player.gameMode=gameMode;
}
function kick(reason)
{
player._client.write('kick_disconnect', {
reason: reason ? JSON.stringify(reason) : '"You were kicked!"'
});
}
function ban(reason, kickReason) {
player.kick(kickReason || reason || "You were banned!");
serv.ban(plainUuid(player._client.uuid), reason);
}
function fillTabList()
{
@ -169,12 +187,18 @@ function inject(serv,player)
}
function login()
{
{
if (serv.uuidToPlayer[player._client.uuid]) {
player._client.end("You are already connected");
return;
}
addPlayer();
addPlayer(); // Added before kicking so no errors in deleting entity
if (serv.bannedPlayers[plainUuid(player._client.uuid)]) {
player.kick(serv.bannedPlayers[plainUuid(player._client.uuid)].reason);
return;
}
sendLogin();
sendMap();
sendSpawnPosition();
@ -193,6 +217,8 @@ function inject(serv,player)
player.setGameMode=setGameMode;
player.kick=kick;
player.ban=ban;
player.login=login;
player.sendInitialPosition=sendInitialPosition;
player.spawn=spawn;

View file

@ -2,6 +2,8 @@ var path = require('path');
var requireIndex = require('requireindex');
var playerPlugins = requireIndex(path.join(__dirname,'..', 'playerPlugins'));
var Player=require("../player");
var moment=require("moment");
var request=require("request");
module.exports = inject;
@ -16,4 +18,48 @@ function inject(serv,options)
serv.emit("newPlayer",player);
player.login();
});
function ban(uuid, reason) {
serv.bannedPlayers[uuid] = {
time: +moment(),
reason: reason || "You are banned!"
};
}
function getUUIDFromUsername(username, cb) {
request('https://api.mojang.com/users/profiles/minecraft/' + username, function(err, res, body) {
cb(body ? JSON.parse(body).id : null);
});
}
function banUsername(username, reason, cb) {
serv.getUUIDFromUsername(username, function(uuid) {
if (!uuid) return cb ? cb(false) : false;
serv.ban(uuid, reason);
if (cb) cb(true);
});
}
function pardonUsername(username, cb) {
serv.getUUIDFromUsername(username, function(uuid) {
if (!cb) return;
if (!uuid) return cb(false);
else return cb(pardon(uuid));
});
}
function pardon(uuid) {
if (serv.bannedPlayers[uuid]) {
delete serv.bannedPlayers[uuid];
return true;
} else {
return false;
}
}
serv.bannedPlayers = {};
serv.ban = ban;
serv.banUsername = banUsername;
serv.pardonUsername = pardonUsername;
serv.getUUIDFromUsername = getUUIDFromUsername;
}

View file

@ -6,4 +6,13 @@ function inject(serv)
serv.players=[];
serv.uuidToPlayer={};
serv.entities={};
function getPlayer(username) {
for (var p in serv.players) {
if (serv.players[p].username == username) return serv.players[p]
}
return null;
}
serv.getPlayer = getPlayer;
}

View file

@ -33,6 +33,7 @@
"prismarine-chunk": "git://github.com/rom1504/prismarine-chunk.git#use-prismarine-block",
"prismarine-entity": "0.1.0",
"prismarine-world": "git://github.com/rom1504/prismarine-world.git#implementation",
"request": "^2.61.0",
"requireindex": "~1.0.0",
"vec3": "0.1.3"
},