mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-11-06 09:09:26 +02:00
Overhaul commands (#576)
* Split admin-only commands out of custom commands Remove free item logging * Overhaul commands remaining in custom_commands * Overhaul commands in remaining files * Change custom_commands to redmew_commands * Remove follow.lua
This commit is contained in:
11
config.lua
11
config.lua
@@ -170,7 +170,11 @@ global.config = {
|
||||
enabled = true,
|
||||
},
|
||||
-- adds many commands for users and admins alike
|
||||
custom_commands = {
|
||||
redmew_commands = {
|
||||
enabled = true,
|
||||
},
|
||||
-- adds many commands for admins
|
||||
admin_commands = {
|
||||
enabled = true,
|
||||
},
|
||||
-- enables donators' on-join messages
|
||||
@@ -181,11 +185,6 @@ global.config = {
|
||||
train_saviour = {
|
||||
enabled = true,
|
||||
},
|
||||
-- logs when commands are used and when items are spawned in
|
||||
free_item_logging = {
|
||||
enabled = true,
|
||||
},
|
||||
-- adds ability to save and restore player colors
|
||||
player_colors = {
|
||||
enabled = true,
|
||||
},
|
||||
|
||||
10
control.lua
10
control.lua
@@ -26,8 +26,11 @@ end
|
||||
if config.corpse_util.enabled then
|
||||
require 'features.corpse_util'
|
||||
end
|
||||
if config.custom_commands.enabled then
|
||||
require 'features.custom_commands'
|
||||
if config.admin_commands.enabled then
|
||||
require 'features.admin_commands'
|
||||
end
|
||||
if config.redmew_commands.enabled then
|
||||
require 'features.redmew_commands'
|
||||
end
|
||||
if config.donator_messages.enabled then
|
||||
require 'features.donator_messages'
|
||||
@@ -38,9 +41,6 @@ end
|
||||
if config.fish_market.enabled then
|
||||
require 'features.fish_market'
|
||||
end
|
||||
if config.free_item_logging.enabled then
|
||||
require 'features.free_item_logging'
|
||||
end
|
||||
if config.nuke_control.enabled then
|
||||
require 'features.nuke_control'
|
||||
end
|
||||
|
||||
402
features/admin_commands.lua
Normal file
402
features/admin_commands.lua
Normal file
@@ -0,0 +1,402 @@
|
||||
local Task = require 'utils.schedule'
|
||||
local Token = require 'utils.token'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local Report = require 'features.report'
|
||||
local Utils = require 'utils.core'
|
||||
local Game = require 'utils.game'
|
||||
local Event = require 'utils.event'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local format = string.format
|
||||
|
||||
--- A table of players with tpmode turned on
|
||||
global.tp_players = {}
|
||||
|
||||
--- Sends a message to all online admins
|
||||
local function admin_chat(args, player)
|
||||
Utils.print_admins(args.msg, player)
|
||||
end
|
||||
|
||||
--- Runs a command silently. Traps and prints errors for the player/server
|
||||
local function silent_command(args, player)
|
||||
local p
|
||||
if player then
|
||||
p = player.print
|
||||
else
|
||||
p = print
|
||||
end
|
||||
|
||||
local func, err = loadstring(args.str)
|
||||
if not func then
|
||||
p(err)
|
||||
end
|
||||
|
||||
local _, err2 = pcall(func)
|
||||
if err2 then
|
||||
local i = err2:find('\n')
|
||||
p(err2:sub(1, i))
|
||||
end
|
||||
end
|
||||
|
||||
--- Toggles cheat mode for a player
|
||||
local function toggle_cheat_mode(_, player)
|
||||
player.cheat_mode = not player.cheat_mode
|
||||
Game.player_print('Cheat mode set to ' .. tostring(player.cheat_mode))
|
||||
end
|
||||
|
||||
--- Enables all researches for a player's force
|
||||
local function all_tech(_, player)
|
||||
player.force.research_all_technologies()
|
||||
Game.player_print('Your force has been granted all technologies')
|
||||
end
|
||||
|
||||
--- Add or remove someone from the list of regulars
|
||||
local function regular(args)
|
||||
local add_target = args['name|remove']
|
||||
local remove_target = args['name']
|
||||
|
||||
if remove_target and add_target == 'remove' then
|
||||
UserGroups.remove_regular(remove_target)
|
||||
else
|
||||
UserGroups.add_regular(add_target)
|
||||
end
|
||||
end
|
||||
|
||||
--- Displays reported players
|
||||
local function show_reports(_, player)
|
||||
Report.show_reports(player)
|
||||
end
|
||||
|
||||
--- Places a target in jail (a permissions group which is unable to act aside from chatting)
|
||||
local function jail_player(args, player)
|
||||
-- Check if the target is valid
|
||||
local target = game.players[args.player]
|
||||
Report.jail(target, player)
|
||||
end
|
||||
|
||||
--- Removes a target from jail
|
||||
local function unjail_player(args, player)
|
||||
-- Check if the target is valid
|
||||
local target = game.players[args.player]
|
||||
Report.unjail(target, player)
|
||||
end
|
||||
|
||||
--- Checks if we have a permission group named 'banned' and if we don't, create it
|
||||
local function get_tempban_group()
|
||||
local group = game.permissions.get_group('Banned')
|
||||
if not group then
|
||||
game.permissions.create_group('Banned')
|
||||
group = game.permissions.get_group('Banned')
|
||||
if group then
|
||||
for i = 2, 174 do
|
||||
group.set_allows_action(i, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
return group
|
||||
end
|
||||
|
||||
--- Removes player from the tempban list (by changing them back to the default permissions group)
|
||||
local redmew_commands_untempban =
|
||||
Token.register(
|
||||
function(param)
|
||||
game.print(param.name .. ' is out of timeout.')
|
||||
game.permissions.get_group('Default').add_player(param.name)
|
||||
end
|
||||
)
|
||||
|
||||
--- Gives a player a temporary ban
|
||||
local function tempban(args, player)
|
||||
local target_name = args.player
|
||||
local target = game.players[target_name]
|
||||
local duration = args.minutes
|
||||
if not target then
|
||||
Game.player_print("Player doesn't exist.")
|
||||
return
|
||||
end
|
||||
if not tonumber(duration) then
|
||||
Game.player_print('Tempban failed. Minutes must be a number.')
|
||||
return
|
||||
end
|
||||
|
||||
local group = get_tempban_group()
|
||||
local actor
|
||||
if player then
|
||||
actor = player.name
|
||||
else
|
||||
actor = 'server'
|
||||
end
|
||||
game.print(format('%s put %s in timeout for %s minutes.', actor, target_name, duration))
|
||||
if group then
|
||||
group.add_player(target_name)
|
||||
Task.set_timeout(60 * tonumber(duration), redmew_commands_untempban, {name = target_name})
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a rectangle of water below an admin
|
||||
local function pool(_, player)
|
||||
local t = {}
|
||||
local p = player.position
|
||||
for x = p.x - 3, p.x + 3 do
|
||||
for y = p.y + 2, p.y + 7 do
|
||||
table.insert(t, {name = 'water', position = {x, y}})
|
||||
end
|
||||
end
|
||||
player.surface.set_tiles(t)
|
||||
player.surface.create_entity {name = 'fish', position = {p.x + 0.5, p.y + 5}}
|
||||
end
|
||||
|
||||
--- Takes a target and teleports them to player
|
||||
local function invoke(args, player)
|
||||
local target = game.players[args.player]
|
||||
if not target then
|
||||
Game.player_print('Unknown player.')
|
||||
return
|
||||
end
|
||||
local pos = player.surface.find_non_colliding_position('player', player.position, 50, 1)
|
||||
if not pos then
|
||||
Game.player_print('Unable to find suitable location to teleport to.')
|
||||
return
|
||||
end
|
||||
target.teleport({pos.x, pos.y}, player.surface)
|
||||
game.print(args.player .. ', get your ass over here!')
|
||||
end
|
||||
|
||||
--- Takes a target and teleports player to target. (admin only)
|
||||
local function teleport_player(args, player)
|
||||
local target_name = args.player
|
||||
local target
|
||||
if target_name then
|
||||
target = game.players[target_name]
|
||||
end
|
||||
if not target then
|
||||
Game.player_print('Unknown player.')
|
||||
return
|
||||
end
|
||||
local surface = target.surface
|
||||
local pos = surface.find_non_colliding_position('player', target.position, 50, 1)
|
||||
if not pos then
|
||||
Game.player_print('Unable to find suitable location to teleport to.')
|
||||
return
|
||||
end
|
||||
player.teleport(pos, surface)
|
||||
game.print(target_name .. "! watcha doin'?!")
|
||||
Game.player_print('You have teleported to ' .. target_name)
|
||||
end
|
||||
|
||||
--- Takes a selected entity and teleports player to it
|
||||
local function teleport_location(_, player)
|
||||
if not player.selected then
|
||||
Game.player_print('No entity under cursor.')
|
||||
return
|
||||
end
|
||||
local pos = player.surface.find_non_colliding_position('player', player.selected.position, 50, 1)
|
||||
if not pos then
|
||||
Game.player_print('Unable to find suitable location to teleport to.')
|
||||
return
|
||||
end
|
||||
player.teleport(pos)
|
||||
Game.player_print('Teleporting to your selected entity.')
|
||||
end
|
||||
|
||||
--- If a player is in the global.tp_players list, remove ghosts they place and teleport them to that position
|
||||
local function built_entity(event)
|
||||
local index = event.player_index
|
||||
|
||||
if global.tp_players[index] then
|
||||
local entity = event.created_entity
|
||||
|
||||
if not entity or not entity.valid or entity.type ~= 'entity-ghost' then
|
||||
return
|
||||
end
|
||||
|
||||
Game.get_player_by_index(index).teleport(entity.position)
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
--- Adds/removes players from the tp_players table (admin only)
|
||||
local function toggle_tp_mode(_, player)
|
||||
local index = player.index
|
||||
local toggled = global.tp_players[index]
|
||||
|
||||
if toggled then
|
||||
global.tp_players[index] = nil
|
||||
Game.player_print('tp mode is now off')
|
||||
else
|
||||
global.tp_players[index] = true
|
||||
Game.player_print('tp mode is now on - place a ghost entity to teleport there.')
|
||||
end
|
||||
end
|
||||
|
||||
--- Takes argument from the tp command and calls the appropriate function
|
||||
local function teleport_command(args, player)
|
||||
local arg = args['mode|player']
|
||||
if not arg then
|
||||
teleport_location(nil, player)
|
||||
elseif arg == 'mode' then
|
||||
toggle_tp_mode(nil, player)
|
||||
else
|
||||
teleport_player({player = arg}, player)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_built_entity, built_entity)
|
||||
|
||||
Command.add(
|
||||
'a',
|
||||
{
|
||||
description = 'Admin chat. Messages all other admins.',
|
||||
arguments = {'msg'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
admin_chat
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'sc',
|
||||
{
|
||||
description = 'silent-command',
|
||||
arguments = {'str'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
silent_command
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'hax',
|
||||
{
|
||||
description = 'Toggles your hax (makes recipes cost nothing)',
|
||||
admin_only = true
|
||||
},
|
||||
toggle_cheat_mode
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'all-tech',
|
||||
{
|
||||
description = 'researches all technologies',
|
||||
admin_only = true,
|
||||
debug_only = true,
|
||||
cheat_only = true
|
||||
},
|
||||
all_tech
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'regular',
|
||||
{
|
||||
description = 'Add/remove player from regualrs. Use /regular <name> to add or /regular remove <name> to remove.',
|
||||
arguments = {'name|remove', 'name'},
|
||||
default_values = {['name'] = false},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = false,
|
||||
allowed_by_server = false
|
||||
},
|
||||
regular
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'showreports',
|
||||
{
|
||||
description = 'Shows user reports',
|
||||
admin_only = true
|
||||
},
|
||||
show_reports
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'jail',
|
||||
{
|
||||
description = 'Puts a player in jail',
|
||||
arguments = {'player'},
|
||||
admin_only = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
jail_player
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'unjail',
|
||||
{
|
||||
description = 'Removes a player from jail',
|
||||
arguments = {'player'},
|
||||
admin_only = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
unjail_player
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'tempban',
|
||||
{
|
||||
description = 'Temporarily bans a player',
|
||||
arguments = {'player', 'minutes'},
|
||||
admin_only = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
tempban
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'pool',
|
||||
{
|
||||
description = 'Spawns a pool of water',
|
||||
admin_only = true
|
||||
},
|
||||
pool
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'invoke',
|
||||
{
|
||||
description = 'Teleports the player to you.',
|
||||
arguments = {'player'},
|
||||
admin_only = true
|
||||
},
|
||||
invoke
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'tp',
|
||||
{
|
||||
description = 'if blank, teleport to selected entity. mode = toggle tp mode where you can teleport to a placed ghost. player = teleport to player.',
|
||||
arguments = {'mode|player'},
|
||||
default_values = {['mode|player'] = false},
|
||||
admin_only = true,
|
||||
custom_help_text = '<blank|mode|player> 3 different uses: "/tp" to tp to selected entity. "/tp mode" to toggle tp mode. "/tp Newcott" to tp to Newcott'
|
||||
},
|
||||
teleport_command
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'tpplayer',
|
||||
{
|
||||
description = 'Teleports you to the player',
|
||||
arguments = {'player'},
|
||||
admin_only = true
|
||||
},
|
||||
teleport_player
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'tppos',
|
||||
{
|
||||
description = 'Teleports you to a selected entity.',
|
||||
admin_only = true
|
||||
},
|
||||
teleport_location
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'tpmode',
|
||||
{
|
||||
description = 'Toggles tp mode. When on place a ghost entity to teleport there',
|
||||
admin_only = true
|
||||
},
|
||||
toggle_tp_mode
|
||||
)
|
||||
@@ -1,628 +0,0 @@
|
||||
local Task = require 'utils.schedule'
|
||||
local Event = require 'utils.event'
|
||||
local Token = require 'utils.token'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local Utils = require 'utils.core'
|
||||
local Game = require 'utils.game'
|
||||
local Report = require 'features.report'
|
||||
local Server = require 'features.server'
|
||||
local Timestamp = require 'utils.timestamp'
|
||||
local Command = require 'utils.command'
|
||||
local format = string.format
|
||||
local ceil = math.ceil
|
||||
|
||||
local deprecated_command_alternatives = {
|
||||
['silent-command'] = 'sc'
|
||||
}
|
||||
|
||||
Event.add(defines.events.on_console_command, function (event)
|
||||
local alternative = deprecated_command_alternatives[event.command]
|
||||
if alternative then
|
||||
local print = log
|
||||
if event.player_index then
|
||||
print = Game.get_player_by_index(event.player_index).print
|
||||
end
|
||||
print(string.format('Warning! Usage of the command "/%s" is deprecated. Please use "%s" instead.', event.command, alternative))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--- Takes a target and teleports them to player. (admin only)
|
||||
local function invoke(cmd)
|
||||
if not (game.player and game.player.admin) then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local target = cmd['parameter']
|
||||
if target == nil or game.players[target] == nil then
|
||||
Game.player_print('Unknown player.')
|
||||
return
|
||||
end
|
||||
local pos = game.player.surface.find_non_colliding_position('player', game.player.position, 0, 1)
|
||||
game.players[target].teleport({pos.x, pos.y}, game.player.surface)
|
||||
game.print(target .. ', get your ass over here!')
|
||||
end
|
||||
|
||||
--- Takes a target and teleports player to target. (admin only)
|
||||
local function teleport_player(cmd)
|
||||
if not (game.player and game.player.admin) then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local target = cmd['parameter']
|
||||
if target == nil or game.players[target] == nil then
|
||||
Game.player_print('Unknown player.')
|
||||
return
|
||||
end
|
||||
local surface = game.players[target].surface
|
||||
local pos = surface.find_non_colliding_position('player', game.players[target].position, 0, 1)
|
||||
game.player.teleport(pos, surface)
|
||||
game.print(target .. "! watcha doin'?!")
|
||||
game.player.print('You have teleported to ' .. game.players[target].name)
|
||||
end
|
||||
|
||||
--- Takes a selected entity and teleports player to entity. (admin only)
|
||||
local function teleport_location(cmd)
|
||||
if not (game.player and game.player.admin) then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
if game.player.selected == nil then
|
||||
Game.player_print('Nothing selected.')
|
||||
return
|
||||
end
|
||||
local pos = game.player.surface.find_non_colliding_position('player', game.player.selected.position, 0, 1)
|
||||
game.player.teleport(pos)
|
||||
end
|
||||
|
||||
--- 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
|
||||
|
||||
local e = player.surface.create_entity {name = 'fish', position = player.position}
|
||||
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(cmd)
|
||||
local player = game.player
|
||||
local param = cmd.parameter
|
||||
local target
|
||||
if param then
|
||||
target = game.players[param]
|
||||
if not target then
|
||||
Game.player_print(table.concat {"Sorry, player '", param, "' was not found."})
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if global.walking then
|
||||
if (player and global.walking[player.index]) or (target and global.walking[target.index]) then
|
||||
Game.player_print("A player on walkabout cannot be killed by a mere fish, don't waste your efforts.")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if not target and player then
|
||||
if not do_fish_kill(player, true) then
|
||||
Game.player_print("Sorry, you don't have a character to kill.")
|
||||
end
|
||||
elseif player then
|
||||
if target == player then
|
||||
if not do_fish_kill(player, true) then
|
||||
Game.player_print("Sorry, you don't have a character to kill.")
|
||||
end
|
||||
elseif target and player.admin then
|
||||
if not do_fish_kill(target) then
|
||||
Game.player_print(table.concat {"'Sorry, '", target.name, "' doesn't have a character to kill."})
|
||||
end
|
||||
else
|
||||
Game.player_print("Sorry you don't have permission to use the kill command on other players.")
|
||||
end
|
||||
elseif target then
|
||||
if not do_fish_kill(target) then
|
||||
Game.player_print(table.concat {"'Sorry, '", target.name, "' doesn't have a character to kill."})
|
||||
end
|
||||
else
|
||||
if param then
|
||||
Game.player_print(table.concat {"Sorry, player '", param, "' was not found."})
|
||||
else
|
||||
Game.player_print('Usage: /kill <player>')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function regular(cmd)
|
||||
if game.player and not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
return
|
||||
end
|
||||
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
if #params == 2 then
|
||||
if params[1] == 'promote' then
|
||||
UserGroups.add_regular(params[2])
|
||||
elseif params[1] == 'demote' then
|
||||
UserGroups.remove_regular(params[2])
|
||||
else
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
end
|
||||
elseif #params == 1 and params[1] ~= 'promote' and params[1] ~= 'demote' then
|
||||
UserGroups.add_regular(params[1])
|
||||
else
|
||||
Game.player_print('Command failed. Usage: /regular <promote, demote>, <player>')
|
||||
end
|
||||
end
|
||||
|
||||
--- Check players' afk times
|
||||
local function afk()
|
||||
for _, v in pairs(game.players) do
|
||||
if v.afk_time > 300 then
|
||||
local time = ' '
|
||||
if v.afk_time > 21600 then
|
||||
time = time .. math.floor(v.afk_time / 216000) .. ' hours '
|
||||
end
|
||||
if v.afk_time > 3600 then
|
||||
time = time .. math.floor(v.afk_time / 3600) % 60 .. ' minutes and '
|
||||
end
|
||||
time = time .. math.floor(v.afk_time / 60) % 60 .. ' seconds.'
|
||||
Game.player_print(v.name .. ' has been afk for' .. time)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Follows a player
|
||||
local function follow(cmd)
|
||||
if not game.player then
|
||||
log("<Server can't do that.")
|
||||
return
|
||||
end
|
||||
if cmd.parameter ~= nil and game.players[cmd.parameter] ~= nil then
|
||||
global.follows[game.player.name] = cmd.parameter
|
||||
global.follows.n_entries = global.follows.n_entries + 1
|
||||
else
|
||||
Game.player_print(
|
||||
'Usage: /follow <player> makes you follow the player. Use /unfollow to stop following a player.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--- Stops following a player
|
||||
local function unfollow()
|
||||
if not game.player then
|
||||
log("<Server can't do that.")
|
||||
return
|
||||
end
|
||||
if global.follows[game.player.name] ~= nil then
|
||||
global.follows[game.player.name] = nil
|
||||
global.follows.n_entries = global.follows.n_entries - 1
|
||||
end
|
||||
end
|
||||
|
||||
--- A table of players with tpmode turned on
|
||||
global.tp_players = {}
|
||||
|
||||
--- If a player is in the global.tp_players list, remove ghosts they place and teleport them to that position
|
||||
local function built_entity(event)
|
||||
local index = event.player_index
|
||||
|
||||
if global.tp_players[index] then
|
||||
local entity = event.created_entity
|
||||
|
||||
if not entity or not entity.valid or entity.type ~= 'entity-ghost' then
|
||||
return
|
||||
end
|
||||
|
||||
Game.get_player_by_index(index).teleport(entity.position)
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
Event.add(defines.events.on_built_entity, built_entity)
|
||||
|
||||
--- Adds/removes players from the tp_players table (admin only)
|
||||
local function toggle_tp_mode(cmd)
|
||||
if not (game.player and game.player.admin) then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
|
||||
local index = game.player.index
|
||||
local toggled = global.tp_players[index]
|
||||
|
||||
if toggled then
|
||||
global.tp_players[index] = nil
|
||||
Game.player_print('tp mode is now off')
|
||||
else
|
||||
global.tp_players[index] = true
|
||||
Game.player_print('tp mode is now on - place a ghost entity to teleport there.')
|
||||
end
|
||||
end
|
||||
|
||||
--- Checks if we have a permission group named 'banned' and if we don't, create it
|
||||
local function get_group()
|
||||
local group = game.permissions.get_group('Banned')
|
||||
if not group then
|
||||
game.permissions.create_group('Banned')
|
||||
group = game.permissions.get_group('Banned')
|
||||
if group then
|
||||
for i = 2, 174 do
|
||||
group.set_allows_action(i, false)
|
||||
end
|
||||
else
|
||||
game.print(
|
||||
'This would have nearly crashed the server, please consult the next best scenario dev (valansch or TWLtriston).'
|
||||
)
|
||||
end
|
||||
end
|
||||
return group
|
||||
end
|
||||
|
||||
--- Removes player from the tempban list (by changing them back to the default permissions group)
|
||||
local custom_commands_untempban =
|
||||
Token.register(
|
||||
function(param)
|
||||
game.print(param.name .. ' is out of timeout.')
|
||||
game.permissions.get_group('Default').add_player(param.name)
|
||||
end
|
||||
)
|
||||
|
||||
--- Gives a player a temporary ban
|
||||
local function tempban(cmd)
|
||||
if (not game.player) or not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Tempban failed. Usage: /tempban <player> <minutes> Temporarily bans a player.')
|
||||
return
|
||||
end
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
if #params < 2 or not tonumber(params[2]) then
|
||||
Game.player_print('Tempban failed. Usage: /tempban <player> <minutes> Temporarily bans a player.')
|
||||
return
|
||||
end
|
||||
if not game.players[params[1]] then
|
||||
Game.player_print("Player doesn't exist.")
|
||||
return
|
||||
end
|
||||
local group = get_group()
|
||||
|
||||
game.print(Utils.get_actor() .. ' put ' .. params[1] .. ' in timeout for ' .. params[2] .. ' minutes.')
|
||||
if group then
|
||||
group.add_player(params[1])
|
||||
if not tonumber(cmd.parameter) then
|
||||
Task.set_timeout(60 * tonumber(params[2]), custom_commands_untempban, {name = params[1]})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local custom_commands_replace_ghosts =
|
||||
Token.register(
|
||||
function(param)
|
||||
for _, ghost in pairs(param.ghosts) do
|
||||
local new_ghost =
|
||||
game.surfaces[param.surface_index].create_entity {
|
||||
name = 'entity-ghost',
|
||||
position = ghost.position,
|
||||
inner_name = ghost.ghost_name,
|
||||
expires = false,
|
||||
force = 'enemy',
|
||||
direction = ghost.direction
|
||||
}
|
||||
new_ghost.last_user = ghost.last_user
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--- Lets a player set their zoom level
|
||||
local function zoom(cmd)
|
||||
if game.player and cmd and cmd.parameter and tonumber(cmd.parameter) then
|
||||
game.player.zoom = tonumber(cmd.parameter)
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a rectangle of water below an admin
|
||||
local function pool(cmd)
|
||||
if game.player and game.player.admin then
|
||||
local t = {}
|
||||
local p = game.player.position
|
||||
for x = p.x - 3, p.x + 3 do
|
||||
for y = p.y + 2, p.y + 7 do
|
||||
table.insert(t, {name = 'water', position = {x, y}})
|
||||
end
|
||||
end
|
||||
game.player.surface.set_tiles(t)
|
||||
game.player.surface.create_entity {name = 'fish', position = {p.x + 0.5, p.y + 5}}
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates an alert for the player at the location of their target
|
||||
local function find_player(cmd)
|
||||
local player = game.player
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local name = cmd.parameter
|
||||
if not name then
|
||||
player.print('Usage: /find-player <player>')
|
||||
return
|
||||
end
|
||||
|
||||
local target = game.players[name]
|
||||
if not target then
|
||||
player.print('player ' .. name .. ' not found')
|
||||
return
|
||||
end
|
||||
|
||||
target = target.character
|
||||
if not target or not target.valid then
|
||||
player.print('player ' .. name .. ' does not have a character')
|
||||
return
|
||||
end
|
||||
|
||||
player.add_custom_alert(target, {type = 'virtual', name = 'signal-F'}, name, true)
|
||||
end
|
||||
|
||||
--- Places a target in jail (a permissions group which is unable to act aside from chatting)(admin only)
|
||||
local function jail_player(cmd)
|
||||
local player = game.player
|
||||
-- Check if the player can run the command
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
-- Check if the target is valid
|
||||
local target_name = cmd['parameter']
|
||||
if not target_name then
|
||||
Game.player_print('Usage: /jail <player>')
|
||||
return
|
||||
end
|
||||
local target = game.players[target_name]
|
||||
Report.jail(target, player)
|
||||
end
|
||||
|
||||
local function all_tech()
|
||||
if game.player then
|
||||
game.player.force.research_all_technologies()
|
||||
Game.player_print('Your force has been granted all technologies')
|
||||
end
|
||||
end
|
||||
|
||||
--- Traps errors if not in DEBUG.
|
||||
if not _DEBUG then
|
||||
local old_add_command = commands.add_command
|
||||
commands.add_command =
|
||||
function(name, desc, func)
|
||||
old_add_command(
|
||||
name,
|
||||
desc,
|
||||
function(cmd)
|
||||
local success, error = pcall(func, cmd)
|
||||
if not success then
|
||||
log(error)
|
||||
Game.player_print('Sorry there was an error running ' .. cmd.name)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--- Sends a message to all online admins
|
||||
local function admin_chat(cmd)
|
||||
if not game.player then -- server
|
||||
Utils.print_admins(cmd.parameter, false)
|
||||
elseif game.player.admin then --admin
|
||||
Utils.print_admins(cmd.parameter, game.player)
|
||||
else
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--- Turns on rail block visualization for player
|
||||
local function show_rail_block()
|
||||
local player = game.player
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
local vs = player.game_view_settings
|
||||
local show = not vs.show_rail_block_visualisation
|
||||
vs.show_rail_block_visualisation = show
|
||||
|
||||
player.print('show_rail_block_visualisation set to ' .. tostring(show))
|
||||
end
|
||||
|
||||
local function server_time()
|
||||
local player = game.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
|
||||
p('Server time is not available, is this game running on a Redmew server?')
|
||||
else
|
||||
p(Timestamp.to_string(secs))
|
||||
end
|
||||
end
|
||||
|
||||
--- Add all commands to command list
|
||||
if _DEBUG or _CHEATS then
|
||||
commands.add_command('all-tech', 'researches all technologies (debug only)', all_tech)
|
||||
end
|
||||
|
||||
Command.add(
|
||||
'sc',
|
||||
{
|
||||
description = 'silent-command',
|
||||
arguments = {'str'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true,
|
||||
allowed_by_player = true
|
||||
},
|
||||
function(args, player)
|
||||
local p
|
||||
if player then
|
||||
p = player.print
|
||||
else
|
||||
p = print
|
||||
end
|
||||
|
||||
local func, err = loadstring(args.str)
|
||||
if not func then
|
||||
p(err)
|
||||
end
|
||||
|
||||
local _, err2 = pcall(func)
|
||||
if err2 then
|
||||
local i = err2:find('\n')
|
||||
p(err2:sub(1, i))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--- Enables cheat mode (free pocket crafting) for player
|
||||
commands.add_command(
|
||||
'hax',
|
||||
'Toggles your hax (makes recipes cost nothing)',
|
||||
function()
|
||||
if game.player and game.player.admin then
|
||||
game.player.cheat_mode = not game.player.cheat_mode
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
--- Show reports coming from users
|
||||
commands.add_command(
|
||||
'showreports',
|
||||
'Shows user reports (Admins only)',
|
||||
function(event)
|
||||
if game.player and game.player.admin then
|
||||
Report.show_reports(Game.get_player_by_index(event.player_index))
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command('kill', 'Will kill you.', kill)
|
||||
commands.add_command('tpplayer', '<player> - Teleports you to the player. (Admins only)', teleport_player)
|
||||
commands.add_command('invoke', '<player> - Teleports the player to you. (Admins only)', invoke)
|
||||
commands.add_command('tppos', 'Teleports you to a selected entity. (Admins only)', teleport_location)
|
||||
commands.add_command('regulars', 'Prints a list of game regulars.', UserGroups.print_regulars)
|
||||
commands.add_command('regular', '<promote, demote>, <player> Change regular status of a player. (Admins only)', regular)
|
||||
commands.add_command('afk', 'Shows how long players have been afk.', afk)
|
||||
commands.add_command(
|
||||
'follow',
|
||||
'<player> makes you follow the player. Use /unfollow to stop following a player.',
|
||||
follow
|
||||
)
|
||||
commands.add_command('unfollow', 'stops following a player.', unfollow)
|
||||
commands.add_command(
|
||||
'tpmode',
|
||||
'Toggles tp mode. When on place a ghost entity to teleport there (Admins only)',
|
||||
toggle_tp_mode
|
||||
)
|
||||
commands.add_command('tempban', '<player> <minutes> Temporarily bans a player (Admins only)', tempban)
|
||||
commands.add_command('zoom', '<number> Sets your zoom.', zoom)
|
||||
commands.add_command('pool', 'Spawns a pool', pool)
|
||||
commands.add_command('find', '<player> shows an alert on the map where the player is located', find_player)
|
||||
commands.add_command(
|
||||
'jail',
|
||||
'<player> disables all actions a player can perform except chatting. (Admins only)',
|
||||
jail_player
|
||||
)
|
||||
commands.add_command(
|
||||
'unjail',
|
||||
'<player> restores ability for a player to perform actions. (Admins only)',
|
||||
Report.unjail_player
|
||||
)
|
||||
commands.add_command('a', 'Admin chat. Messages all other admins (Admins only)', admin_chat)
|
||||
commands.add_command('report', '<griefer-name> <message> Reports a user to admins', Report.cmd_report)
|
||||
commands.add_command('show-rail-block', 'Toggles rail block visualisation', show_rail_block)
|
||||
commands.add_command('server-time', "Prints the server's time", server_time)
|
||||
|
||||
--[[ commands.add_command('undo', '<player> undoes everything a player has done (Admins only)', undo)
|
||||
commands.add_command(
|
||||
'antigrief_surface',
|
||||
'moves you to the antigrief surface or back (Admins only)',
|
||||
antigrief_surface_tp
|
||||
) ]]
|
||||
|
||||
Command.add('search-command', {
|
||||
description = 'Search for commands matching the keyword in name or description',
|
||||
arguments = {'keyword', 'page'},
|
||||
default_values = {page = 1},
|
||||
}, function (arguments, player)
|
||||
local keyword = arguments.keyword
|
||||
local p = player.print
|
||||
if #keyword < 2 then
|
||||
p('Keyword should be 2 characters or more')
|
||||
return
|
||||
end
|
||||
|
||||
local per_page = 7
|
||||
local matches = Command.search(keyword)
|
||||
local count = #matches
|
||||
|
||||
if count == 0 then
|
||||
p('---- 0 Search Results ----')
|
||||
p(format('No commands found matching "%s"', keyword))
|
||||
p('-------------------------')
|
||||
return
|
||||
end
|
||||
|
||||
local page = tonumber(arguments.page)
|
||||
local pages = ceil(count / per_page)
|
||||
|
||||
if nil == page then
|
||||
p('Page should be a valid number')
|
||||
return
|
||||
end
|
||||
|
||||
-- just show the last page
|
||||
if page > pages then
|
||||
page = pages
|
||||
end
|
||||
|
||||
if page < 1 then
|
||||
page = 1
|
||||
end
|
||||
|
||||
local page_start = per_page * (page - 1) + 1
|
||||
local page_end = per_page * page
|
||||
page_end = page_end <= count and page_end or count
|
||||
|
||||
p(format('---- %d Search %s -----', count, count == 1 and 'Result' or 'Results'))
|
||||
p(format('Searching for: "%s"', keyword))
|
||||
for i = page_start, page_end do
|
||||
p(format('[%d] /%s', i, matches[i]))
|
||||
end
|
||||
p(format('-------- Page %d / %d --------', page, pages))
|
||||
end)
|
||||
@@ -14,19 +14,13 @@ local Token = require 'utils.token'
|
||||
local Task = require 'utils.schedule'
|
||||
local PlayerStats = require 'features.player_stats'
|
||||
local Game = require 'utils.game'
|
||||
local Utils = require 'utils.core'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local Market_items = require 'resources.market_items'
|
||||
local market_item = Market_items.market_item
|
||||
local fish_market_bonus_message = require 'resources.fish_messages'
|
||||
|
||||
local function spawn_market(cmd)
|
||||
local player = game.player
|
||||
if not player or not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
|
||||
local function spawn_market(_, player)
|
||||
local surface = player.surface
|
||||
local force = player.force
|
||||
|
||||
@@ -45,7 +39,7 @@ local function spawn_market(cmd)
|
||||
{
|
||||
icon = {type = 'item', name = market_item},
|
||||
position = pos,
|
||||
text = ' Market'
|
||||
text = 'Market'
|
||||
}
|
||||
)
|
||||
end
|
||||
@@ -278,7 +272,14 @@ local function player_created(event)
|
||||
end
|
||||
|
||||
local function init()
|
||||
commands.add_command('market', 'Places a fish market near you. (Admins only)', spawn_market)
|
||||
Command.add(
|
||||
'market',
|
||||
{
|
||||
description = 'Places a market near you.',
|
||||
admin_only = true
|
||||
},
|
||||
spawn_market
|
||||
)
|
||||
|
||||
Event.on_nth_tick(180, on_180_ticks)
|
||||
Event.add(defines.events.on_pre_player_mined_item, pre_player_mined_item)
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
global.follows = {}
|
||||
global.follows.n_entries = 0
|
||||
local Utils = require 'utils.core'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
local function get_direction(follower, target)
|
||||
local delta_x = target.position.x - follower.position.x
|
||||
local delta_y = follower.position.y - target.position.y --reversed x axis
|
||||
local a = delta_y / delta_x
|
||||
if a >= -1.5 and a < -0.5 then
|
||||
--SE OR NW
|
||||
if delta_x > 0 then
|
||||
return defines.direction.southeast
|
||||
else
|
||||
return defines.direction.northwest
|
||||
end
|
||||
elseif a >= -0.5 and a < 0.5 then
|
||||
--E OR W
|
||||
if delta_x > 0 then
|
||||
return defines.direction.east
|
||||
else
|
||||
return defines.direction.west
|
||||
end
|
||||
elseif a >= 0.5 and a < 1.5 then
|
||||
--NE OR SW
|
||||
if delta_x > 0 then
|
||||
return defines.direction.northeast
|
||||
else
|
||||
return defines.direction.southwest
|
||||
end
|
||||
else
|
||||
-- N or S
|
||||
if a < 0 then
|
||||
delta_x = -delta_x
|
||||
end -- mirrow x axis if player is NNW or SSE
|
||||
if delta_x > 0 then
|
||||
return defines.direction.north
|
||||
else
|
||||
return defines.direction.south
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function walk_on_tick()
|
||||
if global.follows.n_entries > 0 then
|
||||
for k, v in pairs(global.follows) do
|
||||
local follower = game.playesr[k]
|
||||
local target = game.players[v]
|
||||
if follower ~= nil and target ~= nil then
|
||||
local d = Utils.distance(follower, target)
|
||||
if follower.connected and target.connected and d < 32 then
|
||||
if d > 5 then
|
||||
direction = get_direction(follower, target)
|
||||
follower.walking_state = {walking = true, direction = direction}
|
||||
end
|
||||
else
|
||||
global.follows[follower.name] = nil
|
||||
global.follows.n_entries = global.follows.n_entries - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,64 +0,0 @@
|
||||
local Utils = require 'utils.core'
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
Event.add(
|
||||
defines.events.on_console_command,
|
||||
function(event)
|
||||
local command = event.command
|
||||
local p_index = event.player_index
|
||||
local actor
|
||||
if p_index then
|
||||
actor = Game.get_player_by_index(event.player_index)
|
||||
else
|
||||
actor = {['admin'] = true, ['name'] = '<server>'}
|
||||
end
|
||||
if actor.admin and command ~= 'color' then --lazy approach, will not fix as this will be handle by the command wrapper
|
||||
local s = table.concat {'[Command] ', actor.name, ' /', command, ' ', event.parameters}
|
||||
log(s)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
global.cheated_items = {}
|
||||
global.cheated_items_by_timestamp = {}
|
||||
|
||||
Event.add(
|
||||
defines.events.on_player_crafted_item,
|
||||
function(event)
|
||||
local pi = event.player_index
|
||||
local p = Game.get_player_by_index(pi)
|
||||
|
||||
if not p or not p.valid or not p.cheat_mode then
|
||||
return
|
||||
end
|
||||
|
||||
local cheat_items = global.cheated_items
|
||||
|
||||
local data = cheat_items[pi]
|
||||
if not data then
|
||||
data = {}
|
||||
cheat_items[pi] = data
|
||||
end
|
||||
|
||||
local stack = event.item_stack
|
||||
local name = stack.name
|
||||
local user_item_record = data[name] or {count = 0}
|
||||
local count = user_item_record.count
|
||||
local time = user_item_record['time'] or Utils.format_time(game.tick)
|
||||
data[name] = {count = stack.count + count, time = time}
|
||||
local s = table.concat {'[Cheated item] ', p.name, ' - ', stack.count, ' x ', name}
|
||||
log(s)
|
||||
end
|
||||
)
|
||||
|
||||
function print_cheated_items()
|
||||
local res = {}
|
||||
local players = game.players
|
||||
|
||||
for pi, data in pairs(global.cheated_items) do
|
||||
res[players[pi].name] = data
|
||||
end
|
||||
|
||||
game.player.print(serpent.block(res))
|
||||
end
|
||||
@@ -4,8 +4,8 @@ local Event = require 'utils.event'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local Game = require 'utils.game'
|
||||
local math = require 'utils.math'
|
||||
local Utils = require 'utils.core'
|
||||
local Server = require 'features.server'
|
||||
local Command = require 'utils.command'
|
||||
local Color = require 'resources.color_presets'
|
||||
|
||||
local insert = table.insert
|
||||
@@ -1281,19 +1281,8 @@ function Class.poll_result(id)
|
||||
return table.concat {'poll #', id, ' not found'}
|
||||
end
|
||||
|
||||
local function poll_command(cmd)
|
||||
local player = game.player
|
||||
if player and not (player.admin or UserGroups.is_regular(player.name)) then
|
||||
Utils.cant_run(cmd.name)
|
||||
end
|
||||
|
||||
local param = cmd.parameter
|
||||
|
||||
if not param then
|
||||
Game.player_print('Usage: /poll <{question = "question", answers = {"answer 1", "answer 2"}, duration = 300 | nil}>')
|
||||
return
|
||||
end
|
||||
|
||||
local function poll_command(args)
|
||||
local param = args.poll
|
||||
param = 'return ' .. param
|
||||
|
||||
local func, error = loadstring(param)
|
||||
@@ -1310,16 +1299,9 @@ local function poll_command(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
local function poll_result_command(cmd)
|
||||
local param = cmd.parameter
|
||||
if not param then
|
||||
Game.player_print('Usage: /poll-result <poll#>')
|
||||
return
|
||||
end
|
||||
|
||||
local id = tonumber(param)
|
||||
local function poll_result_command(args)
|
||||
local id = tonumber(args.poll)
|
||||
local result = Class.poll_result(id)
|
||||
|
||||
Game.player_print(result)
|
||||
end
|
||||
|
||||
@@ -1340,12 +1322,27 @@ function Class.send_poll_result_to_discord(id)
|
||||
Server.to_discord_embed(message)
|
||||
end
|
||||
|
||||
commands.add_command(
|
||||
Command.add(
|
||||
'poll',
|
||||
'<{question = "question", answers = {"answer 1", "answer 2"}, duration = 300 | nil}> - Creates a new poll (Admin and regulars only).',
|
||||
{
|
||||
arguments = {'poll'},
|
||||
regular_only = true,
|
||||
allowed_by_server = true,
|
||||
custom_help_text = '<{question = "question", answers = {"answer 1", "answer 2"}, duration = 300}> - Creates a new poll (Regulars only).',
|
||||
log_command = true,
|
||||
capture_excess_arguments = true
|
||||
},
|
||||
poll_command
|
||||
)
|
||||
|
||||
commands.add_command('poll-result', '<poll#> - prints the result for the poll.', poll_result_command)
|
||||
Command.add(
|
||||
'poll-result',
|
||||
{
|
||||
description = 'Prints the result for the given poll number.',
|
||||
arguments = {'poll'},
|
||||
allowed_by_server = true
|
||||
},
|
||||
poll_result_command
|
||||
)
|
||||
|
||||
return Class
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local Gui = require 'utils.gui'
|
||||
local Utils = require 'utils.core'
|
||||
local Game = require 'utils.game'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local close_name = Gui.uid_name()
|
||||
|
||||
@@ -67,90 +68,79 @@ Gui.on_click(
|
||||
)
|
||||
|
||||
-- Creates a popup dialog for all players
|
||||
local function popup(cmd)
|
||||
local player = game.player
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
|
||||
local message = cmd.parameter
|
||||
if not message then
|
||||
Game.player_print('Usage: /popup <message>')
|
||||
return
|
||||
end
|
||||
|
||||
message = message:gsub('\\n', '\n')
|
||||
local function popup(args)
|
||||
local message = args.message:gsub('\\n', '\n')
|
||||
|
||||
for _, p in ipairs(game.connected_players) do
|
||||
show_popup(p, message)
|
||||
end
|
||||
|
||||
Game.player_print('Popup sent')
|
||||
Utils.print_admins(Utils.get_actor() .. ' sent a popup to all players', false)
|
||||
Utils.print_admins(Utils.get_actor() .. ' sent a popup to all players', nil)
|
||||
end
|
||||
|
||||
-- Creates a popup dialog for all players, specifically for the server upgrading factorio versions
|
||||
local function popup_update(cmd)
|
||||
local player = game.player
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
|
||||
local message = '\nServer updating to ' .. cmd.parameter .. ', back in one minute.'
|
||||
local function popup_update(args)
|
||||
local message = '\nServer updating to ' .. args.version .. ', back in one minute.'
|
||||
|
||||
for _, p in ipairs(game.connected_players) do
|
||||
show_popup(p, message)
|
||||
end
|
||||
|
||||
Game.player_print('Popup sent')
|
||||
Utils.print_admins(Utils.get_actor() .. ' sent a popup to all players', false)
|
||||
Utils.print_admins(Utils.get_actor() .. ' sent a popup to all players', nil)
|
||||
end
|
||||
|
||||
-- Creates a popup dialog for the specifically targetted player
|
||||
local function popup_player(cmd)
|
||||
local player = game.player
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
|
||||
local message = cmd.parameter
|
||||
if not message then
|
||||
Game.player_print('Usage: /popup <player> <message>')
|
||||
return
|
||||
end
|
||||
|
||||
local start_index, end_index = message:find(' ')
|
||||
if not start_index then
|
||||
Game.player_print('Usage: /popup <player> <message>')
|
||||
return
|
||||
end
|
||||
|
||||
local target_name = message:sub(1, start_index - 1)
|
||||
local function popup_player(args)
|
||||
local target_name = args.player
|
||||
local target = game.players[target_name]
|
||||
if not target then
|
||||
Game.player_print('Player ' .. target_name .. ' not found.')
|
||||
return
|
||||
end
|
||||
|
||||
message = message:sub(end_index, #message):gsub('\\n', '\n')
|
||||
local message = args.message:gsub('\\n', '\n')
|
||||
|
||||
show_popup(target, message)
|
||||
|
||||
Game.player_print('Popup sent')
|
||||
end
|
||||
|
||||
commands.add_command('popup', '<message> - Shows a popup to all connected players (Admins only)', popup)
|
||||
Command.add(
|
||||
'popup',
|
||||
{
|
||||
description = 'Shows a popup to all connected players',
|
||||
arguments = {'message'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
popup
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
Command.add(
|
||||
'popup-update',
|
||||
'<version> - Shows an update popup to all connected players (Admins only)',
|
||||
{
|
||||
description = 'Shows an update popup to all connected players',
|
||||
arguments = {'version'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
popup_update
|
||||
)
|
||||
|
||||
commands.add_command('popup-player', '<player> <message> - Shows a popup to the players (Admins only)', popup_player)
|
||||
Command.add(
|
||||
'popup-player',
|
||||
{
|
||||
description = 'Shows a popup to the player.',
|
||||
arguments = {'player', 'message'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
popup_player
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ local Global = require 'utils.global'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local Game = require 'utils.game'
|
||||
local Utils = require 'utils.core'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local deafult_verb = 'expanded'
|
||||
|
||||
@@ -660,36 +661,15 @@ Gui.allow_player_to_toggle_top_element_visibility(main_button_name)
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, player_joined)
|
||||
|
||||
local function tag_command(cmd)
|
||||
local player = game.player
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local function tag_command(args)
|
||||
local target_player = game.players[args.player]
|
||||
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Usage: /tag <player> <tag> Sets a players tag.')
|
||||
return
|
||||
end
|
||||
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
|
||||
if #params < 2 then
|
||||
Game.player_print('Usage: <player> <tag> Sets a players tag.')
|
||||
return
|
||||
end
|
||||
|
||||
local target_player = game.players[params[1]]
|
||||
|
||||
if target_player == nil or not target_player.valid then
|
||||
if not target_player then
|
||||
Game.player_print('Player does not exist.')
|
||||
return
|
||||
end
|
||||
|
||||
local tag_name = string.sub(cmd.parameter, params[1]:len() + 2)
|
||||
local tag_name = args.tag
|
||||
local tag = tag_groups[tag_name]
|
||||
|
||||
if tag == nil then
|
||||
@@ -704,4 +684,14 @@ local function tag_command(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
commands.add_command('tag', "<player> <tag> Sets a player's tag. (Admins only)", tag_command)
|
||||
Command.add(
|
||||
'tag',
|
||||
{
|
||||
description = "Sets a player's tag",
|
||||
arguments = {'player', 'tag'},
|
||||
admin_only = true,
|
||||
capture_excess_arguments = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
tag_command
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ local Utils = require 'utils.core'
|
||||
local Game = require 'utils.game'
|
||||
local Color = require 'resources.color_presets'
|
||||
local math = require 'utils.math'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local normal_color = Color.white
|
||||
local focus_color = Color.dark_orange
|
||||
@@ -1068,28 +1069,17 @@ Gui.on_click(
|
||||
|
||||
Gui.allow_player_to_toggle_top_element_visibility(main_button_name)
|
||||
|
||||
commands.add_command(
|
||||
Command.add(
|
||||
'task',
|
||||
'<task> - Creates a new task (Admins and regulars only).',
|
||||
function(cmd)
|
||||
local player = game.player
|
||||
|
||||
if player then
|
||||
if not player.admin and not UserGroups.is_regular(player.name) then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
else
|
||||
player = server_player
|
||||
end
|
||||
|
||||
local task_name = cmd.parameter
|
||||
|
||||
if not task_name or task_name == '' then
|
||||
player.print('Usage: /task <task>')
|
||||
return
|
||||
end
|
||||
|
||||
create_new_tasks(task_name, player)
|
||||
{
|
||||
description = 'Creates a new task.',
|
||||
arguments = {'task'},
|
||||
regular_only = true,
|
||||
allowed_by_server = true,
|
||||
log_command = true,
|
||||
capture_excess_arguments = true,
|
||||
},
|
||||
function(args, player)
|
||||
create_new_tasks(args.task, player or server_player)
|
||||
end
|
||||
)
|
||||
|
||||
@@ -63,7 +63,7 @@ local function on_player_deconstructed_area(event)
|
||||
if #entities > 1000 then
|
||||
Utils.print_admins(
|
||||
'Warning! ' .. player.name .. ' just tried to deconstruct ' .. tostring(#entities) .. ' entities!',
|
||||
false
|
||||
nil
|
||||
)
|
||||
end
|
||||
for _, entity in pairs(entities) do
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
global.reactors_enabled = global.config.reactor_meltdown.on_by_default
|
||||
global.wastelands = {}
|
||||
@@ -152,13 +153,11 @@ local function entity_build(event)
|
||||
end
|
||||
|
||||
local function reactor_toggle()
|
||||
if not game.player or game.player.admin then
|
||||
global.reactors_enabled = not global.reactors_enabled
|
||||
if global.reactors_enabled then
|
||||
game.print('Reactor meltdown activated.')
|
||||
else
|
||||
game.print('Reactor meltdown deactivated.')
|
||||
end
|
||||
global.reactors_enabled = not global.reactors_enabled
|
||||
if global.reactors_enabled then
|
||||
game.print('Reactor meltdown activated.')
|
||||
else
|
||||
game.print('Reactor meltdown deactivated.')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -169,9 +168,25 @@ local function is_meltdown()
|
||||
Game.player_print('Reactor meltdown is disabled.')
|
||||
end
|
||||
end
|
||||
Command.add(
|
||||
'meltdown',
|
||||
{
|
||||
description = 'Toggles if reactors blow up',
|
||||
admin_only = true,
|
||||
allowed_by_server = true,
|
||||
log_command = true
|
||||
},
|
||||
reactor_toggle
|
||||
)
|
||||
|
||||
commands.add_command('meltdown', 'Toggles if reactors blow up', reactor_toggle)
|
||||
commands.add_command('is-meltdown', 'Prints if meltdown is enabled', is_meltdown)
|
||||
Command.add(
|
||||
'is-meltdown',
|
||||
{
|
||||
description = 'Prints if meltdown is enabled',
|
||||
allowed_by_server = true
|
||||
},
|
||||
is_meltdown
|
||||
)
|
||||
|
||||
Event.on_nth_tick(60, on_tick)
|
||||
Event.add(defines.events.on_player_mined_entity, entity_destroyed)
|
||||
|
||||
280
features/redmew_commands.lua
Normal file
280
features/redmew_commands.lua
Normal file
@@ -0,0 +1,280 @@
|
||||
local Report = require 'features.report'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local Game = require 'utils.game'
|
||||
local Server = require 'features.server'
|
||||
local Timestamp = require 'utils.timestamp'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local format = string.format
|
||||
local ceil = math.ceil
|
||||
|
||||
--- 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
|
||||
|
||||
local e = player.surface.create_entity {name = 'fish', position = player.position}
|
||||
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)
|
||||
local target_name = args.player
|
||||
local target
|
||||
if target_name then
|
||||
target = game.players[target_name]
|
||||
if not target then
|
||||
Game.player_print(format('Player %s was not found.', target_name))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if global.walking and ((player and global.walking[player.index]) or (target and global.walking[target.index])) then
|
||||
Game.player_print("A player on walkabout cannot be killed by a mere fish, don't waste your efforts.")
|
||||
return
|
||||
end
|
||||
|
||||
if not target and player then
|
||||
if not do_fish_kill(player, true) then
|
||||
Game.player_print("Sorry, you don't have a character to kill.")
|
||||
end
|
||||
elseif player then
|
||||
if target == player then
|
||||
if not do_fish_kill(player, true) then
|
||||
Game.player_print("Sorry, you don't have a character to kill.")
|
||||
end
|
||||
elseif target and player.admin then
|
||||
if not do_fish_kill(target) then
|
||||
Game.player_print(table.concat {"'Sorry, '", target.name, "' doesn't have a character to kill."})
|
||||
end
|
||||
else
|
||||
Game.player_print("Sorry you don't have permission to use the kill command on other players.")
|
||||
end
|
||||
elseif target then
|
||||
if not do_fish_kill(target) then
|
||||
Game.player_print(table.concat {"'Sorry, '", target.name, "' doesn't have a character to kill."})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Check players' afk times
|
||||
local function afk()
|
||||
local count = 0
|
||||
for _, v in pairs(game.players) do
|
||||
if v.afk_time > 300 then
|
||||
count = count + 1
|
||||
local time = ' '
|
||||
if v.afk_time > 21600 then
|
||||
time = time .. math.floor(v.afk_time / 216000) .. ' hours '
|
||||
end
|
||||
if v.afk_time > 3600 then
|
||||
time = time .. math.floor(v.afk_time / 3600) % 60 .. ' minutes and '
|
||||
end
|
||||
time = time .. math.floor(v.afk_time / 60) % 60 .. ' seconds.'
|
||||
Game.player_print(v.name .. ' has been afk for' .. time)
|
||||
end
|
||||
end
|
||||
if count == 0 then
|
||||
Game.player_print('No players afk.')
|
||||
end
|
||||
end
|
||||
|
||||
--- Lets a player set their zoom level
|
||||
local function zoom(args, player)
|
||||
if tonumber(args.zoom) then
|
||||
player.zoom = tonumber(args.zoom)
|
||||
else
|
||||
Game.player_print('You must give zoom a number.')
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates an alert for the player at the location of their target
|
||||
local function find_player(args, player)
|
||||
local name = args.player
|
||||
|
||||
local target = game.players[name]
|
||||
if not target then
|
||||
Game.player_print('player ' .. name .. ' not found')
|
||||
return
|
||||
end
|
||||
|
||||
target = target.character
|
||||
if not target or not target.valid then
|
||||
Game.player_print('player ' .. name .. ' does not have a character')
|
||||
return
|
||||
end
|
||||
|
||||
player.add_custom_alert(target, {type = 'virtual', name = 'signal-F'}, name, true)
|
||||
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
|
||||
|
||||
Game.player_print('show_rail_block_visualisation set to ' .. tostring(show))
|
||||
end
|
||||
|
||||
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
|
||||
p('Server time is not available, is this game running on a Redmew server?')
|
||||
else
|
||||
p(Timestamp.to_string(secs))
|
||||
end
|
||||
end
|
||||
|
||||
local function search_command(arguments, player)
|
||||
local keyword = arguments.keyword
|
||||
local p = player.print
|
||||
if #keyword < 2 then
|
||||
p('Keyword should be 2 characters or more')
|
||||
return
|
||||
end
|
||||
|
||||
local per_page = 7
|
||||
local matches = Command.search(keyword)
|
||||
local count = #matches
|
||||
|
||||
if count == 0 then
|
||||
p('---- 0 Search Results ----')
|
||||
p(format('No commands found matching "%s"', keyword))
|
||||
p('-------------------------')
|
||||
return
|
||||
end
|
||||
|
||||
local page = tonumber(arguments.page)
|
||||
local pages = ceil(count / per_page)
|
||||
|
||||
if nil == page then
|
||||
p('Page should be a valid number')
|
||||
return
|
||||
end
|
||||
|
||||
-- just show the last page
|
||||
if page > pages then
|
||||
page = pages
|
||||
end
|
||||
|
||||
if page < 1 then
|
||||
page = 1
|
||||
end
|
||||
|
||||
local page_start = per_page * (page - 1) + 1
|
||||
local page_end = per_page * page
|
||||
page_end = page_end <= count and page_end or count
|
||||
|
||||
p(format('---- %d Search %s -----', count, count == 1 and 'Result' or 'Results'))
|
||||
p(format('Searching for: "%s"', keyword))
|
||||
for i = page_start, page_end do
|
||||
p(format('[%d] /%s', i, matches[i]))
|
||||
end
|
||||
p(format('-------- Page %d / %d --------', page, pages))
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
Command.add(
|
||||
'kill',
|
||||
{
|
||||
description = 'Will kill you.',
|
||||
arguments = {'player'},
|
||||
default_values = {player = false},
|
||||
allowed_by_server = true
|
||||
},
|
||||
kill
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'afk',
|
||||
{
|
||||
description = 'Shows how long players have been afk.',
|
||||
allowed_by_server = true
|
||||
},
|
||||
afk
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'zoom',
|
||||
{
|
||||
description = 'Sets your zoom.',
|
||||
arguments = {'zoom'}
|
||||
},
|
||||
zoom
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'find',
|
||||
{
|
||||
description = 'shows an alert on the map where the player is located',
|
||||
arguments = {'player'}
|
||||
},
|
||||
find_player
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'show-rail-block',
|
||||
{
|
||||
description = 'Toggles rail block visualisation.'
|
||||
},
|
||||
show_rail_block
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'server-time',
|
||||
{
|
||||
description = "Prints the server's time.",
|
||||
allowed_by_server = true
|
||||
},
|
||||
server_time
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'search-command',
|
||||
{
|
||||
description = 'Search for commands matching the keyword in name or description',
|
||||
arguments = {'keyword', 'page'},
|
||||
default_values = {page = 1}
|
||||
},
|
||||
search_command
|
||||
)
|
||||
|
||||
-- Commands with no functions, only calls to other modules
|
||||
|
||||
Command.add(
|
||||
'report',
|
||||
{
|
||||
description = 'Reports a user to admins',
|
||||
arguments = {'player', 'message'},
|
||||
capture_excess_arguments = true
|
||||
},
|
||||
Report.report_command
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'regulars',
|
||||
{
|
||||
description = 'Prints a list of game regulars.',
|
||||
allowed_by_server = true
|
||||
},
|
||||
UserGroups.print_regulars
|
||||
)
|
||||
@@ -1,19 +1,21 @@
|
||||
local Module = {}
|
||||
|
||||
local Gui = require('utils.gui')
|
||||
local Utils = require('utils.core')
|
||||
local Game = require 'utils.game'
|
||||
local Color = require 'resources.color_presets'
|
||||
|
||||
local format = string.format
|
||||
|
||||
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()
|
||||
local jail_name = 'Jail'
|
||||
local default_group = 'Default'
|
||||
local prefix = '------------------NOTICE-------------------'
|
||||
local prefix_e = '--------------------------------------------'
|
||||
|
||||
local Module = {}
|
||||
global.reports = {}
|
||||
global.player_report_data = {}
|
||||
|
||||
@@ -121,33 +123,23 @@ function Module.report(reporting_player, reported_player, message)
|
||||
end
|
||||
end
|
||||
|
||||
function Module.cmd_report(cmd)
|
||||
local reporting_player = game.player
|
||||
if reporting_player then
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
if #params < 2 then
|
||||
reporting_player.print('Please enter then name of the offender and the reason for the report.')
|
||||
return nil
|
||||
end
|
||||
local reported_player_name = params[1] or ''
|
||||
local reported_player = game.players[reported_player_name]
|
||||
function Module.report_command(args, player)
|
||||
local reported_player_name = args.player
|
||||
local reported_player = game.players[reported_player_name]
|
||||
|
||||
if not reported_player then
|
||||
reporting_player.print(reported_player_name .. ' does not exist.')
|
||||
return nil
|
||||
end
|
||||
Module.report(reporting_player, reported_player, string.sub(cmd.parameter, string.len(params[1]) + 2))
|
||||
reporting_player.print('Your report has been sent.')
|
||||
if not reported_player then
|
||||
Game.player_print(reported_player_name .. ' does not exist.')
|
||||
return nil
|
||||
end
|
||||
|
||||
Module.report(player, reported_player, args.message)
|
||||
Game.player_print('Your report has been sent.')
|
||||
end
|
||||
|
||||
-- Places a target in jail as long as player is admin or server
|
||||
--- 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
|
||||
function Module.jail(target_player, player)
|
||||
-- Set the name of the jail permission group
|
||||
|
||||
local print
|
||||
local jailed_by
|
||||
if player then
|
||||
@@ -178,7 +170,7 @@ function Module.jail(target_player, player)
|
||||
end
|
||||
|
||||
if target_player.permission_group == permission_group then
|
||||
print('Player ' .. target_player.name .. ' is already in jail.')
|
||||
print(format('Player %s is already in jail.', target_player.name))
|
||||
return
|
||||
end
|
||||
|
||||
@@ -209,37 +201,32 @@ function Module.jail(target_player, player)
|
||||
target_player.print('You have been placed in jail by ' .. jailed_by .. '. The only action avaliable to you is chatting.')
|
||||
target_player.print('Please respond to inquiries from the admins.', Color.yellow)
|
||||
target_player.print(prefix_e)
|
||||
Utils.print_admins(target_player.name .. ' has been jailed by ' .. player.name)
|
||||
Utils.print_admins(format('%s has been jailed by %s', target_player.name, player.name))
|
||||
Utils.log_command(Utils.get_actor(), 'jail', target_player.name)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
print('Something went wrong in the jailing of ' .. target_player.name .. '. You can still change their group via /permissions.')
|
||||
print(format('Something went wrong in the jailing of %s. You can still change their group via /permissions.',target_player.name))
|
||||
end
|
||||
end
|
||||
|
||||
function Module.unjail_player(cmd)
|
||||
local default_group = 'Default'
|
||||
local player = game.player ~= nil and game.player or cmd['player']
|
||||
-- Check if the player can run the command
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
elseif not player then
|
||||
--- 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
|
||||
player = {name = 'server'}
|
||||
end
|
||||
-- Check if the target is valid (copied from the invoke command)
|
||||
local target = cmd['parameter']
|
||||
if target == nil then
|
||||
Game.player_print('Usage: /unjail <player>')
|
||||
return
|
||||
print = log
|
||||
end
|
||||
|
||||
local target_player = game.players[target]
|
||||
if not target_player then
|
||||
Game.player_print('Unknown player.')
|
||||
print('Unknown player.')
|
||||
return
|
||||
end
|
||||
|
||||
local target_name = target_player.name
|
||||
local permissions = game.permissions
|
||||
|
||||
-- Check if the permission group exists, if it doesn't, create it.
|
||||
@@ -248,29 +235,29 @@ function Module.unjail_player(cmd)
|
||||
permission_group = permissions.create_group(default_group)
|
||||
end
|
||||
|
||||
local jail_permission_group = permissions.get_group('Jail')
|
||||
local jail_permission_group = permissions.get_group(jail_name)
|
||||
if (not jail_permission_group) or target_player.permission_group ~= jail_permission_group then
|
||||
Game.player_print('The player ' .. target .. ' is already not in Jail.')
|
||||
Game.player_print(format('%s is already not in Jail.', target_name))
|
||||
return
|
||||
end
|
||||
|
||||
-- Move player
|
||||
permission_group.add_player(target)
|
||||
permission_group.add_player(target_player)
|
||||
-- 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
|
||||
|
||||
-- Check that it worked
|
||||
if target_player.permission_group == permission_group then
|
||||
-- Let admin know it worked, let target know what's going on.
|
||||
Game.player_print(target .. ' has been returned to the default group. They have been advised of this.')
|
||||
Game.player_print(target_name .. ' has been returned to the default group. They have been advised of this.')
|
||||
target_player.print(prefix)
|
||||
target_player.print('Your ability to perform actions has been restored', Color.green)
|
||||
target_player.print(prefix_e)
|
||||
Utils.print_admins(target_player.name .. ' has been released from jail by ' .. player.name)
|
||||
Utils.print_admins(format('%s has been released from jail by %s', target_player.name, player.name))
|
||||
Utils.log_command(Utils.get_actor(), 'unjail', target_player.name)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
Game.player_print('Something went wrong in the unjailing of ' .. target .. '. You can still change their group via /permissions and inform them.')
|
||||
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))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -378,7 +365,7 @@ Gui.on_click(
|
||||
Gui.destroy(frame)
|
||||
Module.report(event.player, Game.get_player_by_index(reported_player_index), msg)
|
||||
print(prefix)
|
||||
print('You have successfully reported the player: ' .. Game.get_player_by_index(reported_player_index).name)
|
||||
print('You have successfully reported: ' .. Game.get_player_by_index(reported_player_index).name)
|
||||
print(prefix_e)
|
||||
end
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@ local Task = require 'utils.schedule'
|
||||
local Game = require 'utils.game'
|
||||
local Event = require 'utils.event'
|
||||
local Token = require 'utils.token'
|
||||
local Utils = require 'utils.core'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
global.walking = {}
|
||||
global.walking_storage = {}
|
||||
@@ -10,7 +10,7 @@ global.walking_storage = {}
|
||||
--- Returns a player from walkabout after the timeout.
|
||||
-- If the player is no longer logged in, store their info
|
||||
-- in the global table walking_storage
|
||||
local custom_commands_return_player =
|
||||
local redmew_commands_return_player =
|
||||
Token.register(
|
||||
function(args)
|
||||
local player = args.player
|
||||
@@ -52,31 +52,16 @@ local custom_commands_return_player =
|
||||
|
||||
--- Sends a player on a walkabout:
|
||||
-- They are teleported far away, placed on a neutral force, and are given a new character.
|
||||
-- They are turned after the timeout by custom_commands_return_player
|
||||
local function walkabout(cmd)
|
||||
if game.player and not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local params = {}
|
||||
if cmd.parameter == nil then
|
||||
Game.player_print('Walkabout failed, check /help walkabout.')
|
||||
return
|
||||
end
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
local player_name = params[1]
|
||||
local duration = 60
|
||||
if #params > 2 then
|
||||
Game.player_print('Walkabout failed, check /help walkabout.')
|
||||
return
|
||||
elseif #params == 2 and tonumber(params[2]) == nil then
|
||||
Game.player_print(params[2] .. ' is not a number.')
|
||||
return
|
||||
elseif #params == 2 and tonumber(params[2]) then
|
||||
duration = tonumber(params[2])
|
||||
-- They are turned after the timeout by redmew_commands_return_player
|
||||
local function walkabout(args)
|
||||
local player_name = args.player
|
||||
|
||||
local duration = tonumber(args.duration)
|
||||
if not duration then
|
||||
Game.player_print('Duration should be a number, player will be sent on walkabout for the default 60 seconds.')
|
||||
duration = 60
|
||||
end
|
||||
|
||||
if duration < 15 then
|
||||
duration = 15
|
||||
end
|
||||
@@ -86,10 +71,6 @@ local function walkabout(cmd)
|
||||
Game.player_print(player_name .. ' could not go on a walkabout.')
|
||||
return
|
||||
end
|
||||
local chunks = {}
|
||||
for chunk in player.surface.get_chunks() do
|
||||
table.insert(chunks, chunk)
|
||||
end
|
||||
|
||||
local surface = player.surface
|
||||
local chunk = surface.get_random_chunk()
|
||||
@@ -105,7 +86,7 @@ local function walkabout(cmd)
|
||||
game.print(player_name .. ' went on a walkabout, to find himself.')
|
||||
Task.set_timeout(
|
||||
duration,
|
||||
custom_commands_return_player,
|
||||
redmew_commands_return_player,
|
||||
{
|
||||
player = player,
|
||||
force = player.force,
|
||||
@@ -153,4 +134,14 @@ local function clean_on_join(event)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, clean_on_join)
|
||||
commands.add_command('walkabout', '<player> <duration> - Send someone on a walk. (Admins only)', walkabout)
|
||||
Command.add(
|
||||
'walkabout',
|
||||
{
|
||||
description = 'Send someone on a walk. Duration is in seconds.',
|
||||
arguments = {'player', 'duration'},
|
||||
default_values = {duration = 60},
|
||||
admin_only = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
walkabout
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ local Task = require 'utils.schedule'
|
||||
local PlayerStats = require 'features.player_stats'
|
||||
local Game = require 'utils.game'
|
||||
local Utils = require 'utils.core'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local market_items = require 'resources.market_items'
|
||||
|
||||
@@ -18,24 +19,28 @@ market_items[2].offer.effect_description = 'Temporary mining bonus - Price 40 W
|
||||
|
||||
table.insert(market_items, {price = {{'raw-wood', 4}}, offer = {type = 'give-item', item = 'raw-fish'}})
|
||||
|
||||
local function spawn_market(cmd)
|
||||
if not game.player or not game.player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
local function spawn_market(_, player)
|
||||
local surface = game.player.surface
|
||||
local force = player.force
|
||||
|
||||
local player = game.player
|
||||
local pos = player.position
|
||||
pos.y = pos.y - 4
|
||||
|
||||
local market_location = {x = player.position.x, y = player.position.y}
|
||||
market_location.y = market_location.y - 4
|
||||
|
||||
local market = surface.create_entity {name = 'market', position = market_location}
|
||||
local market = surface.create_entity {name = 'market', position = pos}
|
||||
market.destructible = false
|
||||
|
||||
for _, item in ipairs(market_items) do
|
||||
market.add_market_item(item)
|
||||
end
|
||||
|
||||
force.add_chart_tag(
|
||||
surface,
|
||||
{
|
||||
icon = {type = 'item', name = 'raw-wood'},
|
||||
position = pos,
|
||||
text = 'Market'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local entity_drop_amount = {
|
||||
@@ -207,7 +212,14 @@ local function player_mined_entity(event)
|
||||
end
|
||||
end
|
||||
|
||||
commands.add_command('market', 'Places a wood market near you. (Admins only)', spawn_market)
|
||||
Command.add(
|
||||
'market',
|
||||
{
|
||||
description = 'Places a market near you.',
|
||||
admin_only = true
|
||||
},
|
||||
spawn_market
|
||||
)
|
||||
|
||||
Event.on_nth_tick(180, on_180_ticks)
|
||||
|
||||
|
||||
@@ -6,13 +6,11 @@ local Utils = require 'utils.core'
|
||||
local Global = require 'utils.global'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
local Command = require 'utils.command'
|
||||
|
||||
local format = string.format
|
||||
|
||||
ScenarioInfo.add_map_extra_info(
|
||||
'- On this map you will be assigned a silly name.\n' ..
|
||||
'- If you dislike your name you can /name-restore or /name-roll for a new one'
|
||||
)
|
||||
ScenarioInfo.add_map_extra_info('- On this map you will be assigned a silly name.\n' .. '- If you dislike your name you can /name-restore or /name-roll for a new one')
|
||||
|
||||
global.silly_regulars = {}
|
||||
local data_silly_names = {}
|
||||
@@ -51,7 +49,7 @@ end
|
||||
-- @returns string with player's silly name
|
||||
-- TODO: Config option to set the name style
|
||||
local function create_name(words_table, player_name)
|
||||
local adverb, adjective--, noun
|
||||
local adverb, adjective --, noun
|
||||
adverb = table.get_random(words_table.adverbs, true)
|
||||
adjective = table.get_random(words_table.adjectives, true)
|
||||
--noun = table.get_random(words_table.nouns, true)
|
||||
@@ -100,7 +98,7 @@ local function name_player(player)
|
||||
local str = format('%s will now be known as: %s', player.name, name)
|
||||
game.print(str)
|
||||
local admin_str = format('%s (ID: %s)', str, player.index)
|
||||
Utils.print_admins(admin_str, false)
|
||||
Utils.print_admins(admin_str, nil)
|
||||
player.name = name
|
||||
|
||||
-- After they have their name, we need to ensure compatibility with the regulars system
|
||||
@@ -108,20 +106,20 @@ local function name_player(player)
|
||||
end
|
||||
|
||||
--- Restores a player's actual name
|
||||
local function restore_name(data)
|
||||
local function restore_name(data, command_player)
|
||||
local player
|
||||
if data.player_index then
|
||||
if data and data.player_index then
|
||||
player = Game.get_player_by_index(data.player_index)
|
||||
else
|
||||
player = game.player
|
||||
player = command_player
|
||||
end
|
||||
local silly_name = player.name
|
||||
data_silly_names.silly_name_store[player.index] = player.name
|
||||
player.name = data_silly_names.actual_name[player.index]
|
||||
if data.name == 'name-restore' then
|
||||
if command_player then
|
||||
player.print('Your true name has been restored.')
|
||||
local str = silly_name .. ' will now be known as: ' .. player.name
|
||||
Utils.print_admins(str .. ' (ID: ' .. player.index .. ')', false)
|
||||
Utils.print_admins(str .. ' (ID: ' .. player.index .. ')', nil)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -136,13 +134,12 @@ local function player_joined(event)
|
||||
end
|
||||
|
||||
--- Passes target or player on to name_players
|
||||
local function name_player_command(cmd)
|
||||
local player = game.player
|
||||
local param = cmd.parameter
|
||||
local function name_player_command(args, player)
|
||||
local target
|
||||
local target_name = args.player
|
||||
|
||||
if param then
|
||||
target = game.players[param]
|
||||
if target_name then
|
||||
target = game.players[target_name]
|
||||
if player and not player.admin then
|
||||
-- Yes param, yes player, no admin/server = fail, non-admins, non-server cannot use command on others
|
||||
Game.player_print("Sorry you don't have permission to use the roll-name command on other players.")
|
||||
@@ -155,30 +152,20 @@ local function name_player_command(cmd)
|
||||
return
|
||||
else
|
||||
-- Yes param, yes admin/server, no target = fail, wrong player name
|
||||
Game.player_print(table.concat {"Sorry, player '", param, "' was not found."})
|
||||
Game.player_print(table.concat {"Sorry, player '", target_name, "' was not found."})
|
||||
return
|
||||
end
|
||||
end
|
||||
else
|
||||
-- No param = check if server
|
||||
if not player then
|
||||
-- No param, no player = server trying to change its name
|
||||
Game.player_print('The server cannot change its name')
|
||||
return
|
||||
end
|
||||
-- No param, not server = change self name
|
||||
-- No param = change self name
|
||||
name_player(player)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
--- Prints the original name of the target
|
||||
local function check_name(cmd)
|
||||
local current_name = cmd.parameter
|
||||
if not current_name then
|
||||
Game.player_print('Usage: /name-check <player>')
|
||||
return
|
||||
end
|
||||
local function check_name(args)
|
||||
local current_name = args.player
|
||||
|
||||
local target = game.players[current_name]
|
||||
if not target then
|
||||
@@ -191,27 +178,56 @@ local function check_name(cmd)
|
||||
end
|
||||
|
||||
--- Prints the index of the target
|
||||
local function get_player_id(cmd)
|
||||
local player = game.player
|
||||
-- Check if the player can run the command
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
local function get_player_id(args)
|
||||
local target_name = args.player
|
||||
|
||||
local target = game.players[target_name]
|
||||
if not target then
|
||||
Game.player_print('player ' .. target_name .. ' not found')
|
||||
return
|
||||
end
|
||||
-- Check if the target is valid
|
||||
local target_name = cmd['parameter']
|
||||
if not target_name then
|
||||
Game.player_print('Usage: /get-player-id <player>')
|
||||
return
|
||||
end
|
||||
local target_index = game.players[target_name].index
|
||||
Game.player_print(target_name .. ' -- ' .. target_index)
|
||||
|
||||
Game.player_print(format('name: %s -- index: %s', target_name, target.index))
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_joined_game, player_joined)
|
||||
Event.add(defines.events.on_pre_player_left_game, restore_name)
|
||||
|
||||
commands.add_command('name-roll', 'Assigns you a random, silly name', name_player_command)
|
||||
commands.add_command('name-restore', 'Removes your fun/silly name and gives you back your actual name', restore_name)
|
||||
commands.add_command('name-check', '<silly_player_name> Check the original name of a player with a silly name', check_name)
|
||||
commands.add_command('get-player-id', 'Gets the ID of a player (Admin only)', get_player_id)
|
||||
Command.add(
|
||||
'name-roll',
|
||||
{
|
||||
description = 'Assigns you a random, silly name. (Admins can use this command on players)',
|
||||
arguments = {'player'},
|
||||
default_values = {player = false}
|
||||
},
|
||||
name_player_command
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'name-restore',
|
||||
{
|
||||
description = 'Removes your fun/silly name and gives you back your actual name.',
|
||||
},
|
||||
restore_name
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'name-check',
|
||||
{
|
||||
description = 'Check the original name of a player with a silly name',
|
||||
arguments = {'player'},
|
||||
allowed_by_server = true
|
||||
},
|
||||
check_name
|
||||
)
|
||||
|
||||
Command.add(
|
||||
'get-player-id',
|
||||
{
|
||||
description = 'Gets the index of a player',
|
||||
arguments = {'player'},
|
||||
admin_only = true,
|
||||
allowed_by_server = true
|
||||
},
|
||||
get_player_id
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ local random = math.random
|
||||
local insert = table.insert
|
||||
local Popup = require 'features.gui.popup'
|
||||
local Global = require 'utils.global'
|
||||
local Command = require 'utils.command'
|
||||
if not global.map.terraforming then
|
||||
global.map.terraforming = {}
|
||||
end
|
||||
@@ -457,23 +458,29 @@ Event.on_nth_tick(death_recap_timer, print_death_recap)
|
||||
Event.on_nth_tick(player_pos_check_time, apply_creep_effects_on_players)
|
||||
|
||||
--- Debug commands which will generate or clear pollution
|
||||
if _DEBUG or _CHEATS then
|
||||
commands.add_command(
|
||||
'cloud',
|
||||
'Use your vape rig to create a pollution cloud around you',
|
||||
function()
|
||||
if game.player then
|
||||
game.player.surface.pollute(game.player.position, 10000)
|
||||
end
|
||||
Command.add(
|
||||
'cloud',
|
||||
{
|
||||
description = 'Create a lot of pollution',
|
||||
debug_only = true,
|
||||
cheat_only = true
|
||||
},
|
||||
function()
|
||||
if game.player then
|
||||
game.player.surface.pollute(game.player.position, 10000)
|
||||
end
|
||||
)
|
||||
commands.add_command(
|
||||
'clean',
|
||||
'Use your vacuum to suck up the pollution cloud around you',
|
||||
function()
|
||||
if game.player then
|
||||
game.player.surface.clear_pollution()
|
||||
end
|
||||
end
|
||||
)
|
||||
Command.add(
|
||||
'clean',
|
||||
{
|
||||
description = 'Eliminate all pollution on the surface',
|
||||
debug_only = true,
|
||||
cheat_only = true
|
||||
},
|
||||
function()
|
||||
if game.player then
|
||||
game.player.surface.clear_pollution()
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
require 'utils.table'
|
||||
local UserGroups = require 'features.user_groups'
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
local insert = table.insert
|
||||
local format = string.format
|
||||
@@ -9,17 +11,26 @@ local match = string.match
|
||||
|
||||
local Command = {}
|
||||
|
||||
local deprecated_command_alternatives = {
|
||||
['silent-command'] = 'sc',
|
||||
['tpplayer'] = 'tp',
|
||||
['tppos'] = 'tp',
|
||||
['tpmode'] = 'tp',
|
||||
}
|
||||
|
||||
local option_names = {
|
||||
['description'] = 'A description of the command',
|
||||
['arguments'] = 'A table of arguments, example: {"foo", "bar"} would map the first 2 arguments to foo and bar',
|
||||
['default_values'] = 'A default value for a given argument when omitted, example: {bar = false}',
|
||||
['regular_only'] = 'Set this to true if only regulars may execute this command',
|
||||
['admin_only'] = 'Set this to true if only admins may execute this command',
|
||||
['debug_only'] = 'Set this to true if it should only be registered when _DEBUG is true',
|
||||
['debug_only'] = 'Set this to true if it should be registered when _DEBUG is true',
|
||||
['cheat_only'] = 'Set this to true if it should be registered when _CHEATS is true',
|
||||
['allowed_by_server'] = 'Set to true if the server (host) may execute this command',
|
||||
['allowed_by_player'] = 'Set to false to disable players from executing this command',
|
||||
['log_command'] = 'Set to true to log commands. Always true when admin_only is enabled',
|
||||
['capture_excess_arguments'] = 'Allows the last argument to be the remaining text in the command',
|
||||
['custom_help_text'] = 'Sets a custom help text to override the auto-generated help',
|
||||
}
|
||||
|
||||
---Validates if there aren't any wrong fields in the options.
|
||||
@@ -46,7 +57,8 @@ end
|
||||
--- default_values = {bar = false}, -- gives a default value to 'bar' when omitted
|
||||
--- regular_only = true, -- defaults to false
|
||||
--- admin_only = true, -- defaults to false
|
||||
--- debug_only = false, -- only registers it if _DEBUG is set to true when false
|
||||
--- debug_only = true, -- registers the command if _DEBUG is set to true, defaults to false
|
||||
--- cheat_only = true, -- registers the command if _CHEATS is set to true, defaults to false
|
||||
--- allowed_by_server = false, -- lets the server execute this, defaults to false
|
||||
--- allowed_by_player = true, -- lets players execute this, defaults to true
|
||||
--- log_command = true, -- defaults to false unless admin only, then always true
|
||||
@@ -68,7 +80,9 @@ function Command.add(command_name, options, callback)
|
||||
local regular_only = options.regular_only or false
|
||||
local admin_only = options.admin_only or false
|
||||
local debug_only = options.debug_only or false
|
||||
local cheat_only = options.cheat_only or false
|
||||
local capture_excess_arguments = options.capture_excess_arguments or false
|
||||
local custom_help_text = options.custom_help_text or false
|
||||
local allowed_by_server = options.allowed_by_server or false
|
||||
local allowed_by_player = options.allowed_by_player
|
||||
local log_command = options.log_command or options.admin_only or false
|
||||
@@ -81,7 +95,7 @@ function Command.add(command_name, options, callback)
|
||||
allowed_by_player = true
|
||||
end
|
||||
|
||||
if not _DEBUG and debug_only then
|
||||
if (not _DEBUG and debug_only) and (not _CHEATS and cheat_only) then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -115,7 +129,9 @@ function Command.add(command_name, options, callback)
|
||||
extra = ' (Regulars Only)'
|
||||
end
|
||||
|
||||
commands.add_command(command_name, argument_list .. description .. extra, function (command)
|
||||
local help_text = custom_help_text or argument_list .. description .. extra
|
||||
|
||||
commands.add_command(command_name, help_text, function (command)
|
||||
local print -- custom print reference in case no player is present
|
||||
local player = game.player
|
||||
local player_name = player and player.valid and player.name or '<server>'
|
||||
@@ -140,7 +156,7 @@ function Command.add(command_name, options, callback)
|
||||
end
|
||||
|
||||
if regular_only and not UserGroups.is_regular(player_name) then
|
||||
print(format("The command '%s' is not available to guests.", command_name))
|
||||
print(format("The command '%s' is not available to guests.", command_name))
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -239,4 +255,36 @@ function Command.search(keyword)
|
||||
return matches
|
||||
end
|
||||
|
||||
--- Warns in-game players of deprecated commands, ignores the server
|
||||
local function notify_deprecated(event)
|
||||
local alternative = deprecated_command_alternatives[event.command]
|
||||
if alternative then
|
||||
if event.player_index then
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
player.print(format('Warning! Usage of the command "/%s" is deprecated. Please use "/%s" instead.', event.command, alternative))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Traps command errors if not in DEBUG.
|
||||
if not _DEBUG then
|
||||
local old_add_command = commands.add_command
|
||||
commands.add_command =
|
||||
function(name, desc, func)
|
||||
old_add_command(
|
||||
name,
|
||||
desc,
|
||||
function(cmd)
|
||||
local success, error = pcall(func, cmd)
|
||||
if not success then
|
||||
log(error)
|
||||
Game.player_print('Sorry there was an error running ' .. cmd.name)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_console_command, notify_deprecated)
|
||||
|
||||
return Command
|
||||
|
||||
@@ -34,8 +34,8 @@ function Module.print_except(msg, player)
|
||||
end
|
||||
|
||||
--- Prints a message to all online admins
|
||||
--@param1 The message to print, as a string
|
||||
--@param2 The source of the message, as a string, LuaPlayer, or nil.
|
||||
--@param msg <string> The message to print
|
||||
--@param source <LuaPlayer|string|nil> string must be the name of a player, nil for server.
|
||||
function Module.print_admins(msg, source)
|
||||
local source_name
|
||||
local chat_color
|
||||
|
||||
Reference in New Issue
Block a user