From 2c108e679252d1cd336e575394bfcbadbbf06c0e Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 18 Apr 2019 14:34:21 +0100 Subject: [PATCH 1/2] Added report-control --- modules/addons/jail-control.lua | 20 ++++- modules/addons/reports-control.lua | 132 +++++++++++++++++++++++++++++ modules/commands/jail.lua | 2 +- 3 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 modules/addons/reports-control.lua diff --git a/modules/addons/jail-control.lua b/modules/addons/jail-control.lua index b743e1b7..a65d6c2e 100644 --- a/modules/addons/jail-control.lua +++ b/modules/addons/jail-control.lua @@ -5,7 +5,11 @@ local move_items = ext_require('expcore.common','move_items') local Public = { old_roles = {}, - temp_bans = {} + temp_bans = {}, + player_jailed=script.generate_event_name(), + player_unjailed=script.generate_event_name(), + player_temp_banned=script.generate_event_name(), + player_clear_temp_ban=script.generate_event_name() } Global.register({ Public.old_roles, @@ -15,6 +19,16 @@ Global.register({ Public.temp_bans=tbl[2] end) +local function event_emit(event,player,by_player_name,reason) + script.raise_event(event,{ + name=event, + tick=game.tick, + player_index=player.index, + by_player_name=by_player_name, + reason=reason + }) +end + --- Jails a player, this is only the logic there is no output to players -- @tparam player LuaPlayer the player that will be jailed, must not be in jail -- @tparam[opt=''] by_player_name string the name of the player doing the action used in logs @@ -27,6 +41,7 @@ function Public.jail_player(player,by_player_name) Public.old_roles[player.name] = old_roles Roles.unassign_player(player,old_roles,by_player_name,true) Roles.assign_player(player,'Jail',by_player_name,true) + event_emit(Public.player_jailed,player,by_player_name) return #old_roles end @@ -41,6 +56,7 @@ function Public.unjail_player(player,by_player_name) local old_roles = Public.old_roles[player.name] Roles.unassign_player(player,'Jail',by_player_name,true) Roles.assign_player(player,old_roles,by_player_name,true) + event_emit(Public.player_unjailed,player,by_player_name) return #old_roles end @@ -59,6 +75,7 @@ function Public.temp_ban_player(player,by_player_name,reason) local inv = player.get_main_inventory() move_items(inv.get_contents()) inv.clear() + event_emit(Public.player_temp_banned,player,by_player_name,reason) return true end @@ -72,6 +89,7 @@ function Public.clear_temp_ban_player(player,by_player_name) if not Public.temp_bans[player.name] then return end Public.unjail_player(player,by_player_name) Public.temp_bans[player.name] = nil + event_emit(Public.player_clear_temp_ban,player,by_player_name) return true end diff --git a/modules/addons/reports-control.lua b/modules/addons/reports-control.lua new file mode 100644 index 00000000..eacb212b --- /dev/null +++ b/modules/addons/reports-control.lua @@ -0,0 +1,132 @@ +local Game = require 'utils.game' +local Global = require 'utils.global' + +local Public = { + user_reports={}, + player_report_added = script.generate_event_name(), + player_report_removed = script.generate_event_name() +} + +Global.register(Public.user_reports,function(tbl) + Public.user_reports = tbl +end) + +local function event_emit(event,player,by_player_name) + local reports = Public.user_reports[player.name] + local reason = reports and reports[by_player_name] + script.raise_event(event,{ + name=event, + tick=game.tick, + player_index=player.index, + by_player_name=by_player_name, + reason=reason + }) +end + +--- Adds a report to a player, reports are stored in global table and can be accessed later +-- @tparam player LuaPlayer the player that will be reported +-- @tparam[opt='Non Given.'] reason string the reason that the player is being reported +-- @tparam[opt=''] by_player_name string the name of the player doing the action +-- @treturn boolean true if the report was added, nil if there is an error +function Public.report_player(player,reason,by_player_name) + player = Game.get_player_from_any(player) + if not player then return end + reason = reason or 'Non Given.' + by_player_name = by_player_name or '' + local reports = Public.user_reports[player.name] + if not reports then + Public.user_reports[player.name] = { + [by_player_name] = reason + } + elseif not reports[by_player_name] then + reports[by_player_name] = reason + else return false end + event_emit(Public.player_report_added,player,by_player_name) + return true +end + +--- Removes a report from a player by the given player, see clear_player_reports to remove all +-- @tparam player LuaPlayer the player that will have the report removed +-- @tparam[opt=''] by_player_name string the name of the player doing the action +-- @treturn boolean true if the report was removed, nil if there was an error +function Public.remove_player_report(player,by_player_name) + player = Game.get_player_from_any(player) + if not player then return end + by_player_name = by_player_name or '' + local reports = Public.user_reports[player.name] + if reports and reports[by_player_name] then + event_emit(Public.player_report_removed,player,by_player_name) + reports[by_player_name] = nil + return true + end + return false +end + +--- Clears all reports from a player, will emit an event for each individual report as if remove_player_report was used +-- @tparam player LuaPlayer the player to clear the reports of +-- @treturn boolean true if the reports were cleared, nil if error +function Public.clear_player_reports(player) + player = Game.get_player_from_any(player) + if not player then return end + local reports = Public.user_reports[player.name] + if reports then + for by_player_name,reason in pairs(reports) do + event_emit(Public.player_report_removed,player,by_player_name) + end + Public.user_reports[player.name] = nil + return true + end + return false +end + +--- Test for if a player has been reported by another player, can also return the reason from that player +-- @tparam player LuaPlayer the player to check the reports of +-- @tparam by_player_name string the player that made if the report if present (note server is not default here) +-- @tparam[opt=false] rtn_reason boolean true will return the reason for the report rather than a boolean +-- @treturn boolean true if a report from the player is present unless rtn_reason is true when a string is returned (or false) +function Public.player_is_reported_by(player,by_player_name,rtn_reason) + player = Game.get_player_from_any(player) + if not player then return end + local reports = Public.user_reports[player.name] + if reports and reports[by_player_name] then + return rtn_reason and reports[by_player_name] or true + end + return false +end + +--- Gets all the reports that are on a player +-- @tparam player LuaPlayer the player to get the reports of +-- @treturn table a table of all the reports for this player, empty table if no reports +function Public.get_player_reports(player) + player = Game.get_player_from_any(player) + if not player then return end + return Public.user_reports[player.name] or {} +end + +--- Counts all reports on a player returning a number, a custom count function can be given which should return a number +-- @tparam player LuaPlayer the player to count the reports of +-- @tparam[opt] count_callback function should return a number or true (for 1) this will be passed every report on the player +-- count_callback param - player_name string - the name of the player who made the report +-- count_callback param - reason string - the reason the reason was made +-- count_callback return - number or boolean - if number then this will be added to the count, if boolean then false = 0 and true = 1 +-- @treturn number the number of reports on the player +function Public.count_player_reports(player,count_callback) + player = Game.get_player_from_any(player) + if not player then return end + local reports = Public.user_reports[player.name] or {} + if not count_callback then + return #reports + else + local ctn = 0 + for player_name,reason in pairs(reports) do + local success,err = pcall(count_callback,player_name,reason) + if success and err then + if err == true then err = 1 end + ctn = ctn+err + end + end + return ctn + end +end + +return Public \ No newline at end of file diff --git a/modules/commands/jail.lua b/modules/commands/jail.lua index 3c2b74ee..adfcd927 100644 --- a/modules/commands/jail.lua +++ b/modules/commands/jail.lua @@ -45,7 +45,7 @@ Commands.new_command('temp-ban','Temp bans a player until the next reset; this r end end) -Commands.new_command('remove-temp-ban','Removes temp ban from a player; this will not restore they items.') +Commands.new_command('clear-temp-ban','Removes temp ban from a player; this will not restore they items.') :add_param('player',false,'player-role') :add_param('reason',false) :enable_auto_concat() From 17e61e710b091953c2e755c25dd6ec38a4a85a48 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Thu, 18 Apr 2019 15:16:12 +0100 Subject: [PATCH 2/2] Added report commands --- expcore/roles.lua | 44 +++++++++++++++++++++++ locale/en/commands.cfg | 9 +++++ modules/commands/jail.lua | 2 ++ modules/commands/reports.lua | 69 ++++++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+) create mode 100644 modules/commands/reports.lua diff --git a/expcore/roles.lua b/expcore/roles.lua index 97107404..f503798d 100644 --- a/expcore/roles.lua +++ b/expcore/roles.lua @@ -108,6 +108,10 @@ >>>>Functions List (see function for more detail): Roles.debug() --- Returns a string which contains all roles in index order displaying all data for them + Roles.print_to_roles(roles,message) --- Prints a message to all players in the given roles, may send duplicate message however factorio blocks spam + Roles.print_to_roles_higher(role,message) --- Prints a message to all players who have the given role or one which is higher (excluding default) + Roles.print_to_roles_lower(role,message) --- Prints a message to all players who have the given role or one which is lower (excluding default) + Roles.get_role_by_name(name) --- Get a role for the given name Roles.get_role_by_order(index) --- Get a role with the given order index Roles.get_role_from_any(any) --- Gets a role from a name,index or role object (where it is just returned) @@ -240,6 +244,46 @@ function Roles.debug() return output end +--- Prints a message to all players in the given roles, may send duplicate message however factorio blocks spam +-- @tparam roles table a table of roles which to send the message to +-- @tparam message string the message to send to the players +function Roles.print_to_roles(roles,message) + for _,role in pairs(roles) do + role = Roles.get_role_from_any(role) + if role then role:print(message) end + end +end + +--- Prints a message to all players who have the given role or one which is higher (excluding default) +-- @tparam role string the name of the role to send the message to +-- @tparam message string the message to send to the players +function Roles.print_to_roles_higher(role,message) + role = Roles.get_role_from_any(role) + if not role then return end + local roles = {} + for index,role_name in pairs(Roles.config.order) do + if index <= role.index and role_name ~= Roles.config.internal.default then + table.insert(roles,role_name) + end + end + Roles.print_to_roles(roles,message) +end + +--- Prints a message to all players who have the given role or one which is lower (excluding default) +-- @tparam role string the name of the role to send the message to +-- @tparam message string the message to send to the players +function Roles.print_to_roles_lower(role,message) + role = Roles.get_role_from_any(role) + if not role then return end + local roles = {} + for index,role_name in pairs(Roles.config.order) do + if index >= role.index and role_name ~= Roles.config.internal.default then + table.insert(roles,role_name) + end + end + Roles.print_to_roles(roles,message) +end + --- Get a role for the given name -- @tparam name string the name of the role to get -- @treturn Roles._prototype the role with that name or nil diff --git a/locale/en/commands.cfg b/locale/en/commands.cfg index c8b9a2d9..8bf0ea4b 100644 --- a/locale/en/commands.cfg +++ b/locale/en/commands.cfg @@ -20,3 +20,12 @@ jail-temp-ban=__1__ was temp banned until next reset by __2__. Reason: __3__ jail-temp-ban-clear=__1__ was cleared from temp banned by __2__. jail-not-temp-banned=__1__ is not currently temp banned. jail-already-banned=__1__ is already banned. +report-player-immune=This player can not be reported. +report-non-admin=__1__ was reported for __2__. +report-admin=__1__ was reported by __2__ for __3__. +report-already-reported=You can only report a player once, you can ask a moderator to clear this report. +report-not-reported=The player had no reports on them. +report-player-count-title=The following players have reports against them: +report-player-report-title=__1__ has the following reports agasinst them: +report-list=__1__: __2__ +report-removed=__1__ has one or more reports removed by __2__. \ No newline at end of file diff --git a/modules/commands/jail.lua b/modules/commands/jail.lua index adfcd927..d6452252 100644 --- a/modules/commands/jail.lua +++ b/modules/commands/jail.lua @@ -20,6 +20,7 @@ end) Commands.new_command('unjail','Puts a player into jail and removes all other roles.') :add_param('player',false,'player-role') +:add_alias('clear-jail','remove-jail') :enable_auto_concat() :register(function(player,action_player,raw) local action_player_name_color = format_chat_player_name(action_player) @@ -48,6 +49,7 @@ end) Commands.new_command('clear-temp-ban','Removes temp ban from a player; this will not restore they items.') :add_param('player',false,'player-role') :add_param('reason',false) +:add_alias('untemp-ban','remove-temp-ban') :enable_auto_concat() :register(function(player,action_player,reason,raw) local action_player_name_color = format_chat_player_name(action_player) diff --git a/modules/commands/reports.lua b/modules/commands/reports.lua new file mode 100644 index 00000000..f1c5c670 --- /dev/null +++ b/modules/commands/reports.lua @@ -0,0 +1,69 @@ +local Roles = require 'expcore.roles' +local Commands = require 'expcore.commands' +local ReportsControl = require 'modules.addons.reports-control' +local format_chat_player_name = ext_require('expcore.common','format_chat_player_name') +require 'config.command_parse_general' + +Commands.new_command('report','Reports a player and notifies moderators') +:add_param('player',false,function(input,player,reject) + input = Commands.parse('player',input,player,reject) + if not input then return end + if Roles.player_has_flag(player,'report-immune') then + return reject{'exp-command.report-player-immune'} + else + return input + end +end) +:add_param('reason',false) +:add_alias('report-player') +:enable_auto_concat() +:register(function(player,action_player,reason,raw) + local action_player_name_color = format_chat_player_name(action_player) + local by_player_name_color = format_chat_player_name(player) + if ReportsControl.report_player(action_player,reason,player.name) then + game.print{'exp-commands.report-non-admin',action_player_name_color,reason} + Roles.print_to_roles_higher('Trainee',{'exp-commands.report-admin',action_player_name_color,by_player_name_color,reason}) + else + return Commands.error{'exp-commands.report-already-reported'} + end +end) + +Commands.new_command('get-reports','Gets a list of all reports that a player has on them. If no player then lists all players and the number of reports on them.') +:add_param('player',true,'player') +:add_alias('reports','list-reports') +:register(function(player,action_player,raw) + if action_player then + local reports = ReportsControl.get_player_reports(action_player) + local action_player_name_color = format_chat_player_name(action_player) + Commands.print{'exp-commands.report-player-report-title',action_player_name_color} + for player_name,reason in pairs(reports) do + local by_player_name_color = format_chat_player_name(player_name) + Commands.print{'exp-commands.report-list',by_player_name_color,reason} + end + else + local user_reports = ReportsControl.user_reports + Commands.print{'exp-commands.report-player-count-title'} + for player_name,reports in pairs(user_reports) do + local player_name_color = format_chat_player_name(player_name) + Commands.print{'exp-commands.report-list',player_name_color,#reports} + end + end +end) + +Commands.new_command('clear-reports','Clears all reports from a player or just the report from one player.') +:add_param('player',false,'player') +:add_param('from-player',true,'player') +:register(function(player,action_player,from_player,raw) + if from_player then + if not ReportsControl.remove_player_report(action_player,from_player) then + return Commands.error{'exp-commands.report-not-reported'} + end + else + if not ReportsControl.clear_player_reports(action_player) then + return Commands.error{'exp-commands.report-not-reported'} + end + end + local action_player_name_color = format_chat_player_name(action_player) + local by_player_name_color = format_chat_player_name(player) + game.print{'exp-commands.report-removed',action_player_name_color,by_player_name_color} +end) \ No newline at end of file