2019-01-17 01:55:19 +02:00
|
|
|
local Command = require 'utils.command'
|
2020-09-23 12:14:36 +02:00
|
|
|
local Rank = require 'features.rank_system'
|
2019-01-17 01:55:19 +02:00
|
|
|
local Task = require 'utils.task'
|
|
|
|
local Token = require 'utils.token'
|
|
|
|
local Server = require 'features.server'
|
|
|
|
local Popup = require 'features.gui.popup'
|
|
|
|
local Global = require 'utils.global'
|
2019-01-30 05:52:43 +02:00
|
|
|
local Ranks = require 'resources.ranks'
|
2020-10-23 18:10:04 +02:00
|
|
|
local Core = require 'utils.core'
|
2020-11-05 20:28:34 +02:00
|
|
|
local Color = require 'resources.color_presets'
|
2019-01-17 01:55:19 +02:00
|
|
|
|
2020-10-01 22:08:09 +02:00
|
|
|
local Public = {}
|
|
|
|
|
|
|
|
function Public.control(config)
|
|
|
|
|
2019-01-17 01:55:19 +02:00
|
|
|
local server_player = {name = '<server>', print = print}
|
|
|
|
|
|
|
|
local global_data = {restarting = nil}
|
|
|
|
|
|
|
|
Global.register(
|
|
|
|
global_data,
|
|
|
|
function(tbl)
|
|
|
|
global_data = tbl
|
|
|
|
end
|
|
|
|
)
|
|
|
|
|
|
|
|
local function double_print(str)
|
|
|
|
game.print(str)
|
|
|
|
print(str)
|
|
|
|
end
|
|
|
|
|
|
|
|
local callback
|
|
|
|
callback =
|
|
|
|
Token.register(
|
|
|
|
function(data)
|
|
|
|
if not global_data.restarting then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local state = data.state
|
|
|
|
if state == 0 then
|
|
|
|
Server.start_scenario(data.scenario_name)
|
|
|
|
double_print('restarting')
|
2020-04-16 00:03:51 +02:00
|
|
|
global_data.restarting = nil
|
2019-01-17 01:55:19 +02:00
|
|
|
return
|
|
|
|
elseif state == 1 then
|
2020-10-23 18:10:04 +02:00
|
|
|
local time_string = Core.format_time(game.ticks_played)
|
|
|
|
local discord_crashsite_role = '<@&762441731194748958>' -- @crash_site
|
|
|
|
--local discord_crashsite_role = '<@&593534612051984431>' -- @test
|
|
|
|
Server.to_discord_raw(discord_crashsite_role .. ' **Crash Site has just restarted! Previous map lasted: ' .. time_string .. '!**')
|
2020-10-29 18:38:14 +02:00
|
|
|
|
2020-10-29 18:26:27 +02:00
|
|
|
local unix_time = Server.get_current_time()
|
|
|
|
local game_time = game.ticks_played
|
|
|
|
Server.set_data('crash_site_data', tostring(unix_time), game_time) -- Store the server unix time as key and total game ticks in the Scenario Data
|
2020-10-29 18:38:14 +02:00
|
|
|
|
2019-01-17 01:55:19 +02:00
|
|
|
Popup.all('\nServer restarting!\nInitiated by ' .. data.name .. '\n')
|
|
|
|
end
|
|
|
|
|
|
|
|
double_print(state)
|
|
|
|
|
|
|
|
data.state = state - 1
|
|
|
|
Task.set_timeout_in_ticks(60, callback, data)
|
|
|
|
end
|
|
|
|
)
|
|
|
|
|
2020-10-10 11:41:25 +02:00
|
|
|
local static_entities_to_check = {
|
2020-10-01 22:08:09 +02:00
|
|
|
'spitter-spawner','biter-spawner',
|
2020-10-01 22:52:47 +02:00
|
|
|
'small-worm-turret', 'medium-worm-turret','big-worm-turret', 'behemoth-worm-turret',
|
|
|
|
'gun-turret', 'laser-turret', 'artillery-turret', 'flamethrower-turret'
|
2020-10-01 22:08:09 +02:00
|
|
|
}
|
2020-10-10 14:07:22 +02:00
|
|
|
|
2020-10-10 11:41:25 +02:00
|
|
|
local biter_entities_to_check = {
|
|
|
|
'small-spitter', 'medium-spitter', 'big-spitter', 'behemoth-spitter',
|
|
|
|
'small-biter', 'medium-biter', 'big-biter', 'behemoth-biter'
|
|
|
|
}
|
2020-10-01 22:08:09 +02:00
|
|
|
|
2020-10-10 11:41:25 +02:00
|
|
|
local function map_cleared(player)
|
|
|
|
player = player or server_player
|
2020-10-01 22:08:09 +02:00
|
|
|
local get_entity_count = game.forces["enemy"].get_entity_count
|
2020-10-10 11:41:25 +02:00
|
|
|
-- Check how many of each turrets, worms and spawners are left and return false if there are any of each left.
|
|
|
|
for i = 1, #static_entities_to_check do
|
|
|
|
local name = static_entities_to_check[i]
|
2020-10-01 22:08:09 +02:00
|
|
|
if get_entity_count(name) > 0 then
|
2020-10-10 14:07:22 +02:00
|
|
|
player.print('All enemy spawners, worms, buildings, biters and spitters must be cleared before crashsite can be restarted.')
|
2020-10-01 22:08:09 +02:00
|
|
|
return false
|
|
|
|
end
|
|
|
|
end
|
2020-10-10 11:41:25 +02:00
|
|
|
|
|
|
|
-- Count all the remaining biters and spitters
|
|
|
|
local biter_total = 0;
|
|
|
|
for i = 1, #biter_entities_to_check do
|
2020-10-10 14:07:22 +02:00
|
|
|
local name = biter_entities_to_check[i]
|
2020-10-10 11:41:25 +02:00
|
|
|
biter_total = biter_total + get_entity_count(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Return false if more than 20 left. Players have had problems finding the last few biters so set to a reasonable value.
|
|
|
|
if biter_total > 20 then
|
2020-10-10 14:07:22 +02:00
|
|
|
player.print('All enemy spawners, worms, buildings are dead. Crashsite can be restarted when all biters and spitters are killed.')
|
2020-10-10 11:41:25 +02:00
|
|
|
return false
|
|
|
|
end
|
2020-10-01 22:08:09 +02:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2019-03-06 23:35:38 +02:00
|
|
|
local function restart(args, player)
|
|
|
|
player = player or server_player
|
2020-10-01 22:08:09 +02:00
|
|
|
local sanitised_scenario = args.scenario_name
|
2019-03-06 23:35:38 +02:00
|
|
|
|
|
|
|
if global_data.restarting then
|
|
|
|
player.print('Restart already in progress')
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2020-10-01 22:52:47 +02:00
|
|
|
if player ~= server_player and Rank.less_than(player.name, Ranks.admin) then
|
|
|
|
-- Check enemy count
|
2020-10-10 11:41:25 +02:00
|
|
|
if not map_cleared(player) then
|
2020-09-23 12:14:36 +02:00
|
|
|
return
|
2020-10-01 22:52:47 +02:00
|
|
|
end
|
2020-10-01 22:08:09 +02:00
|
|
|
|
|
|
|
-- Limit the ability of non-admins to call the restart function with arguments to change the scenario
|
|
|
|
-- If not an admin, restart the same scenario always
|
|
|
|
sanitised_scenario = config.scenario_name
|
2020-09-23 12:14:36 +02:00
|
|
|
end
|
2020-10-01 22:52:47 +02:00
|
|
|
|
2019-03-06 23:35:38 +02:00
|
|
|
global_data.restarting = true
|
|
|
|
|
|
|
|
double_print('#################-Attention-#################')
|
|
|
|
double_print('Server restart initiated by ' .. player.name)
|
|
|
|
double_print('###########################################')
|
|
|
|
|
2020-10-03 16:32:57 +02:00
|
|
|
for _, p in pairs(game.players) do
|
|
|
|
if p.admin then
|
|
|
|
p.print('Abort restart with /abort')
|
2019-03-06 23:35:38 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
print('Abort restart with /abort')
|
2020-10-01 22:08:09 +02:00
|
|
|
Task.set_timeout_in_ticks(60, callback, {name = player.name, scenario_name = sanitised_scenario, state = 10})
|
2019-03-06 23:35:38 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local function abort(_, player)
|
|
|
|
player = player or server_player
|
|
|
|
|
|
|
|
if global_data.restarting then
|
|
|
|
global_data.restarting = nil
|
|
|
|
double_print('Restart aborted by ' .. player.name)
|
|
|
|
else
|
|
|
|
player.print('Cannot abort a restart that is not in progress.')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-11-04 18:19:52 +02:00
|
|
|
local function spy(args, player)
|
|
|
|
local player_name = player.name
|
2020-11-10 22:11:18 +02:00
|
|
|
local inv = player.get_inventory(defines.inventory.character_main)
|
2020-11-05 20:28:34 +02:00
|
|
|
local coin_count = inv.get_item_count("coin")
|
2020-11-04 18:19:52 +02:00
|
|
|
|
2020-11-04 18:24:14 +02:00
|
|
|
-- Parse the values from the location string
|
2020-11-04 18:19:52 +02:00
|
|
|
-- {location = "[gps=-110,-17,redmew]"}
|
|
|
|
local location_string = args.location
|
|
|
|
local coords = {}
|
2020-11-06 20:56:42 +02:00
|
|
|
|
2020-11-04 18:24:14 +02:00
|
|
|
for m in string.gmatch( location_string, "%-?%d+" ) do
|
2020-11-04 18:19:52 +02:00
|
|
|
table.insert(coords, tonumber(m))
|
|
|
|
end
|
|
|
|
-- Do some checks then reveal the pinged map and remove 1000 coins
|
2020-11-10 22:11:18 +02:00
|
|
|
if #coords < 2 then
|
|
|
|
player.print({'command_description.crash_site_spy_invalid'}, Color.fail)
|
2020-11-04 18:19:52 +02:00
|
|
|
return
|
|
|
|
elseif coin_count < 1000 then
|
2020-11-10 22:11:18 +02:00
|
|
|
player.print({'command_description.crash_site_spy_funds'}, Color.fail)
|
2020-11-04 18:19:52 +02:00
|
|
|
return
|
|
|
|
else
|
|
|
|
local xpos=coords[1]
|
|
|
|
local ypos=coords[2]
|
2020-11-08 23:59:54 +02:00
|
|
|
-- reveal 3x3 chunks centred on chunk containing pinged location
|
|
|
|
player.force.chart(player.surface, {{xpos-32, ypos-32}, {xpos+32, ypos+32}})
|
2020-11-06 20:52:33 +02:00
|
|
|
game.print({'command_description.crash_site_spy_success', player_name, xpos,ypos}, Color.success)
|
2020-11-05 20:28:34 +02:00
|
|
|
inv.remove({name = "coin", count = 1000})
|
2020-11-04 18:19:52 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-03-06 23:35:38 +02:00
|
|
|
Command.add(
|
|
|
|
'crash-site-restart-abort',
|
|
|
|
{
|
|
|
|
description = {'command_description.crash_site_restart_abort'},
|
|
|
|
required_rank = Ranks.admin,
|
|
|
|
allowed_by_server = true
|
|
|
|
},
|
|
|
|
abort
|
|
|
|
)
|
2019-01-17 01:55:19 +02:00
|
|
|
|
|
|
|
Command.add(
|
2019-03-06 23:35:38 +02:00
|
|
|
'abort',
|
2019-01-17 01:55:19 +02:00
|
|
|
{
|
2019-03-04 00:13:56 +02:00
|
|
|
description = {'command_description.crash_site_restart_abort'},
|
2019-01-30 05:52:43 +02:00
|
|
|
required_rank = Ranks.admin,
|
2019-01-17 01:55:19 +02:00
|
|
|
allowed_by_server = true
|
|
|
|
},
|
2019-03-06 23:35:38 +02:00
|
|
|
abort
|
2019-01-17 01:55:19 +02:00
|
|
|
)
|
2019-07-28 12:44:13 +02:00
|
|
|
|
|
|
|
|
2020-11-04 18:19:52 +02:00
|
|
|
local default_name = config.scenario_name or 'crashsite'
|
|
|
|
Command.add(
|
|
|
|
'crash-site-restart',
|
|
|
|
{
|
|
|
|
description = {'command_description.crash_site_restart'},
|
|
|
|
arguments = {'scenario_name'},
|
|
|
|
default_values = {scenario_name = default_name},
|
|
|
|
required_rank = Ranks.admin,
|
|
|
|
allowed_by_server = true
|
|
|
|
},
|
|
|
|
restart
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'restart',
|
|
|
|
{
|
|
|
|
description = {'command_description.crash_site_restart'},
|
|
|
|
arguments = {'scenario_name'},
|
|
|
|
default_values = {scenario_name = default_name},
|
|
|
|
required_rank = Ranks.auto_trusted,
|
|
|
|
allowed_by_server = true
|
|
|
|
},
|
|
|
|
restart
|
|
|
|
)
|
|
|
|
|
|
|
|
Command.add(
|
|
|
|
'spy',
|
|
|
|
{
|
|
|
|
description = {'command_description.crash_site_spy'},
|
|
|
|
arguments = {'location'},
|
2020-11-05 20:28:34 +02:00
|
|
|
capture_excess_arguments = true,
|
|
|
|
required_rank = Ranks.guest,
|
2020-11-04 18:19:52 +02:00
|
|
|
allowed_by_server = false
|
|
|
|
},
|
|
|
|
spy
|
|
|
|
)
|
2019-07-28 12:44:13 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
return Public
|