Limit node placement to 5 NPS (#803)

* Limit placement to 5 nodes per second

* Add Readme, check pointed thing, inform player

* Include team door fix

* Add license
This commit is contained in:
Lars Müller 2021-03-27 15:27:22 +01:00 committed by GitHub
parent 243061957a
commit 7382db367b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 2 deletions

View file

@ -362,14 +362,20 @@ function doors.register(name, def)
meta:set_string("owner_team", tname) meta:set_string("owner_team", tname)
end end
local copy = table.copy
local newnode = minetest.get_node(pos)
for _, on_placenode in pairs(minetest.registered_on_placenodes) do
if on_placenode(copy(pos), copy(newnode), placer, copy(node), ItemStack(itemstack), copy(pointed_thing)) then
return itemstack
end
end
if not (creative and creative.is_enabled_for and creative.is_enabled_for(pn)) then if not (creative and creative.is_enabled_for and creative.is_enabled_for(pn)) then
itemstack:take_item() itemstack:take_item()
end end
minetest.sound_play(def.sounds.place, {pos = pos}) minetest.sound_play(def.sounds.place, {pos = pos})
on_place_node(pos, minetest.get_node(pos), on_place_node(pos, newnode, placer, node, itemstack, pointed_thing)
placer, node, itemstack, pointed_thing)
return itemstack return itemstack
end end

View file

@ -0,0 +1,19 @@
Copyright (c) 2021 appgurueu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,8 @@
# `place_limit`
Fixes two things related to node placement:
* Ratelimits node placement
* Disallows building to non-pointable nodes (anticheat + race condition fix)
Licensed under the MIT license, written by appgurueu.

View file

@ -0,0 +1,53 @@
-- Licensed under the MIT license, written by appgurueu.
local players = {}
local blocks_per_second = 5
local resend_chat_message_seconds = 10
minetest.register_on_joinplayer(function(player)
-- player has to wait after join before they can place a node
players[player:get_player_name()] = {
last_placement = minetest.get_us_time(),
last_chat_message_sent = -math.huge
}
end)
local chat_send_player = minetest.chat_send_player
function minetest.chat_send_player(name, message)
if players[name] then
players[name].last_chat_message_sent = -math.huge
end
return chat_send_player(name, message)
end
local chat_send_all = minetest.chat_send_all
function minetest.chat_send_all(message)
for _, playerdata in pairs(players) do
playerdata.last_chat_message_sent = -math.huge
end
return chat_send_all(message)
end
minetest.register_on_leaveplayer(function(player)
players[player:get_player_name()] = nil
end)
minetest.register_on_placenode(function(pos, _newnode, placer, oldnode, _itemstack, pointed_thing)
if not ItemStack(minetest.get_node(pointed_thing.under).name):get_definition().pointable then
-- this should happen rarely
minetest.chat_send_player(placer:get_player_name(), "The block you have been building to has been dug/replaced!")
minetest.set_node(pos, oldnode)
return true
end
local name = placer:get_player_name()
local playerdata = players[name]
local time = minetest.get_us_time()
if (time - playerdata.last_placement) / 1e6 < 1 / blocks_per_second then
if (time - playerdata.last_chat_message_sent) / 1e6 >= resend_chat_message_seconds then
chat_send_player(placer:get_player_name(), "You are placing blocks too fast (more than " .. blocks_per_second .. " blocks per second) !")
playerdata.last_chat_message_sent = time
end
minetest.set_node(pos, oldnode)
return true
end
playerdata.last_placement = time
end)

View file

@ -0,0 +1,2 @@
name = place_limit
description = Limits block placement