1
0
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:
Matthew
2019-01-02 10:34:17 -05:00
committed by Valansch
parent b43eef96e7
commit a84dcfdd91
21 changed files with 1045 additions and 1075 deletions

View File

@@ -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,
},

View File

@@ -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
View 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
)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 = {}

View File

@@ -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
)

View File

@@ -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
)

View File

@@ -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

View File

@@ -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,14 +153,12 @@ 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
end
end
local function is_meltdown()
@@ -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)

View 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
)

View File

@@ -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 ''
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.')
Game.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.')
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
)

View File

@@ -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
)

View File

@@ -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)

View File

@@ -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
)

View File

@@ -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(
Command.add(
'cloud',
'Use your vape rig to create a pollution cloud around you',
{
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
end
)
commands.add_command(
)
Command.add(
'clean',
'Use your vacuum to suck up the pollution cloud around you',
{
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
)

View File

@@ -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>'
@@ -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

View File

@@ -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