2019-01-31 00:21:42 +02:00
local Gui = require ' utils.gui '
local Utils = require ' utils.core '
2018-11-18 18:12:00 +02:00
local Game = require ' utils.game '
2019-01-31 00:21:42 +02:00
local Global = require ' utils.global '
local Popup = require ' features.gui.popup '
2018-12-29 19:39:20 +02:00
local Color = require ' resources.color_presets '
2018-11-18 18:12:00 +02:00
2019-01-02 17:34:17 +02:00
local format = string.format
2018-11-18 18:12:00 +02:00
local report_frame_name = Gui.uid_name ( )
local report_close_button_name = Gui.uid_name ( )
local report_tab_button_name = Gui.uid_name ( )
local jail_offender_button_name = Gui.uid_name ( )
local report_body_name = Gui.uid_name ( )
2018-11-18 21:34:18 +02:00
local jail_name = ' Jail '
2019-01-02 17:34:17 +02:00
local default_group = ' Default '
2018-11-18 18:12:00 +02:00
local prefix = ' ------------------NOTICE------------------- '
local prefix_e = ' -------------------------------------------- '
2019-01-02 17:34:17 +02:00
local Module = { }
2019-01-31 00:21:42 +02:00
-- Global registered locals
local report_data = { }
local jail_data = { }
Global.register (
{
report_data = report_data ,
jail_data = jail_data
} ,
function ( tbl )
report_data = tbl.report_data
jail_data = tbl.jail_data
end
)
2018-11-18 18:12:00 +02:00
local function draw_report ( parent , report_id )
2019-01-31 00:21:42 +02:00
local report = report_data [ report_id ]
2018-11-18 18:12:00 +02:00
if report_id == 0 or not report then
2018-11-18 23:26:43 +02:00
parent.add { type = ' label ' , caption = ' No reports yet. ' }
2018-11-18 18:12:00 +02:00
return
end
local reported_player_name = Game.get_player_by_index ( report.reported_player_index ) . name
2018-11-18 23:26:43 +02:00
local reporting_player_name = ' <script> '
2018-11-18 18:12:00 +02:00
if report.reporting_player_index then
2018-11-18 23:26:43 +02:00
reporting_player_name = Game.get_player_by_index ( report.reporting_player_index ) . name
2018-11-18 18:12:00 +02:00
end
local time = Utils.format_time ( report.tick )
local time_ago = Utils.format_time ( game.tick - report.tick )
local message = report.message
Gui.clear ( parent )
2018-11-18 21:34:18 +02:00
local permission_group = game.permissions . get_group ( jail_name )
2018-11-18 23:26:43 +02:00
local jail_offender_button_caption = ( Game.get_player_by_index ( report.reported_player_index ) . permission_group == permission_group ) and ' Unjail ' .. reported_player_name or ' Jail ' .. reported_player_name
2018-11-18 21:34:18 +02:00
2018-11-18 23:26:43 +02:00
parent.add { type = ' label ' , caption = ' Offender: ' .. reported_player_name }
local msg_label_pane = parent.add { type = ' scroll-pane ' , vertical_scroll_policy = ' auto-and-reserve-space ' , horizontal_scroll_policy = ' never ' }
2018-11-18 18:12:00 +02:00
msg_label_pane.style . maximal_height = 400
2018-11-18 23:26:43 +02:00
local msg_label = msg_label_pane.add { type = ' label ' , caption = ' Message: ' .. message }
2018-11-18 21:34:18 +02:00
local jail_offender_button = parent.add { type = ' button ' , name = jail_offender_button_name , caption = jail_offender_button_caption }
2018-11-18 18:12:00 +02:00
jail_offender_button.style . height = 24
jail_offender_button.style . font = ' default-small '
jail_offender_button.style . top_padding = 0
jail_offender_button.style . bottom_padding = 0
jail_offender_button.style . left_padding = 0
jail_offender_button.style . right_padding = 0
msg_label.style . single_line = false
msg_label.style . maximal_width = 680
2018-11-18 23:26:43 +02:00
parent.add { type = ' label ' , caption = string.format ( ' Time: %s (%s ago) ' , time , time_ago ) }
parent.add { type = ' label ' , caption = ' Reported by: ' .. reporting_player_name }
2018-11-18 18:12:00 +02:00
end
2018-11-18 23:26:43 +02:00
Module.show_reports =
function ( player )
2019-01-31 00:21:42 +02:00
local reports = report_data
2018-11-18 18:12:00 +02:00
local center = player.gui . center
local report_frame = center [ report_frame_name ]
if report_frame and report_frame.valid then
Gui.destroy ( report_frame )
end
2018-11-18 23:26:43 +02:00
report_frame =
center.add {
2018-11-18 18:12:00 +02:00
type = ' frame ' ,
name = report_frame_name ,
direction = ' vertical ' ,
caption = ' User reports '
}
report_frame.style . maximal_width = 700
player.opened = report_frame
if # reports > 1 then
2018-11-18 23:26:43 +02:00
local scroll_pane = report_frame.add { type = ' scroll-pane ' , horizontal_scroll_policy = ' auto-and-reserve-space ' , vertical_scroll_policy = ' never ' }
local tab_flow = scroll_pane.add { type = ' flow ' }
for k , report in pairs ( reports ) do
local button_cell = tab_flow.add { type = ' flow ' , caption = ' reportuid ' .. k }
2018-11-18 18:12:00 +02:00
button_cell.add {
2018-11-18 23:26:43 +02:00
type = ' button ' ,
name = report_tab_button_name ,
2018-11-18 18:12:00 +02:00
caption = Game.get_player_by_index ( report.reported_player_index ) . name
}
end
end
2018-11-18 23:26:43 +02:00
local report_body = report_frame.add { type = ' scroll-pane ' , name = report_body_name , horizontal_scroll_policy = ' never ' , vertical_scroll_policy = ' never ' }
2018-11-18 18:12:00 +02:00
report_frame.add { type = ' button ' , name = report_close_button_name , caption = ' Close ' }
draw_report ( report_body , # reports )
end
function Module . report ( reporting_player , reported_player , message )
local player_index
if reporting_player then
player_index = reporting_player.index
2018-12-22 01:37:28 +02:00
reporting_player.print ( ' Your report has been sent. ' )
2018-11-18 18:12:00 +02:00
end
2019-01-31 00:21:42 +02:00
table.insert ( report_data , { reporting_player_index = player_index , reported_player_index = reported_player.index , message = message , tick = game.tick } )
2018-11-18 18:12:00 +02:00
local notified = false
2018-11-18 23:26:43 +02:00
for _ , p in pairs ( game.players ) do
2018-11-18 18:12:00 +02:00
if p.admin and p.connected then
2018-11-18 23:26:43 +02:00
p.play_sound { path = ' utility/tutorial_notice ' , volume_modifier = 1 }
2018-11-18 18:12:00 +02:00
Module.show_reports ( p )
2018-11-18 23:26:43 +02:00
if p.afk_time < 3600 then
notified = true
end
2018-11-18 18:12:00 +02:00
end
end
if not notified then
2018-11-18 23:26:43 +02:00
for _ , p in pairs ( game.players ) do
2018-11-18 18:12:00 +02:00
if p.admin then
Module.show_reports ( p )
end
end
end
end
2019-01-02 17:34:17 +02:00
function Module . report_command ( args , player )
local reported_player_name = args.player
local reported_player = game.players [ reported_player_name ]
2018-11-18 18:12:00 +02:00
2019-01-02 17:34:17 +02:00
if not reported_player then
Game.player_print ( reported_player_name .. ' does not exist. ' )
return nil
2018-11-18 18:12:00 +02:00
end
2019-01-02 17:34:17 +02:00
Module.report ( player , reported_player , args.message )
Game.player_print ( ' Your report has been sent. ' )
2018-11-18 18:12:00 +02:00
end
2019-01-02 17:34:17 +02:00
--- Places a target in jail
-- @param target_player <LuaPlayer> the target to jail
-- @param player <LuaPlayer|nil> the admin as LuaPlayer or server as nil
2018-11-18 18:12:00 +02:00
function Module . jail ( target_player , player )
local print
if player then
print = player.print
else
2018-11-18 22:23:19 +02:00
player = { name = ' server ' }
2018-11-18 18:12:00 +02:00
print = log
end
if not target_player then
print ( ' Unknown player. ' )
return
end
2019-01-31 00:21:42 +02:00
local target_name = target_player.name
2018-11-18 18:12:00 +02:00
local permissions = game.permissions
-- Check if the permission group exists, if it doesn't, create it.
local permission_group = permissions.get_group ( jail_name )
if not permission_group then
permission_group = permissions.create_group ( jail_name )
2018-11-18 21:34:18 +02:00
-- Set all permissions to disabled
for action_name , _ in pairs ( defines.input_action ) do
permission_group.set_allows_action ( defines.input_action [ action_name ] , false )
end
2018-11-18 18:12:00 +02:00
end
2019-01-31 00:21:42 +02:00
local former_permission_group = target_player.permission_group
if former_permission_group == permission_group then
print ( format ( ' Player %s is already in jail. ' , target_name ) )
2018-11-18 18:12:00 +02:00
return
end
2019-01-31 00:21:42 +02:00
-- Enable writing to console to allow a person to speak, and allow them to edit permission group so that an admin can unjail themselves
2018-11-18 18:12:00 +02:00
permission_group.set_allows_action ( defines.input_action . write_to_console , true )
permission_group.set_allows_action ( defines.input_action . edit_permission_group , true )
2018-11-18 23:26:13 +02:00
-- Add player to jail group
permission_group.add_player ( target_player )
2019-01-31 00:21:42 +02:00
-- If in vehicle, kick them out and set the speed to 0.
local vehicle = target_player.vehicle
if vehicle then
vehicle.speed = 0
target_player.driving = false
end
2018-11-18 22:45:02 +02:00
2018-11-18 18:12:00 +02:00
-- If a player is shooting when they're jailed they can't stop shooting, so we change their shooting state
if target_player.shooting_state . state ~= 0 then
2018-11-18 23:26:43 +02:00
target_player.shooting_state . state = { state = defines.shooting . not_shooting , position = { 0 , 0 } }
2018-11-18 18:12:00 +02:00
end
2018-11-18 23:26:43 +02:00
-- Stop player walking while jailed
if target_player.walking_state . walking == true then
2018-11-18 22:49:43 +02:00
target_player.walking_state = { walking = false , direction = defines.direction . north }
2018-11-18 22:24:35 +02:00
end
2019-01-31 00:21:42 +02:00
-- Check they're in jail
2018-11-18 18:12:00 +02:00
if target_player.permission_group == permission_group then
-- Let admin know it worked, let target know what's going on.
2019-01-31 00:21:42 +02:00
target_player.clear_console ( )
Popup.player ( target_player , ' You have been jailed. \n Respond to queries from the mod team. ' )
Utils.print_admins ( format ( ' %s has been jailed by %s ' , target_name , player.name ) )
Utils.log_command ( Utils.get_actor ( ) , ' jail ' , target_name )
local character = target_player.character
local former_char_dest
if character and character.valid then
former_char_dest = character.destructible
character.destructible = false
end
jail_data [ target_player.index ] = {
name = target_name ,
perm_group = former_permission_group ,
char_dest = former_char_dest ,
color = target_player.color ,
chat_color = target_player.chat_color
}
target_player.color = Color.white
target_player.chat_color = Color.white
2018-11-18 18:12:00 +02:00
else
-- Let admin know it didn't work.
2019-01-31 00:21:42 +02:00
print ( format ( ' Something went wrong in the jailing of %s. You can still change their group via /permissions. ' , target_name ) )
2018-11-18 18:12:00 +02:00
end
end
2019-01-02 17:34:17 +02:00
--- Removes a target from jail
-- @param target_player <LuaPlayer> the target to unjail
-- @param player <LuaPlayer|nil> the admin as LuaPlayer or server as nil
function Module . unjail ( target_player , player )
local print
if player then
print = player.print
else
2018-11-18 22:29:05 +02:00
player = { name = ' server ' }
2019-01-02 17:34:17 +02:00
print = log
2018-11-18 18:12:00 +02:00
end
if not target_player then
2019-01-02 17:34:17 +02:00
print ( ' Unknown player. ' )
2018-11-18 18:12:00 +02:00
return
end
2019-01-02 17:34:17 +02:00
local target_name = target_player.name
2019-01-31 00:21:42 +02:00
local target_index = target_player.index
2018-11-18 18:12:00 +02:00
local permissions = game.permissions
2019-01-31 00:21:42 +02:00
local target_jail_data = jail_data [ target_index ]
2018-11-18 18:12:00 +02:00
-- Check if the permission group exists, if it doesn't, create it.
2019-01-31 00:21:42 +02:00
local permission_group = target_jail_data.perm_group or permissions.get_group ( default_group )
2018-11-18 18:12:00 +02:00
if not permission_group then
permission_group = permissions.create_group ( default_group )
end
2019-01-02 17:34:17 +02:00
local jail_permission_group = permissions.get_group ( jail_name )
2018-11-18 18:12:00 +02:00
if ( not jail_permission_group ) or target_player.permission_group ~= jail_permission_group then
2019-01-02 17:34:17 +02:00
Game.player_print ( format ( ' %s is already not in Jail. ' , target_name ) )
2018-11-18 18:12:00 +02:00
return
end
-- Move player
2019-01-02 17:34:17 +02:00
permission_group.add_player ( target_player )
2018-11-18 18:12:00 +02:00
-- Set player to a non-shooting state (solves a niche case where players jailed while shooting will be locked into a shooting state)
target_player.shooting_state . state = 0
2019-01-31 00:21:42 +02:00
-- Restore player's state from stored data
local character = target_player.character
if character and character.valid then
character.destructible = target_jail_data.char_dest
end
target_player.color = target_jail_data.color
target_player.chat_color = target_jail_data.chat_color
jail_data [ target_index ] = nil
2018-11-18 18:12:00 +02:00
-- Check that it worked
if target_player.permission_group == permission_group then
-- Let admin know it worked, let target know what's going on.
2019-01-02 17:34:17 +02:00
Game.player_print ( target_name .. ' has been returned to the default group. They have been advised of this. ' )
2018-11-18 18:12:00 +02:00
target_player.print ( prefix )
2019-02-04 20:17:46 +02:00
target_player.print ( ' Your ability to perform actions has been restored ' , Color.light_green )
2018-11-18 18:12:00 +02:00
target_player.print ( prefix_e )
2019-01-31 00:21:42 +02:00
Utils.print_admins ( format ( ' %s has been released from jail by %s ' , target_name , player.name ) )
Utils.log_command ( Utils.get_actor ( ) , ' unjail ' , target_name )
2018-11-18 18:12:00 +02:00
else
-- Let admin know it didn't work.
2019-01-02 17:34:17 +02:00
Game.player_print ( format ( ' Something went wrong in the unjailing of %s. You can still change their group via /permissions and inform them. ' , target_name ) )
2018-11-18 18:12:00 +02:00
end
end
Gui.on_custom_close (
report_frame_name ,
function ( event )
Gui.destroy ( event.element )
end
)
Gui.on_click (
report_close_button_name ,
function ( event )
Gui.destroy ( event.element . parent )
end
)
Gui.on_click (
jail_offender_button_name ,
function ( event )
local target_name = string.sub ( event.element . caption , 6 )
local target = game.players [ target_name ]
2018-11-18 21:34:18 +02:00
if target then
Module.jail ( target , event.player )
else
target_name = string.sub ( event.element . caption , 8 )
Module.unjail_player ( { [ ' parameter ' ] = target_name , [ ' player ' ] = event.player } )
end
Module.show_reports ( event.player )
Module.show_reports ( event.player ) -- Double toggle, first destroy then draw.
2018-11-18 18:12:00 +02:00
end
)
Gui.on_click (
report_tab_button_name ,
function ( event )
local center = event.player . gui.center
local report_frame = center [ report_frame_name ]
local report_uid_str = string.sub ( event.element . parent.caption , 10 )
local report_uid = tonumber ( report_uid_str )
draw_report ( report_frame [ report_body_name ] , report_uid )
end
)
local reporting_popup_name = Gui.uid_name ( )
local reporting_cancel_button_name = Gui.uid_name ( )
local reporting_submit_button_name = Gui.uid_name ( )
local reporting_input_name = Gui.uid_name ( )
2018-11-18 23:26:43 +02:00
Module.spawn_reporting_popup =
function ( player , reported_player )
2018-11-18 18:12:00 +02:00
local center = player.gui . center
local reporting_popup = center [ reporting_popup_name ]
if reporting_popup and reporting_popup.valid then
Gui.destroy ( reporting_popup )
end
2018-11-18 23:26:43 +02:00
reporting_popup =
center.add {
2018-11-18 18:12:00 +02:00
type = ' frame ' ,
name = reporting_popup_name ,
direction = ' vertical ' ,
caption = ' Report player ' .. reported_player.name
}
Gui.set_data ( reporting_popup , { reported_player_index = reported_player.index } )
reporting_popup.style . maximal_width = 500
player.opened = reporting_popup
reporting_popup.add {
type = ' label ' ,
caption = ' Report message: '
}
2018-11-18 23:26:43 +02:00
local input = reporting_popup.add { type = ' text-box ' , name = reporting_input_name }
2018-11-18 18:12:00 +02:00
input.style . width = 400
input.style . height = 85
2018-11-18 23:26:43 +02:00
local button_flow = reporting_popup.add { type = ' flow ' }
button_flow.add { type = ' button ' , name = reporting_submit_button_name , caption = ' Submit ' }
button_flow.add { type = ' button ' , name = reporting_cancel_button_name , caption = ' Cancel ' }
2018-11-18 18:12:00 +02:00
end
Gui.on_custom_close (
reporting_popup_name ,
function ( event )
Gui.destroy ( event.element )
end
)
Gui.on_click (
reporting_cancel_button_name ,
function ( event )
local frame = event.element . parent.parent
Gui.destroy ( frame )
end
)
Gui.on_click (
reporting_submit_button_name ,
function ( event )
local frame = event.element . parent.parent
local msg = frame [ reporting_input_name ] . text
local data = Gui.get_data ( frame )
2018-11-18 23:26:43 +02:00
local reported_player_index = data [ ' reported_player_index ' ]
2018-11-18 18:12:00 +02:00
local print = event.player . print
Gui.destroy ( frame )
Module.report ( event.player , Game.get_player_by_index ( reported_player_index ) , msg )
print ( prefix )
2019-01-02 17:34:17 +02:00
print ( ' You have successfully reported: ' .. Game.get_player_by_index ( reported_player_index ) . name )
2018-11-18 18:12:00 +02:00
print ( prefix_e )
end
)
return Module