2019-01-02 17:34:17 +02:00
|
|
|
local Game = require 'utils.game'
|
|
|
|
local Timestamp = require 'utils.timestamp'
|
|
|
|
local Command = require 'utils.command'
|
2019-02-03 01:10:40 +02:00
|
|
|
local Utils = require 'utils.core'
|
|
|
|
local Server = require 'features.server'
|
2019-02-08 23:55:57 +02:00
|
|
|
local Rank = require 'features.rank_system'
|
|
|
|
local Donator = require 'features.donator'
|
2019-03-03 22:50:19 +02:00
|
|
|
local Color = require 'resources.color_presets'
|
2019-05-31 23:18:19 +02:00
|
|
|
local ScoreTracker = require 'utils.score_tracker'
|
2019-06-01 13:41:12 +02:00
|
|
|
local format_number = require 'util'.format_number
|
2024-10-22 21:22:35 +02:00
|
|
|
local player_data_to_show = storage.config.redmew_commands.whois.player_data_to_show
|
2019-06-01 13:41:12 +02:00
|
|
|
local print_to_player = Game.player_print
|
2019-01-22 22:03:34 +02:00
|
|
|
local concat = table.concat
|
2019-02-02 17:08:09 +02:00
|
|
|
local tostring = tostring
|
|
|
|
local tonumber = tonumber
|
|
|
|
local pairs = pairs
|
2019-05-31 23:18:19 +02:00
|
|
|
local floor = math.floor
|
2021-02-27 21:18:31 +02:00
|
|
|
local Ranks = require 'resources.ranks'
|
2024-08-10 15:36:11 +02:00
|
|
|
local ClearCorpses = require 'features.clear_corpses'
|
2019-01-02 17:34:17 +02:00
|
|
|
|
2019-03-03 22:50:19 +02:00
|
|
|
--- Informs the actor that there is no target. Acts as a central place where this message can be changed.
|
|
|
|
local function print_no_target(target_name)
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'common.fail_no_target', target_name }, Color.fail)
|
2019-03-03 22:50:19 +02:00
|
|
|
end
|
|
|
|
|
2019-01-02 17:34:17 +02:00
|
|
|
--- Kill a player with fish as the cause of death.
|
|
|
|
local function do_fish_kill(player, suicide)
|
|
|
|
local c = player.character
|
|
|
|
if not c then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2024-10-22 21:22:35 +02:00
|
|
|
local e = player.physical_surface.create_entity { name = 'fish', position = player.physical_position }
|
2019-01-02 17:34:17 +02:00
|
|
|
c.die(player.force, e)
|
|
|
|
|
|
|
|
-- Don't want people killing themselves for free fish.
|
|
|
|
if suicide then
|
|
|
|
e.destroy()
|
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Kill a player: admins and the server can kill others, non-admins can only kill themselves
|
|
|
|
local function kill(args, player)
|
2019-03-02 19:20:56 +02:00
|
|
|
local target_ident = args.player
|
2019-03-03 22:50:19 +02:00
|
|
|
local target, target_name = Utils.validate_player(target_ident)
|
|
|
|
if target_ident and not target then
|
2019-01-02 17:34:17 +02:00
|
|
|
if not target then
|
2019-03-03 22:50:19 +02:00
|
|
|
print_no_target(target_ident)
|
2019-01-02 17:34:17 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-03 22:50:19 +02:00
|
|
|
if player then
|
|
|
|
if not target or target == player then -- player suicide
|
2019-01-02 17:34:17 +02:00
|
|
|
if not do_fish_kill(player, true) then
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.kill_fail_suicide_no_character' })
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
2019-03-03 22:50:19 +02:00
|
|
|
elseif target and player.admin then -- admin killing target
|
2019-01-02 17:34:17 +02:00
|
|
|
if not do_fish_kill(target) then
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.kill_fail_target_no_character' }, target_name)
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
2019-03-03 22:50:19 +02:00
|
|
|
else -- player failing to kill target
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.kill_fail_no_perm' })
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
2019-03-03 22:50:19 +02:00
|
|
|
elseif target then -- server killing target
|
2019-01-02 17:34:17 +02:00
|
|
|
if not do_fish_kill(target) then
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.kill_fail_target_no_character' }, target_name)
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Check players' afk times
|
|
|
|
local function afk()
|
|
|
|
local count = 0
|
|
|
|
for _, v in pairs(game.players) do
|
2019-05-31 23:18:19 +02:00
|
|
|
local afk_time = v.afk_time
|
|
|
|
if afk_time > 300 then
|
2019-01-02 17:34:17 +02:00
|
|
|
count = count + 1
|
|
|
|
local time = ' '
|
2019-05-31 23:18:19 +02:00
|
|
|
if afk_time > 21600 then
|
|
|
|
time = time .. floor(afk_time / 216000) .. ' hours '
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
2019-05-31 23:18:19 +02:00
|
|
|
if afk_time > 3600 then
|
|
|
|
time = time .. floor(afk_time / 3600) % 60 .. ' minutes and '
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
2019-05-31 23:18:19 +02:00
|
|
|
time = time .. floor(v.afk_time / 60) % 60 .. ' seconds.'
|
2019-06-01 13:41:12 +02:00
|
|
|
print_to_player(v.name .. ' has been afk for' .. time)
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
if count == 0 then
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.afk_no_afk' })
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Lets a player set their zoom level
|
|
|
|
local function zoom(args, player)
|
2019-03-03 22:50:19 +02:00
|
|
|
local zoom_val = tonumber(args.zoom)
|
|
|
|
if zoom_val then
|
|
|
|
player.zoom = zoom_val
|
2019-01-02 17:34:17 +02:00
|
|
|
else
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.zoom_fail' })
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
--- Creates an alert for the player at the location of their target
|
|
|
|
local function find_player(args, player)
|
2019-03-02 19:20:56 +02:00
|
|
|
local target_ident = args.player
|
2019-03-03 22:50:19 +02:00
|
|
|
local target, target_name = Utils.validate_player(target_ident)
|
2019-01-02 17:34:17 +02:00
|
|
|
|
|
|
|
if not target then
|
2019-03-03 22:50:19 +02:00
|
|
|
print_no_target(target_ident)
|
2019-01-02 17:34:17 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
target = target.character
|
|
|
|
if not target or not target.valid then
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.find_player_fail_no_character', target_name })
|
2019-01-02 17:34:17 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2022-07-03 20:18:29 +02:00
|
|
|
player.add_custom_alert(target, { type = 'virtual', name = 'signal-F' }, target_name, true)
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
--- Turns on rail block visualization for player
|
|
|
|
local function show_rail_block(_, player)
|
|
|
|
local vs = player.game_view_settings
|
|
|
|
local show = not vs.show_rail_block_visualisation
|
|
|
|
vs.show_rail_block_visualisation = show
|
|
|
|
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ 'redmew_commands.show_rail_block_success', tostring(show) })
|
2019-01-02 17:34:17 +02:00
|
|
|
end
|
|
|
|
|
2019-01-29 01:59:28 +02:00
|
|
|
--- Provides the time on the server
|
2019-01-02 17:34:17 +02:00
|
|
|
local function server_time(_, player)
|
|
|
|
local p
|
|
|
|
if not player then
|
|
|
|
p = print
|
|
|
|
elseif player.valid then
|
|
|
|
p = player.print
|
|
|
|
else
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local secs = Server.get_current_time()
|
|
|
|
if secs == nil then
|
2022-07-03 20:18:29 +02:00
|
|
|
p({ 'redmew_commands.server_time_fail' })
|
2019-01-02 17:34:17 +02:00
|
|
|
else
|
|
|
|
p(Timestamp.to_string(secs))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-01-22 22:03:34 +02:00
|
|
|
local function list_seeds()
|
|
|
|
local seeds = {}
|
|
|
|
local count_of_seeds = 0
|
|
|
|
for _, surface in pairs(game.surfaces) do
|
|
|
|
seeds[count_of_seeds + 1] = surface.name
|
|
|
|
seeds[count_of_seeds + 2] = ': '
|
|
|
|
seeds[count_of_seeds + 3] = tostring(surface.map_gen_settings.seed)
|
|
|
|
count_of_seeds = count_of_seeds + 4
|
|
|
|
seeds[count_of_seeds] = ', '
|
|
|
|
end
|
|
|
|
|
|
|
|
seeds[#seeds] = nil
|
|
|
|
seeds = concat(seeds)
|
2019-06-01 13:41:12 +02:00
|
|
|
print_to_player(seeds)
|
2019-01-22 22:03:34 +02:00
|
|
|
end
|
|
|
|
|
2019-01-27 08:27:57 +02:00
|
|
|
local function print_version()
|
2019-01-27 21:40:07 +02:00
|
|
|
local version_str
|
2024-10-22 21:22:35 +02:00
|
|
|
if storage.redmew_version then
|
|
|
|
version_str = storage.redmew_version
|
2019-01-27 21:40:07 +02:00
|
|
|
else
|
2022-07-03 20:18:29 +02:00
|
|
|
version_str = { 'redmew_commands.print_version_from_source' }
|
2019-01-27 21:40:07 +02:00
|
|
|
end
|
2019-06-01 13:41:12 +02:00
|
|
|
print_to_player(version_str)
|
2019-01-27 08:27:57 +02:00
|
|
|
end
|
|
|
|
|
2019-01-29 01:59:28 +02:00
|
|
|
--- Prints information about the target player
|
|
|
|
local function print_player_info(args, player)
|
2019-03-02 19:20:56 +02:00
|
|
|
local target_ident = args.player
|
2019-06-01 13:41:12 +02:00
|
|
|
local target, target_name, player_index = Utils.validate_player(target_ident)
|
2019-03-03 22:50:19 +02:00
|
|
|
|
2019-01-29 01:59:28 +02:00
|
|
|
if not target then
|
2019-03-03 22:50:19 +02:00
|
|
|
print_no_target(target_ident)
|
2019-02-03 01:14:48 +02:00
|
|
|
return
|
2019-01-29 01:59:28 +02:00
|
|
|
end
|
2019-02-03 01:14:48 +02:00
|
|
|
|
2019-06-01 13:41:12 +02:00
|
|
|
local sep = ': '
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ '', { 'common.player_name' }, sep, target_name })
|
|
|
|
print_to_player({ '', { 'common.connection_status' }, sep,
|
|
|
|
{ target.connected and 'common.online' or 'common.offline' } })
|
|
|
|
print_to_player({ '', { 'common.player_index' }, sep, target.index })
|
|
|
|
print_to_player({ '', { 'common.player_rank' }, sep, Rank.get_player_rank_name(target_name) })
|
|
|
|
print_to_player({ '', { 'ranks.donator' }, sep, { Donator.is_donator(target.name) and 'common.yes' or 'common.no' } })
|
|
|
|
print_to_player({ '', { 'common.time_played' }, sep, Utils.format_time(target.online_time) })
|
|
|
|
print_to_player({ '', { 'common.afk_time' }, sep, Utils.format_time(target.afk_time or 0) })
|
|
|
|
print_to_player({ '', { 'common.current_force' }, sep, target.force.name })
|
|
|
|
print_to_player({ '', { 'common.current_surface' }, sep, target.surface.name })
|
|
|
|
print_to_player({ '', { 'common.player_tag' }, sep, target.tag })
|
2019-06-01 13:41:12 +02:00
|
|
|
|
|
|
|
local scores = ScoreTracker.get_player_scores_with_metadata(player_index, player_data_to_show)
|
|
|
|
|
|
|
|
for i = 1, #scores do
|
|
|
|
local score_data = scores[i]
|
2022-07-03 20:18:29 +02:00
|
|
|
print_to_player({ '', score_data.locale_string, sep, format_number(score_data.value, true) })
|
2019-06-01 13:41:12 +02:00
|
|
|
end
|
2019-01-29 01:59:28 +02:00
|
|
|
|
2019-01-31 02:33:11 +02:00
|
|
|
if (not player or player.admin) and args.inventory then
|
2019-05-02 16:53:12 +02:00
|
|
|
local m_inventory = target.get_inventory(defines.inventory.character_main)
|
2019-01-31 02:33:11 +02:00
|
|
|
m_inventory = m_inventory.get_contents()
|
2019-06-01 13:41:12 +02:00
|
|
|
print_to_player('Main and hotbar inventories: ')
|
|
|
|
print_to_player(serpent.line(m_inventory))
|
2019-01-29 01:59:28 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-07-03 20:18:29 +02:00
|
|
|
local function clear_corpses(args, player)
|
2024-08-10 15:36:11 +02:00
|
|
|
ClearCorpses.clear_corpses(player, args)
|
2022-07-03 20:18:29 +02:00
|
|
|
end
|
|
|
|
|
2019-01-08 22:58:12 +02:00
|
|
|
-- Command registrations
|
2019-01-02 17:34:17 +02:00
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'kill',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.kill' },
|
|
|
|
arguments = { 'player' },
|
|
|
|
default_values = { player = false },
|
2019-01-29 01:59:28 +02:00
|
|
|
allowed_by_server = true
|
2019-01-02 17:34:17 +02:00
|
|
|
},
|
|
|
|
kill
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'afk',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.afk' },
|
2019-01-29 01:59:28 +02:00
|
|
|
allowed_by_server = true
|
2019-01-02 17:34:17 +02:00
|
|
|
},
|
|
|
|
afk
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'zoom',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.zoom' },
|
|
|
|
arguments = { 'zoom' },
|
2021-02-27 21:18:31 +02:00
|
|
|
required_rank = Ranks.admin
|
2019-01-02 17:34:17 +02:00
|
|
|
},
|
|
|
|
zoom
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'find',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.find' },
|
|
|
|
arguments = { 'player' }
|
2019-01-02 17:34:17 +02:00
|
|
|
},
|
|
|
|
find_player
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'show-rail-block',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.show_rail_block' }
|
2019-01-02 17:34:17 +02:00
|
|
|
},
|
|
|
|
show_rail_block
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'server-time',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.server_time' },
|
2019-01-29 01:59:28 +02:00
|
|
|
allowed_by_server = true
|
2019-01-02 17:34:17 +02:00
|
|
|
},
|
|
|
|
server_time
|
|
|
|
)
|
|
|
|
|
2019-01-22 22:03:34 +02:00
|
|
|
Command.add(
|
|
|
|
'seeds',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.seeds' },
|
2019-01-29 01:59:28 +02:00
|
|
|
allowed_by_server = true
|
2019-01-22 22:03:34 +02:00
|
|
|
},
|
|
|
|
list_seeds
|
|
|
|
)
|
|
|
|
|
2019-01-27 08:27:57 +02:00
|
|
|
Command.add(
|
|
|
|
'redmew-version',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.redmew_version' },
|
2019-01-29 01:59:28 +02:00
|
|
|
allowed_by_server = true
|
2019-01-27 08:27:57 +02:00
|
|
|
},
|
|
|
|
print_version
|
|
|
|
)
|
|
|
|
|
2019-01-29 01:59:28 +02:00
|
|
|
Command.add(
|
|
|
|
'whois',
|
|
|
|
{
|
2022-07-03 20:18:29 +02:00
|
|
|
description = { 'command_description.whois' },
|
|
|
|
arguments = { 'player', 'inventory' },
|
|
|
|
default_values = { inventory = false },
|
2019-01-29 01:59:28 +02:00
|
|
|
allowed_by_server = true
|
|
|
|
},
|
|
|
|
print_player_info
|
|
|
|
)
|
2022-07-03 20:18:29 +02:00
|
|
|
|
|
|
|
Command.add(
|
2022-12-22 17:56:40 +02:00
|
|
|
'corpses',
|
2022-07-03 20:18:29 +02:00
|
|
|
{
|
|
|
|
description = { 'command_description.clear_corpses' },
|
|
|
|
arguments = { 'surface' },
|
|
|
|
default_values = { surface = '' },
|
|
|
|
required_rank = Ranks.regular
|
|
|
|
},
|
|
|
|
clear_corpses
|
|
|
|
)
|