summaryrefslogtreecommitdiff
path: root/protection.lua
diff options
context:
space:
mode:
authorBremaWeb <brandon@bremaweb.com>2013-11-30 13:23:50 -0600
committerBremaWeb <brandon@bremaweb.com>2013-11-30 13:23:50 -0600
commit81a12e3d38c83eacfce4a3eeaec14724dcdb4c8f (patch)
tree58701772bd01e4ab332a0699cdcf0a3e0bf8e432 /protection.lua
parent6b22f3d60f1b942485ccbb6dc5417fbe65119db9 (diff)
restructured, use Settings interface for config, use protection API
Diffstat (limited to 'protection.lua')
-rw-r--r--protection.lua188
1 files changed, 188 insertions, 0 deletions
diff --git a/protection.lua b/protection.lua
new file mode 100644
index 0000000..8e1f16f
--- /dev/null
+++ b/protection.lua
@@ -0,0 +1,188 @@
+landrush.offense = {}
+
+function landrush.can_interact(pos, name)
+
+ if ( pos.y < -200 ) then
+ return true
+ end
+
+ if ( minetest.check_player_privs(name, {landrush=true}) ) then
+ return true
+ end
+
+ local chunk = landrush.get_chunk(pos)
+
+ if ( landrush.claims[chunk] ~= nil ) then
+ if ( landrush.claims[chunk].shared['*all'] ) then
+ return true
+ end
+ end
+
+
+ -- return landrush.claims[chunk] == nil or landrush.claims[chunk].owner == name or landrush.claims[chunk].shared[name]
+ if ( landrush.claims[chunk] == nil ) then
+ if ( landrush.config:get_bool("requireClaim") == true ) then
+ return false
+ else
+ return true
+ end
+ end
+
+ -- see if the owner is offline, and area is not shared then it's off limits
+ if ( landrush.claims[chunk].owner ~= name and landrush.config:get_bool("onlineProtection") == false ) then
+ if ( minetest.get_player_by_name(owner) ~= nil ) then
+ minetest.chat_send_player( landrush.claims[chunk].owner, "You are being griefed by "..name.." at "..minetest.pos_to_string(pos) )
+
+ for u,u in pairs(landrush.claims[chunk].shared) do
+ minetest.chat_send_player( u, name.." is griefing your shared claim at "..minetest.pos_to_string(pos) )
+ end
+
+ minetest.chat_send_player( name, "You are griefing "..landrush.claims[chunk].owner )
+ return true
+ end
+ end
+ return landrush.claims[chunk].owner == name or landrush.claims[chunk].shared[name]
+end
+
+function landrush.do_autoban(pos,name)
+ -- moved this to it's own function so landrush.protection_violation is a little cleaner, and this could be overwritten as well
+ if ( landrush.offense[name] == nil ) then
+ landrush.offense[name] = {count=0,lastpos=nil,lasttime=os.time(),bancount=0}
+ end
+
+ local timediff = (os.time() - landrush.offense[name].lasttime)/60
+ local distance = landrush.get_distance(landrush.offense[name].lastpos,pos)
+
+ -- reset offenses after a given time period
+ if timediff > tonumber(landrush.config:get("offenseReset")) then
+ landrush.offense[name].count=0
+ end
+
+ -- offense amount starts at 10 and is decreased based on the length of time between offenses
+ -- and the distance from the last offense. This weighted system tries to make it fair for people who aren't
+ -- intentionally griefing
+ offenseAmount = ( 10 - ( timediff / 10 ) ) - ( ( distance / landrush.config:get("chunkSize") ) * 0.5 )
+
+ landrush.offense[name].count=landrush.offense[name].count + offenseAmount
+ minetest.log("action",name.." greifing attempt")
+
+ if ( landrush.offense[name].count > tonumber(landrush.config:get("banLevel")) ) then
+ landrush.offense[name].bancount = landrush.offense[name].bancount + 1
+
+ local banlength = landrush.offense[name].bancount * 10
+
+ if ( landrush.offense[name].bancount < 4 ) then
+ minetest.chat_send_player(name, "You have been banned for "..tostring(banlength).." minutes!")
+ else
+ minetest.chat_send_player(name, "You have been banned!")
+ end
+
+ minetest.log("action",name.." has been banned for griefing attempts")
+ minetest.chat_send_all(name.." has been banned for griefing attempts")
+
+ if ( chatplus and landrush.config:get_string("adminUser") ~= nil) then
+ table.insert(chatplus.names[landrush.config:get_string("adminUser")].messages,"mail from <LandRush>: "..name.." banned for "..tostring(banlength).." minutes for attempted griefing")
+ end
+ minetest.ban_player(name)
+
+ landrush.offense[name].count = 0
+ landrush.offense[name].lastpos = nil
+
+ if ( landrush.offense[name].bancount < 4 ) then
+ minetest.after( (banlength * 60), minetest.unban_name_or_ip,name )
+ end
+
+ return
+ end
+
+ if ( landrush.offense[name].count > tonumber(landrush.config:get("banWarning")) ) then
+ minetest.chat_send_player(name, "Stop trying to dig in claimed areas or you will be banned!")
+ minetest.chat_send_player(name, "Use /showarea and /landowner to see the protected area and who owns it.")
+ minetest.sound_play("landrush_ban_warning", {to_name=name,gain = 10.0})
+ end
+
+ landrush.offense[name].lasttime = os.time()
+ landrush.offense[name].lastpos = pos
+end
+
+function landrush.protection_violation(pos,name)
+ -- this function can be overwritten to apply whatever discipline the server admin wants
+ -- this is the default discipline
+
+ local player = minetest.get_player_by_name(name)
+ local owner = landrush.get_owner(pos)
+
+ if ( landrush.config:get_bool("requireClaim") == true ) then
+ if ( owner == nil ) then
+ minetest.chat_send_player(name,"This area is unowned, but you must claim it to build or mine")
+ return true
+ end
+ end
+
+ minetest.chat_send_player(name, "Area owned by "..tostring(owner).." stop trying to dig here!")
+ player:set_hp( player:get_hp() - landrush.config:get("offenseDamage") )
+
+ if ( landrush.config:get_bool("autoBan") == true ) then
+ landrush.do_autoban(pos,name)
+ end
+
+end
+
+landrush.default_is_protected = minetest.is_protected
+
+function minetest.is_protected (pos, name)
+ if ( landrush.can_interact(pos, name) ) then
+ return landrush.default_is_protected(pos,name)
+ else
+ return true
+ end
+end
+
+minetest.register_on_protection_violation( landrush.protection_violation )
+
+
+-- I'm keeping this just for the TNT workaround
+landrush.default_place = minetest.item_place
+
+function minetest.item_place(itemstack, placer, pointed_thing)
+ owner = landrush.get_owner(pointed_thing.above)
+ name = placer:get_player_name()
+ if landrush.can_interact(pointed_thing.above,name) or itemstack:get_name() == "" then
+ -- add a workaround for TNT, since overwriting the registered node seems not to work
+ if itemstack:get_name() == "tnt:tnt" or itemstack:get_name() == "tnt:tnt_burning" then
+ local pos = pointed_thing.above
+ local temp_pos = pos
+ temp_pos.x = pos.x + 2
+ if name ~= landrush.get_owner( temp_pos ) then
+ minetest.chat_send_player( name, "Do not place TNT near claimed areas..." )
+ return itemstack
+ end
+ temp_pos.x = pos.x - 2
+ if name ~= landrush.get_owner( temp_pos ) then
+ minetest.chat_send_player( name, "Do not place TNT near claimed areas..." )
+ return itemstack
+ end
+ temp_pos.z = pos.z + 2
+ if name ~= landrush.get_owner( temp_pos ) then
+ minetest.chat_send_player( name, "Do not place TNT near claimed areas..." )
+ return itemstack
+ end
+ temp_pos.z = pos.z - 2
+ if name ~= landrush.get_owner( temp_pos ) then
+ minetest.chat_send_player( name, "Do not place TNT near claimed areas..." )
+ return itemstack
+ end
+ end
+ -- end of the workaround
+ return landrush.default_place(itemstack, placer, pointed_thing)
+ else
+ if ( owner ~= nil ) then
+ minetest.chat_send_player(name, "Area owned by "..owner)
+ return itemstack
+ else
+ minetest.chat_send_player(name,"Area unclaimed, claim this area to build")
+ return itemstack
+ end
+ end
+end
+