diff --git a/utils/antigrief.lua b/utils/antigrief.lua index 3745a099..bf43105f 100644 --- a/utils/antigrief.lua +++ b/utils/antigrief.lua @@ -10,12 +10,14 @@ local Color = require 'utils.color_presets' local Server = require 'utils.server' local Jail = require 'utils.datastore.jail_data' local FancyTime = require 'tools.fancy_time' +local Task = require 'utils.task' +local Token = require 'utils.token' local Public = {} local match = string.match local capsule_bomb_threshold = 8 local de = defines.events - +local sub = string.sub local format = string.format local floor = math.floor local random = math.random @@ -31,6 +33,7 @@ local this = { corpse_history = {}, message_history = {}, cancel_crafting_history = {}, + deconstruct_history = {}, whitelist_types = {}, permission_group_editing = {}, players_warned = {}, @@ -45,6 +48,9 @@ local this = { required_playtime = 2592000, damage_entity_threshold = 20, explosive_threshold = 16, + enable_jail_when_decon = true, + decon_surface_blacklist = 'nauvis', + players_warn_when_decon = {}, limit = 2000 } @@ -75,6 +81,17 @@ local chests = { ['logistic-container'] = true } +-- Clears the player from players_warn_when_decon tbl. +local clear_player_decon_warnings = + Token.register( + function(event) + local player_index = event.player_index + if this.players_warn_when_decon[player_index] then + this.players_warn_when_decon[player_index] = nil + end + end +) + Global.register( this, function(t) @@ -809,6 +826,74 @@ local function on_permission_group_deleted(event) end end +local function on_player_deconstructed_area(event) + local surface = event.surface + + local surface_name = this.decon_surface_blacklist + if sub(surface.name, 0, #surface_name) ~= surface_name then + return + end + + local player = game.get_player(event.player_index) + local area = event.area + local count = surface.count_entities_filtered({area = area, force = 'neutral'}) + if count and count > 0 then + surface.cancel_deconstruct_area { + area = area, + force = player.force + } + if count >= 2000 then + local msg = '[Deconstruct] ' .. player.name .. ' tried to deconstruct: ' .. count .. ' entities!' + Utils.print_to(nil, msg) + Server.to_discord_embed(msg) + + if not this.deconstruct_history then + this.deconstruct_history = {} + end + if #this.deconstruct_history > this.limit then + overflow(this.deconstruct_history) + end + + local t = abs(floor((game.tick) / 60)) + t = FancyTime.short_fancy_time(t) + local str = '[' .. t .. '] ' + str = str .. msg + str = str .. ' at lt_x:' + str = str .. floor(area.left_top.x) + str = str .. ' at lt_y:' + str = str .. floor(area.left_top.y) + str = str .. ' at rb_x:' + str = str .. floor(area.right_bottom.x) + str = str .. ' at rb_y:' + str = str .. floor(area.right_bottom.y) + str = str .. ' ' + str = str .. 'surface:' .. player.surface.index + increment(this.deconstruct_history, str) + + if this.enable_jail_when_decon and not player.admin then + if not this.players_warn_when_decon[player.index] then + this.players_warn_when_decon[player.index] = 1 + local r = random(7200, 18000) + Task.set_timeout_in_ticks(r, clear_player_decon_warnings, {player_index = player.index}) + end + local warnings = this.players_warn_when_decon[player.index] + if warnings then + if warnings == 1 or warnings == 2 then + Utils.print_to(player, '[Deconstruct] Warning! Do not deconstruct that many entities at once!') + this.players_warn_when_decon[player.index] = this.players_warn_when_decon[player.index] + 1 + elseif warnings == 3 then + Utils.print_to(player, '[Deconstruct] Warning! Do not deconstruct that many entities at once! This is your final warning!') + this.players_warn_when_decon[player.index] = this.players_warn_when_decon[player.index] + 1 + else + Jail.try_ul_data(player, true, 'script', 'Deconstructed ' .. count .. ' entities. Has been warned 3 times before getting jailed.') + this.players_warn_when_decon[player.index] = nil + end + end + end + end + end +end + local function on_permission_group_edited(event) if not this.enabled then return @@ -901,33 +986,47 @@ function Public.whitelist_types(key, value) end --- If the event should also check trusted players. ----@param value string +---@param value boolean function Public.do_not_check_trusted(value) this.do_not_check_trusted = value or false return this.do_not_check_trusted end --- If ANY actions should be performed when a player misbehaves. ----@param value string +---@param value boolean function Public.enable_capsule_warning(value) this.enable_capsule_warning = value or false return this.enable_capsule_warning end --- If ANY actions should be performed when a player misbehaves. ----@param value string +---@param value boolean function Public.enable_capsule_cursor_warning(value) this.enable_capsule_cursor_warning = value or false return this.enable_capsule_cursor_warning end --- If the script should jail a person instead of kicking them ----@param value string +---@param value boolean function Public.enable_jail(value) this.enable_jail = value or false return this.enable_jail end +--- If the script should jail a person whenever they deconstruct multiple times. +---@param value boolean +function Public.enable_jail_when_decon(value) + this.enable_jail_when_decon = value or false + return this.enable_jail_when_decon +end + +--- If the script should jail a person whenever they deconstruct multiple times. +---@param value string +function Public.decon_surface_blacklist(value) + this.decon_surface_blacklist = value or 'nauvis' + return this.decon_surface_blacklist +end + --- Defines what the threshold for amount of explosives in chest should be - logged or not. ---@param value string function Public.explosive_threshold(value) @@ -976,5 +1075,6 @@ Event.add(de.on_permission_group_deleted, on_permission_group_deleted) Event.add(de.on_permission_group_edited, on_permission_group_edited) Event.add(de.on_permission_string_imported, on_permission_string_imported) Event.add(de.on_console_chat, on_console_chat) +Event.add(de.on_player_deconstructed_area, on_player_deconstructed_area) return Public diff --git a/utils/datastore/jail_data.lua b/utils/datastore/jail_data.lua index 5cd90d20..864ffaff 100644 --- a/utils/datastore/jail_data.lua +++ b/utils/datastore/jail_data.lua @@ -478,7 +478,7 @@ local function jail(player, griefer, msg, raised) end if not msg then - return + msg = 'Jailed by script' end if not game.get_player(griefer) then @@ -589,7 +589,10 @@ function Public.try_dl_data(key) end --- Tries to get data from the webpanel and updates the local table with values. --- @param data_set player token +-- @param key LuaPlayer +-- @param value boolean +-- @param player LuaPlayer or