voxelands/src/servercommand.c

609 lines
15 KiB
C

/************************************************************************
* Minetest-c55
* Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
* Copyright (C) 2011 Ciaran Gultnieks <ciaran@ciarang.com>
*
* servercommand.cpp
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
* for Voxelands.
************************************************************************/
#include "common.h"
#include "array.h"
#include "auth.h"
#include "ban.h"
#include <string.h>
int command_status(command_context_t *ctx, array_t *args)
{
char buff[1024];
if (bridge_server_get_status(ctx,buff,1024))
return 1;
command_print(ctx,SEND_TO_SENDER,CN_INFO,"%s",buff);
return 0;
}
int command_me(command_context_t *ctx, array_t *args)
{
char* str;
if (!ctx || !args || !args->length)
return 1;
str = array_join(args," ",0);
if (!str)
return 1;
command_print(ctx,SEND_TO_OTHERS | SEND_NO_PREFIX, CN_CHAT, "* %s %s",ctx->player,str);
free(str);
return 0;
}
int command_privs(command_context_t *ctx, array_t *args)
{
char* str;
char buff[256];
uint64_t privs = 0;
if (!args || !args->length) {
if (!ctx) {
/* assume server console */
privs = PRIV_ALL;
}else{
/* Show our own real privs, without any adjustments made for admin status */
privs = auth_getprivs(ctx->player);
}
if (auth_privs2str(privs,buff,256) < 0)
buff[0] = 0;
command_print(ctx,SEND_TO_SENDER,CN_INFO,"%s",buff);
return 0;
}
if (ctx && (ctx->privs&PRIV_PRIVS) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
str = array_get_string(args,0);
if (!str) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,str) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
privs = auth_getprivs(str);
if (!privs) {
command_print(ctx,SEND_TO_SENDER,CN_CHAT,"none");
return 0;
}
if (auth_privs2str(privs,buff,256) < 0)
buff[0] = 0;
command_print(ctx,SEND_TO_SENDER,CN_INFO,"%s",buff);
return 0;
}
int command_grant(command_context_t *ctx, array_t *args)
{
char* name;
char* str;
uint64_t privs;
uint64_t newprivs = 0;
char buff[256];
int i;
if (ctx && (ctx->privs&PRIV_PRIVS) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length < 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
privs = auth_getprivs(name);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
for (i=1; i<args->length; i++) {
str = array_get_string(args,i);
if (!str)
break;
privs = auth_str2privs(str);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
newprivs |= privs;
}
if (!newprivs || newprivs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
privs |= newprivs;
auth_setprivs(name,privs);
privs = auth_getprivs(name);
if (auth_privs2str(newprivs,buff,256) >= 0) {
char *n = "Server Admin";
if (ctx)
n = ctx->player;
bridge_server_notify_player(ctx,name,"%s granted you the privilege \"%s\"",n,buff);
}
if (auth_privs2str(privs,buff,256) < 0) {
strcpy(buff,"???");
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Privileges changed to \"%s\"",buff);
return 0;
}
int command_revoke(command_context_t *ctx, array_t *args)
{
char* name;
char* str;
uint64_t privs;
uint64_t newprivs = 0;
char buff[256];
int i;
if (ctx && (ctx->privs&PRIV_PRIVS) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length < 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
privs = auth_getprivs(name);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
for (i=1; i<args->length; i++) {
str = array_get_string(args,i);
if (!str)
break;
privs = auth_str2privs(str);
if (privs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
newprivs |= privs;
}
if (!newprivs || newprivs == PRIV_INVALID) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid privileges specified");
return 1;
}
privs &= ~newprivs;
auth_setprivs(name,privs);
privs = auth_getprivs(name);
if (auth_privs2str(newprivs,buff,256) >= 0) {
char *n = "Server Admin";
if (ctx)
n = ctx->player;
bridge_server_notify_player(ctx,name,"%s revoked from you the privilige \"%s\"",n,buff);
}
if (auth_privs2str(privs,buff,256) < 0) {
strcpy(buff,"???");
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Privileges changed to \"%s\"",buff);
return 0;
}
int command_time(command_context_t *ctx, array_t *args)
{
char* str;
uint32_t time;
if (ctx && (ctx->privs&PRIV_SETTIME) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
str = array_get_string(args,0);
if (!str) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
time = strtol(str,NULL,10);
time %= 24000;
if (bridge_server_settime(ctx,time)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to set time");
return 1;
}
str = "Server Admin";
if (ctx)
str = ctx->player;
command_print(ctx,SEND_TO_OTHERS|SEND_TO_SENDER,CN_INFO,"%s sets time to %u",str,time);
return 0;
}
int command_shutdown(command_context_t *ctx, array_t *args)
{
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_server_shutdown(ctx)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to shutdown");
return 1;
}
command_print(ctx,SEND_TO_OTHERS|SEND_TO_SENDER,CN_INFO,"Server shutting down (operator request)");
return 0;
}
int command_teleport(command_context_t *ctx, array_t *args)
{
char* str;
v3_t pos;
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
str = array_get_string(args,0);
if (!str) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
if (!str_tov3t(str,&pos)) {
pos.x *= 10.0;
pos.y *= 10.0;
pos.z *= 10.0;
}else if (bridge_env_check_player(ctx,str) || bridge_env_player_pos(ctx,str,&pos)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Teleport to where?");
return 1;
}
if (bridge_move_player(ctx,&pos)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to teleport");
return 1;
}
vlprintf(CN_ACTION,"%s teleports to %s",ctx->player,str);
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Teleported to %s",str);
return 0;
}
int command_ban(command_context_t *ctx, array_t *args)
{
char* name;
char buff[256];
if (ctx && (ctx->privs&PRIV_BAN) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
if (bridge_server_get_player_ip_or_name(ctx,name,buff,256)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
bridge_server_notify_player(ctx,name,"You have been banned from this server");
ban_add(buff,name);
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Banned %s (%s)",name,buff);
return 0;
}
int command_unban(command_context_t *ctx, array_t *args)
{
char* name;
if (ctx && (ctx->privs&PRIV_BAN) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || !args->length) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
if (!name) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
ban_remove(name);
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Unbanned %s",name);
return 0;
}
int command_adduser(command_context_t *ctx, array_t *args)
{
char* name;
char* pass;
if (ctx && (ctx->privs&PRIV_BAN) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length != 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
pass = array_get_string(args,1);
if (!name || !pass) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) != 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Player '%s' already exists",name);
return 1;
}
if (bridge_server_add_player(ctx,name,pass)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to add player");
return 1;
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Added user %s",name);
return 0;
}
int command_clearobjects(command_context_t *ctx, array_t *args)
{
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
bridge_server_notify_player(ctx,NULL,"Clearing all objects, server may lag for a while.");
bridge_env_clear_objects(ctx);
command_print(ctx,SEND_TO_SENDER|SEND_TO_OTHERS,CN_INFO,"Clearing objects complete.");
return 0;
}
int command_setpassword(command_context_t *ctx, array_t *args)
{
char* name;
char* pass;
char buff[256];
if (ctx && (ctx->privs&PRIV_SERVER) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (!args || args->length != 2) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Missing parameter");
return 1;
}
name = array_get_string(args,0);
pass = array_get_string(args,1);
if (!name || !pass) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"You don't have permission to do that");
return 1;
}
if (bridge_env_check_player(ctx,name) == 0) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"No such player");
return 1;
}
if (str_topwd(name,pass,buff,256)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Invalid password");
return 1;
}
if (bridge_set_player_password(ctx,name,buff)) {
command_print(ctx,SEND_TO_SENDER,CN_WARN,"Unable to set password");
return 1;
}
command_print(ctx,SEND_TO_SENDER,CN_INFO,"Password set for %s",name);
return 0;
}
/*
void cmd_help(std::wostringstream &os,
ServerCommandContext *ctx)
{
uint64_t privs = ctx->privs;
if (ctx->parms.size() > 1) {
if ((privs&PRIV_SERVER) == PRIV_SERVER) {
if (ctx->parms[1] == L"shutdown") {
os<<L"-!- /#shutdown - shutdown the server";
return;
}else if (ctx->parms[1] == L"clearobjects") {
os<<L"-!- /clearobjects - remove active objects from the world, may take a long time";
return;
}else if (ctx->parms[1] == L"setting") {
os<<L"-!- /#setting <SETTING> [= VALUE] - change or view a config setting";
return;
}else if (ctx->parms[1] == L"setpassword") {
os<<L"-!- /setpassword <PLAYERNAME> <PASSWORD> - change or set a player's password";
return;
}
}
if ((privs&PRIV_SETTIME) == PRIV_SETTIME && ctx->parms[1] == L"time") {
os<<L"-!- /time <0-23999> - set the game time";
return;
}
if ((privs&PRIV_TELEPORT) == PRIV_TELEPORT && ctx->parms[1] == L"teleport") {
os<<L"-!- /teleport <X>,<Y>,<Z> - teleport to coordinates <X>,<Y>,<Z>";
return;
}
if ((privs&PRIV_PRIVS) == PRIV_PRIVS) {
if (ctx->parms[1] == L"grant") {
os<<L"-!- /grant <PLAYERNAME> <PRIVILEGE> - grant a new privilege to a player";
return;
}else if (ctx->parms[1] == L"revoke") {
os<<L"-!- /revoke <PLAYERNAME> <PRIVILEGE> - remove privilege from a player";
return;
}
}
if ((privs&PRIV_BAN) == PRIV_BAN) {
if (ctx->parms[1] == L"ban") {
os<<L"-!- /ban <PLAYERNAME OR IP ADDRESS> - ban a player from the server";
return;
}else if (ctx->parms[1] == L"unban") {
os<<L"-!- /unban <PLAYERNAME OR IP ADDRESS> - remove a player's ban from the server";
return;
}else if (ctx->parms[1] == L"adduser") {
os<<L"-!- /adduser <PLAYERNAME> <PASSWORD> - add a new player with the specified password";
return;
}
}
if (ctx->parms[1] == L"privs") {
if ((privs&PRIV_PRIVS) == PRIV_PRIVS) {
os<<L"-!- /privs [PLAYERNAME] - view the server privileges of a player";
return;
}
os<<L"-!- /privs - view your server privileges";
return;
}
if (ctx->parms[1] == L"status") {
os<<L"-!- /status - view the server's status and welcome message";
return;
}
if (ctx->parms[1] == L"help") {
os<<L"-!- /help [COMMAND] - get help for a command or a list of commands";
return;
}
}
os<<L"-!- Available commands: ";
os<<L"help status privs";
if ((privs&PRIV_SERVER) == PRIV_SERVER)
os<<L" shutdown setting clearobjects setpassword";
if ((privs&PRIV_SETTIME) == PRIV_SETTIME)
os<<L" time";
if ((privs&PRIV_TELEPORT) == PRIV_TELEPORT)
os<<L" teleport";
if ((privs&PRIV_PRIVS) == PRIV_PRIVS)
os<<L" grant revoke";
if ((privs&PRIV_BAN) == PRIV_BAN)
os<<L" ban unban";
}
*/