diff --git a/builtin/chatcommands.lua b/builtin/chatcommands.lua index b9661a888..66fcab63a 100644 --- a/builtin/chatcommands.lua +++ b/builtin/chatcommands.lua @@ -107,7 +107,7 @@ minetest.register_chatcommand("grant", { description = "Give privilege to player", privs = {}, func = function(name, param) - if not minetest.check_player_privs(name, {privs=true}) and + if not minetest.check_player_privs(name, {privs=true}) and not minetest.check_player_privs(name, {basic_privs=true}) then minetest.chat_send_player(name, "Your privileges are insufficient.") return @@ -153,7 +153,7 @@ minetest.register_chatcommand("revoke", { description = "Remove privilege from player", privs = {}, func = function(name, param) - if not minetest.check_player_privs(name, {privs=true}) and + if not minetest.check_player_privs(name, {privs=true}) and not minetest.check_player_privs(name, {basic_privs=true}) then minetest.chat_send_player(name, "Your privileges are insufficient.") return @@ -670,6 +670,24 @@ minetest.register_chatcommand("unban", { end, }) +minetest.register_chatcommand("kick", { + params = " [reason]", + description = "kick a player", + privs = {kick=true}, + func = function(name, param) + local tokick, reason = string.match(param, "([^ ]+) (.+)") + if not tokick then + tokick = param + end + if not minetest.kick_player(tokick, reason) then + minetest.chat_send_player(name, "Failed to kick player " .. tokick) + else + minetest.chat_send_player(name, "kicked " .. tokick) + minetest.log("action", name .. " kicked " .. tokick) + end + end, +}) + minetest.register_chatcommand("clearobjects", { params = "", description = "clear all objects in world", diff --git a/builtin/privileges.lua b/builtin/privileges.lua index 8dd06b24f..244aa453c 100644 --- a/builtin/privileges.lua +++ b/builtin/privileges.lua @@ -34,6 +34,7 @@ minetest.register_privilege("basic_privs", "Can modify 'shout' and 'interact' pr minetest.register_privilege("server", "Can do server maintenance stuff") minetest.register_privilege("shout", "Can speak in chat") minetest.register_privilege("ban", "Can ban and unban players") +minetest.register_privilege("kick", "Can kick players") minetest.register_privilege("give", "Can use /give and /giveme") minetest.register_privilege("password", "Can use /setpassword and /clearpassword") minetest.register_privilege("fly", { diff --git a/doc/lua_api.txt b/doc/lua_api.txt index f42cec76c..5536d0bfd 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -393,7 +393,7 @@ All default ores are of the uniformly-distributed scatter type. - scatter Randomly chooses a location and generates a cluster of ore. - If noise_params is specified, the ore will be placed if the 3d perlin noise at + If noise_params is specified, the ore will be placed if the 3d perlin noise at that point is greater than the noise_threshhold, giving the ability to create a non-equal distribution of ore. - sheet @@ -439,7 +439,7 @@ or through raw data supplied through Lua, in the form of a table. This table mu - The 'data' field is a flat table of MapNodes making up the schematic, in the order of [z [y [x]]]. Important: The default value for param1 in MapNodes here is 255, which represents "always place". -In the bulk MapNode data, param1, instead of the typical light values, instead represents the +In the bulk MapNode data, param1, instead of the typical light values, instead represents the probability of that node appearing in the structure. When passed to minetest.create_schematic, probability is an integer value ranging from 0 to 255: - A probability value of 0 means that node will never appear (0% chance). @@ -542,7 +542,7 @@ eg. 'default:pick_wood 21323' eg. 'default:apple' Table format: -eg. {name="default:dirt", count=5, wear=0, metadata=""} +eg. {name="default:dirt", count=5, wear=0, metadata=""} ^ 5 dirt nodes eg. {name="default:pick_wood", count=1, wear=21323, metadata=""} ^ a wooden pick about 1/3 weared out @@ -1102,7 +1102,7 @@ tablecolumns[,,,...;,,;...] ^^ span= number of following columns to affect (default infinite) Note: do NOT use a element name starting with "key_" those names are reserved to -pass key press events to formspec! +pass key press events to formspec! Inventory location: @@ -1458,7 +1458,7 @@ minetest.get_all_craft_recipes(query item) -> table or nil ^ returns indexed table with all registered recipes for query item (node) or nil if no recipe was found recipe entry table: - { + { method = 'normal' or 'cooking' or 'fuel' width = 0-3, 0 means shapeless recipe items = indexed [1-9] table with recipe items @@ -1532,6 +1532,7 @@ minetest.get_ban_list() -> ban list (same as minetest.get_ban_description("")) minetest.get_ban_description(ip_or_name) -> ban description (string) minetest.ban_player(name) -> ban a player minetest.unban_player_or_ip(name) -> unban player or IP address +minetest.kick_player(name, [reason]) -> disconnect a player with a optional reason Particles: minetest.add_particle(particle definition) @@ -1918,7 +1919,7 @@ methods: ^ returns raw node data is in the form of an array of node content ids - set_data(data): Sets the data contents of the VoxelManip object - update_map(): Update map after writing chunk back to map. - ^ To be used only by VoxelManip objects created by the mod itself; not a VoxelManip that was + ^ To be used only by VoxelManip objects created by the mod itself; not a VoxelManip that was ^ retrieved from minetest.get_mapgen_object - set_lighting(light, p1, p2): Set the lighting within the VoxelManip to a uniform value ^ light is a table, {day=<0...15>, night=<0...15>} @@ -1968,31 +1969,31 @@ methods: Mapgen objects --------------- -A mapgen object is a construct used in map generation. Mapgen objects can be used by an on_generate -callback to speed up operations by avoiding unnecessary recalculations; these can be retrieved using the -minetest.get_mapgen_object() function. If the requested Mapgen object is unavailable, or +A mapgen object is a construct used in map generation. Mapgen objects can be used by an on_generate +callback to speed up operations by avoiding unnecessary recalculations; these can be retrieved using the +minetest.get_mapgen_object() function. If the requested Mapgen object is unavailable, or get_mapgen_object() was called outside of an on_generate() callback, nil is returned. The following Mapgen objects are currently available: - voxelmanip - This returns three values; the VoxelManip object to be used, minimum and maximum emerged position, in that + This returns three values; the VoxelManip object to be used, minimum and maximum emerged position, in that order. All mapgens support this object. - heightmap - Returns an array containing the y coordinates of the ground levels of nodes in the most recently + Returns an array containing the y coordinates of the ground levels of nodes in the most recently generated chunk by the current mapgen. - biomemap - Returns an array containing the biome IDs of nodes in the most recently generated chunk by the + Returns an array containing the biome IDs of nodes in the most recently generated chunk by the current mapgen. - heatmap - Returns an array containing the temperature values of nodes in the most recently generated chunk by + Returns an array containing the temperature values of nodes in the most recently generated chunk by the current mapgen. - humiditymap - Returns an array containing the humidity values of nodes in the most recently generated chunk by the + Returns an array containing the humidity values of nodes in the most recently generated chunk by the current mapgen. - gennotify diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 9d3575a72..dc05ccbbe 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -160,6 +160,31 @@ int ModApiServer::l_ban_player(lua_State *L) return 1; } +// kick_player(name, [reason]) -> success +int ModApiServer::l_kick_player(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + const char *name = luaL_checkstring(L, 1); + std::string message; + if (lua_isstring(L, 2)) + { + message = std::string("Kicked: ") + lua_tostring(L, 2); + } + else + { + message = "Kicked."; + } + Player *player = getEnv(L)->getPlayer(name); + if (player == NULL) + { + lua_pushboolean(L, false); // No such player + return 1; + } + getServer(L)->DenyAccess(player->peer_id, narrow_to_wide(message)); + lua_pushboolean(L, true); + return 1; +} + // unban_player_or_ip() int ModApiServer::l_unban_player_or_ip(lua_State *L) { @@ -327,6 +352,7 @@ void ModApiServer::Initialize(lua_State *L, int top) API_FCT(get_ban_list); API_FCT(get_ban_description); API_FCT(ban_player); + API_FCT(kick_player); API_FCT(unban_player_or_ip); API_FCT(notify_authentication_modified); } diff --git a/src/script/lua_api/l_server.h b/src/script/lua_api/l_server.h index 21f300400..0d0aa45c8 100644 --- a/src/script/lua_api/l_server.h +++ b/src/script/lua_api/l_server.h @@ -79,6 +79,9 @@ private: // unban_player_or_ip() static int l_unban_player_or_ip(lua_State *L); + // kick_player(name, [message]) -> success + static int l_kick_player(lua_State *L); + // notify_authentication_modified(name) static int l_notify_authentication_modified(lua_State *L); diff --git a/src/server.h b/src/server.h index 21e9c811c..19bedf74a 100644 --- a/src/server.h +++ b/src/server.h @@ -330,6 +330,8 @@ public: void peerAdded(con::Peer *peer); void deletingPeer(con::Peer *peer, bool timeout); + void DenyAccess(u16 peer_id, const std::wstring &reason); + private: friend class EmergeThread; @@ -415,7 +417,6 @@ private: void DiePlayer(u16 peer_id); void RespawnPlayer(u16 peer_id); - void DenyAccess(u16 peer_id, const std::wstring &reason); void DeleteClient(u16 peer_id, ClientDeletionReason reason); void UpdateCrafting(u16 peer_id);