1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-10-30 23:47:41 +02:00

Small commands refactor

This commit is contained in:
Gerkiz
2024-06-04 23:27:12 +02:00
parent da1dfda5a4
commit 091c64e11e
41 changed files with 2930 additions and 3312 deletions

View File

@@ -13,7 +13,7 @@ require 'utils.table'
require 'utils.whisper_notice'
require 'utils.datastore.init'
require 'utils.chatbot'
require 'utils.commands'
require 'utils.common_commands'
require 'utils.antigrief'
require 'utils.debug.command'
require 'modules.corpse_markers'

View File

@@ -1,375 +1,209 @@
local Color = require 'utils.color_presets'
local Public = require 'maps.mountain_fortress_v3.table'
local Task = require 'utils.task'
local Server = require 'utils.server'
local Collapse = require 'modules.collapse'
local WD = require 'modules.wave_defense.table'
local Discord = require 'utils.discord_handler'
local Commands = require 'utils.commands'
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
local scenario_name = Public.scenario_name
commands.add_command(
'scenario',
'Usable only for admins - controls the scenario!',
function(cmd)
local p
local player = game.player
if not player or not player.valid then
p = log
else
p = player.print
if not player.admin then
return
end
end
local this = Public.get()
local param = cmd.parameter
if param == 'restart' or param == 'shutdown' or param == 'reset' or param == 'restartnow' then
goto continue
else
p('[ERROR] Arguments are:\nrestart\nshutdown\nreset\nrestartnow')
return
end
::continue::
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
p('[WARNING] This command will disable the soft-reset feature, run this command again if you really want to do this!')
return
end
if param == 'restart' then
if this.restart then
this.reset_are_you_sure = nil
this.restart = false
this.soft_reset = true
p('[SUCCESS] Soft-reset is enabled.')
Discord.send_notification_raw(scenario_name, player.name .. ' has enabled soft-reset!')
return
else
this.reset_are_you_sure = nil
this.restart = true
this.soft_reset = false
if this.shutdown then
this.shutdown = false
end
Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset! Restart will happen from scenario.')
p('[WARNING] Soft-reset is disabled! Server will restart from scenario to load new changes.')
return
end
elseif param == 'restartnow' then
this.reset_are_you_sure = nil
Server.start_scenario('Mountain_Fortress_v3')
Discord.send_notification_raw(scenario_name, player.name .. ' restarted the scenario.')
return
elseif param == 'shutdown' then
if this.shutdown then
this.reset_are_you_sure = nil
this.shutdown = false
this.soft_reset = true
p('[SUCCESS] Soft-reset is enabled.')
Discord.send_notification_raw(scenario_name, player.name .. ' has enabled soft-reset. Server will NOT shutdown!')
return
else
this.reset_are_you_sure = nil
this.shutdown = true
this.soft_reset = false
if this.restart then
this.restart = false
end
p('[WARNING] Soft-reset is disabled! Server will shutdown. Most likely because of updates.')
Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset. Server will shutdown!')
return
end
elseif param == 'reset' then
this.reset_are_you_sure = nil
if player and player.valid then
game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
Discord.send_notification_raw(scenario_name, player.name .. ' has reset the game!')
else
game.print(mapkeeper .. ' server, has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
Discord.send_notification_raw(scenario_name, 'Server has reset the game!')
end
Public.reset_map()
p('[WARNING] Game has been reset!')
return
end
end
)
commands.add_command(
'set_queue_speed',
'Usable only for admins - sets the queue speed of this map!',
function(cmd)
local player = game.player
local param = tonumber(cmd.parameter)
if player and player.valid then
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
end
if not param then
return
end
Discord.send_notification_raw(scenario_name, player.name .. ' set the queue speed to: ' .. param)
player.print('Queue speed set to: ' .. param)
Task.set_queue_speed(param)
else
log('Queue speed set to: ' .. param)
Task.set_queue_speed(param)
end
end
)
commands.add_command(
'complete_quests',
'Usable only for admins - sets the queue speed of this map!',
function()
local player = game.player
if player and player.valid then
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
end
Commands.new('scenario', 'Usable only for admins - controls the scenario!')
:require_admin()
:require_validation()
:add_parameter('restart/shutdown/reset/restartnow', false, 'string')
:callback(
function (player, action)
local this = Public.get()
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
player.print('[WARNING] This command will break the current run and complete all quests, run this command again if you really want to do this!', Color.warning)
return
if action == 'restart' or action == 'shutdown' or action == 'reset' or action == 'restartnow' then
goto continue
else
player.print('Invalid action.')
return false
end
this.reset_are_you_sure = nil
::continue::
if action == 'restart' then
if this.restart then
this.reset_are_you_sure = nil
this.restart = false
this.soft_reset = true
Discord.send_notification_raw(scenario_name, player.name .. ' has enabled soft-reset!')
player.print('Soft-reset is enabled.')
else
this.reset_are_you_sure = nil
this.restart = true
this.soft_reset = false
if this.shutdown then
this.shutdown = false
end
Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset! Restart will happen from scenario.')
player.print('Soft-reset is disabled! Server will restart from scenario to load new changes.')
end
elseif action == 'restartnow' then
this.reset_are_you_sure = nil
Server.start_scenario('Mountain_Fortress_v3')
Discord.send_notification_raw(scenario_name, player.name .. ' restarted the scenario.')
player.print('Restarted the scenario.')
elseif action == 'shutdown' then
if this.shutdown then
this.reset_are_you_sure = nil
this.shutdown = false
this.soft_reset = true
Discord.send_notification_raw(scenario_name,
player.name .. ' has enabled soft-reset. Server will NOT shutdown!')
player.print('Soft-reset is enabled.')
else
this.reset_are_you_sure = nil
this.shutdown = true
this.soft_reset = false
if this.restart then
this.restart = false
end
Discord.send_notification_raw(scenario_name, player.name .. ' has disabled soft-reset. Server will shutdown!')
player.print('Soft-reset is disabled! Server will shutdown.')
end
elseif action == 'reset' then
this.reset_are_you_sure = nil
if player and player.valid then
game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!',
{ r = 0.98, g = 0.66, b = 0.22 })
Discord.send_notification_raw(scenario_name, player.name .. ' has reset the game!')
else
game.print(mapkeeper .. ' server, has reset the game!', { r = 0.98, g = 0.66, b = 0.22 })
Discord.send_notification_raw(scenario_name, 'Server has reset the game!')
end
Public.reset_map()
player.print('Game has been reset!')
end
end
)
Commands.new('mtn_set_queue_speed', 'Usable only for admins - sets the queue speed of this map!')
:require_admin()
:require_validation()
:add_parameter('speed', true, 'number')
:callback(
function (player, speed)
Task.set_queue_speed(speed)
Discord.send_notification_raw(scenario_name, player.name .. ' set the queue speed to: ' .. speed)
player.print('Queue speed set to: ' .. speed)
end
)
Commands.new('mtn_complete_quests', 'Usable only for admins - sets the queue speed of this map!')
:require_admin()
:require_validation()
:callback(
function (player)
Discord.send_notification_raw(scenario_name, player.name .. ' completed all the quest via command.')
Public.stateful.set_stateful('objectives_completed_count', 6)
game.print(mapkeeper .. player.name .. ', has forced completed all quests!', {r = 0.98, g = 0.66, b = 0.22})
else
local this = Public.get()
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
log('[WARNING] This command will break the current run and complete all quests, run this command again if you really want to do this!')
return
end
this.reset_are_you_sure = nil
log('Quests completed.')
Discord.send_notification_raw(scenario_name, 'Server completed all the quest via command')
Public.stateful.set_stateful('objectives_completed_count', 6)
game.print(mapkeeper .. player.name .. ', has forced completed all quests!', { r = 0.98, g = 0.66, b = 0.22 })
player.print('Quests completed.')
end
end
)
commands.add_command(
'reverse_map',
'Usable only for admins - reverses the map!',
function()
local player = game.player
if player and player.valid then
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
end
local this = Public.get()
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
player.print('[WARNING] This command will reverse the map and soft-reset!', Color.warning)
return
end
this.reset_are_you_sure = nil
)
Commands.new('mtn_reverse_map', 'Usable only for admins - reverses the map!')
:require_admin()
:require_validation()
:callback(
function (player)
local reversed = Public.get_stateful_settings('reversed')
Public.set_stateful_settings('reversed', not reversed)
Discord.send_notification_raw(scenario_name, player.name .. ' reversed the map.')
Public.reset_map()
game.print(mapkeeper .. player.name .. ', has reverse the map and reset the game!', {r = 0.98, g = 0.66, b = 0.22})
else
game.print(mapkeeper .. player.name .. ', has reverse the map and reset the game!',
{ r = 0.98, g = 0.66, b = 0.22 })
player.print('Map reversed.')
end
)
Commands.new('mtn_disable_biters', 'Usable only for admins - disables wave defense!')
:require_admin()
:require_validation()
:callback(
function (player)
local tbl = WD.get()
if not tbl.game_lost then
Discord.send_notification_raw(scenario_name, player.name .. ' disabled the wave defense module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the wave_defense module!',
{ r = 0.98, g = 0.66, b = 0.22 })
tbl.game_lost = true
else
Discord.send_notification_raw(scenario_name, player.name .. ' enabled the wave defense module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the wave_defense module!',
{ r = 0.98, g = 0.66, b = 0.22 })
tbl.game_lost = false
end
end
)
Commands.new('mtn_toggle_orbital_strikes',
'Usable only for admins - toggles orbital strikes!')
:require_admin()
:require_validation()
:callback(
function (player)
local this = Public.get()
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
log('[WARNING] This command will reverse the map and soft-reset!')
return
if this.orbital_strikes.enabled then
Discord.send_notification_raw(scenario_name, player.name .. ' disabled the orbital strike module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the orbital_strikes module!',
{ r = 0.98, g = 0.66, b = 0.22 })
this.orbital_strikes.enabled = false
else
Discord.send_notification_raw(scenario_name, player.name .. ' enabled the orbital strike module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the orbital_strikes module!',
{ r = 0.98, g = 0.66, b = 0.22 })
this.orbital_strikes.enabled = true
end
this.reset_are_you_sure = nil
local reversed = Public.get_stateful_settings('reversed')
Public.set_stateful_settings('reversed', not reversed)
Discord.send_notification_raw(scenario_name, 'script has reversed the map.')
Public.reset_map()
game.print(mapkeeper .. 'script, has reverse the map and reset the game!', {r = 0.98, g = 0.66, b = 0.22})
end
end
)
)
commands.add_command(
'disable_biters',
'Usable only for admins - disables wave defense!',
function()
local player = game.player
Commands.new('mtn_toggle_end_game', 'Usable only for admins - initiates the final battle!')
:require_admin()
:require_validation()
:callback(
function (player)
Discord.send_notification_raw(scenario_name, player.name .. ' toggled the end game.')
Public.stateful.set_stateful('final_battle', true)
Public.set('final_battle', true)
if not player or not player.valid then
return
game.print(mapkeeper .. ' ' .. player.name .. ', has triggered the final battle sequence!',
{ r = 0.98, g = 0.66, b = 0.22 })
end
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
)
Commands.new('mtn_get_queue_speed', 'Usable only for admins - gets the queue speed of this map!')
:require_admin()
:require_validation()
:callback(
function (player)
player.print(Task.get_queue_speed())
end
)
local this = Public.get()
local tbl = WD.get()
if not this.disable_biters_are_you_sure then
this.disable_biters_are_you_sure = true
player.print('[WARNING] This command will disable the wave_defense in-game, run this command again if you really want to do this!', Color.warning)
return
end
if not tbl.game_lost then
Discord.send_notification_raw(scenario_name, player.name .. ' disabled the wave defense module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the wave_defense module!', {r = 0.98, g = 0.66, b = 0.22})
tbl.game_lost = true
else
Discord.send_notification_raw(scenario_name, player.name .. ' enabled the wave defense module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the wave_defense module!', {r = 0.98, g = 0.66, b = 0.22})
tbl.game_lost = false
end
this.disable_biters_are_you_sure = nil
end
)
commands.add_command(
'toggle_orbital_strikes',
'Usable only for admins - toggles orbital strikes!',
function()
local player = game.player
if not player or not player.valid then
return
end
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
end
local this = Public.get()
if not this.orbital_strikes_are_you_sure then
this.orbital_strikes_are_you_sure = true
player.print('[WARNING] This command will disable the orbital_strikes in-game, run this command again if you really want to do this!', Color.warning)
return
end
if this.orbital_strikes.enabled then
Discord.send_notification_raw(scenario_name, player.name .. ' disabled the orbital strike module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled the orbital_strikes module!', {r = 0.98, g = 0.66, b = 0.22})
this.orbital_strikes.enabled = false
else
Discord.send_notification_raw(scenario_name, player.name .. ' enabled the orbital strike module.')
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled the orbital_strikes module!', {r = 0.98, g = 0.66, b = 0.22})
this.orbital_strikes.enabled = true
end
this.orbital_strikes_are_you_sure = nil
end
)
commands.add_command(
'toggle_end_game',
'Usable only for admins - initiates the final battle!',
function()
local player = game.player
if not player or not player.valid then
return
end
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
end
local this = Public.get()
if not this.final_battle_are_you_sure then
this.final_battle_are_you_sure = true
player.print('[WARNING] This command will trigger the final battle, ONLY run this command again if you really want to do this!', Color.warning)
return
end
Discord.send_notification_raw(scenario_name, player.name .. ' toggled the end game.')
Public.stateful.set_stateful('final_battle', true)
Public.set('final_battle', true)
game.print(mapkeeper .. ' ' .. player.name .. ', has triggered the final battle sequence!', {r = 0.98, g = 0.66, b = 0.22})
this.final_battle_are_you_sure = nil
end
)
commands.add_command(
'get_queue_speed',
'Usable only for admins - gets the queue speed of this map!',
function()
local p
local player = game.player
if player and player.valid then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
p(Task.get_queue_speed())
else
p = log
p(Task.get_queue_speed())
end
end
)
commands.add_command(
'disable_collapse',
'Toggles the collapse feature',
function()
local player = game.player
if player and player.valid then
if not player.admin then
player.print("[ERROR] You're not admin!", Color.fail)
return
end
Commands.new('mtn_disable_collapse', 'Usable only for admins - toggles the collapse feature!')
:require_admin()
:require_validation()
:callback(
function (player)
if not Collapse.has_collapse_started() then
Collapse.start_now(true, false)
Discord.send_notification_raw(scenario_name, player.name .. ' has enabled collapse.')
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled collapse!', {r = 0.98, g = 0.66, b = 0.22})
log(player.name .. ', has enabled collapse!')
game.print(mapkeeper .. ' ' .. player.name .. ', has enabled collapse!', { r = 0.98, g = 0.66, b = 0.22 })
else
Collapse.start_now(false, true)
Discord.send_notification_raw(scenario_name, player.name .. ' has disabled collapse.')
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled collapse!', {r = 0.98, g = 0.66, b = 0.22})
log(player.name .. ', has disabled collapse!')
end
else
if not Collapse.has_collapse_started() then
Collapse.start_now(true, false)
Discord.send_notification_raw(scenario_name, 'Server has enabled collapse.')
log('Collapse has started.')
else
Collapse.start_now(false, true)
Discord.send_notification_raw(scenario_name, 'Server has disabled collapse.')
log('Collapse has stopped.')
game.print(mapkeeper .. ' ' .. player.name .. ', has disabled collapse!',
{ r = 0.98, g = 0.66, b = 0.22 })
end
end
end
)
)
return Public

View File

@@ -47,7 +47,7 @@ local function get_top_frame(player)
end
local function increment(t, k)
t[k] = {trusted = true, drive = true}
t[k] = { trusted = true, drive = true }
end
local function decrement(t, k)
@@ -68,11 +68,12 @@ local function get_players(player, frame, all)
insert(tbl, tostring(p.name))
end
end
insert(tbl, ({'ic.select_player'}))
insert(tbl, ({ 'ic.select_player' }))
local selected_index = #tbl
local f = frame.add({type = 'drop-down', name = transfer_player_select_name, items = tbl, selected_index = selected_index})
local f = frame.add({ type = 'drop-down', name = transfer_player_select_name, items = tbl,
selected_index = selected_index })
return f
end
@@ -128,21 +129,21 @@ end
local function draw_add_player(player, frame)
local main_frame =
frame.add(
{
type = 'frame',
name = draw_add_player_frame_name,
caption = ({'ic.add_player'}),
direction = 'vertical'
}
)
{
type = 'frame',
name = draw_add_player_frame_name,
caption = ({ 'ic.add_player' }),
direction = 'vertical'
}
)
local main_frame_style = main_frame.style
main_frame_style.width = 370
main_frame_style.use_header_filler = true
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' }
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table = inside_frame.add { type = 'table', column_count = 1 }
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 5
inside_table_style.top_padding = 10
@@ -153,20 +154,20 @@ local function draw_add_player(player, frame)
local add_player_frame = get_players(player, main_frame)
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' })
local left_flow = bottom_flow.add({type = 'flow'})
local left_flow = bottom_flow.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
local close_button = left_flow.add({type = 'button', name = discard_add_player_name, caption = ({'ic.discard'})})
local close_button = left_flow.add({ type = 'button', name = discard_add_player_name, caption = ({ 'ic.discard' }) })
close_button.style = 'back_button' ---@class GuiButtonStyle
close_button.style.maximal_width = 100
local right_flow = bottom_flow.add({type = 'flow'})
local right_flow = bottom_flow.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
local save_button = right_flow.add({type = 'button', name = save_add_player_button_name, caption = ({'ic.save'})})
local save_button = right_flow.add({ type = 'button', name = save_add_player_button_name, caption = ({ 'ic.save' }) })
save_button.style = 'confirm_button' ---@class GuiButtonStyle
save_button.style.maximal_width = 100
@@ -176,21 +177,21 @@ end
local function draw_transfer_car(player, frame)
local main_frame =
frame.add(
{
type = 'frame',
name = draw_transfer_car_frame_name,
caption = ({'ic.transfer_car'}),
direction = 'vertical'
}
)
{
type = 'frame',
name = draw_transfer_car_frame_name,
caption = ({ 'ic.transfer_car' }),
direction = 'vertical'
}
)
local main_frame_style = main_frame.style
main_frame_style.width = 370
main_frame_style.use_header_filler = true
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' }
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table = inside_frame.add { type = 'table', column_count = 1 }
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 5
inside_table_style.top_padding = 10
@@ -199,25 +200,25 @@ local function draw_transfer_car(player, frame)
inside_table_style.bottom_padding = 10
inside_table_style.width = 325
local transfer_car_alert_frame = main_frame.add({type = 'label', caption = ({'ic.warning'})})
transfer_car_alert_frame.style.font_color = {r = 255, g = 0, b = 0}
local transfer_car_alert_frame = main_frame.add({ type = 'label', caption = ({ 'ic.warning' }) })
transfer_car_alert_frame.style.font_color = { r = 255, g = 0, b = 0 }
transfer_car_alert_frame.style.font = 'heading-1'
local transfer_car_frame = get_players(player, main_frame, true)
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' })
local left_flow = bottom_flow.add({type = 'flow'})
local left_flow = bottom_flow.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
local close_button = left_flow.add({type = 'button', name = discard_transfer_car_name, caption = ({'ic.discard'})})
local close_button = left_flow.add({ type = 'button', name = discard_transfer_car_name, caption = ({ 'ic.discard' }) })
close_button.style = 'back_button' ---@class GuiButtonStyle
close_button.style.maximal_width = 100
local right_flow = bottom_flow.add({type = 'flow'})
local right_flow = bottom_flow.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
local save_button = right_flow.add({type = 'button', name = save_transfer_car_button_name, caption = ({'ic.save'})})
local save_button = right_flow.add({ type = 'button', name = save_transfer_car_button_name, caption = ({ 'ic.save' }) })
save_button.style = 'confirm_button' ---@class GuiButtonStyle
save_button.style.maximal_width = 100
@@ -227,21 +228,21 @@ end
local function draw_destroy_surface_name(frame)
local main_frame =
frame.add(
{
type = 'frame',
name = draw_destroy_surface_frame_name,
caption = ({'ic.destroy_surface'}),
direction = 'vertical'
}
)
{
type = 'frame',
name = draw_destroy_surface_frame_name,
caption = ({ 'ic.destroy_surface' }),
direction = 'vertical'
}
)
local main_frame_style = main_frame.style
main_frame_style.width = 370
main_frame_style.use_header_filler = true
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' }
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table = inside_frame.add { type = 'table', column_count = 1 }
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 5
inside_table_style.top_padding = 10
@@ -250,28 +251,29 @@ local function draw_destroy_surface_name(frame)
inside_table_style.bottom_padding = 10
inside_table_style.width = 325
local destroy_car_frame = main_frame.add({type = 'label', caption = ({'ic.warning'})})
destroy_car_frame.style.font_color = {r = 255, g = 0, b = 0}
local destroy_car_frame = main_frame.add({ type = 'label', caption = ({ 'ic.warning' }) })
destroy_car_frame.style.font_color = { r = 255, g = 0, b = 0 }
destroy_car_frame.style.font = 'heading-1'
local warn_again_frame = main_frame.add({type = 'label', caption = ({'ic.warning_2'})})
warn_again_frame.style.font_color = {r = 255, g = 0, b = 0}
local warn_again_frame = main_frame.add({ type = 'label', caption = ({ 'ic.warning_2' }) })
warn_again_frame.style.font_color = { r = 255, g = 0, b = 0 }
warn_again_frame.style.font = 'heading-1'
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' })
local left_flow = bottom_flow.add({type = 'flow'})
local left_flow = bottom_flow.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
local close_button = left_flow.add({type = 'button', name = discard_destroy_surface_name, caption = ({'ic.discard'})})
local close_button = left_flow.add({ type = 'button', name = discard_destroy_surface_name, caption = ({ 'ic.discard' }) })
close_button.style = 'back_button' ---@class GuiButtonStyle
close_button.style.maximal_width = 100
local right_flow = bottom_flow.add({type = 'flow'})
local right_flow = bottom_flow.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
local save_button = right_flow.add({type = 'button', name = save_destroy_surface_button_name, caption = ({'ic.save'})})
local save_button = right_flow.add({ type = 'button', name = save_destroy_surface_button_name,
caption = ({ 'ic.save' }) })
save_button.style = 'confirm_button' ---@class GuiButtonStyle
save_button.style.maximal_width = 100
@@ -288,55 +290,55 @@ local function draw_players(data)
Gui.set_data(add_player_frame, p)
local t_label =
player_table.add(
{
type = 'label',
caption = p
}
)
{
type = 'label',
caption = p
}
)
t_label.style.minimal_width = 75
t_label.style.horizontal_align = 'center'
local a_flow = player_table.add {type = 'flow'}
local a_flow = player_table.add { type = 'flow' }
local a_label =
a_flow.add(
{
type = 'label',
caption = p_data.trusted and '✔️' or '✖️',
name = trust_player_name,
tooltip = ({'ic.allowed_tooltip'})
}
)
{
type = 'label',
caption = p_data.trusted and '✔️' or '✖️',
name = trust_player_name,
tooltip = ({ 'ic.allowed_tooltip' })
}
)
a_label.style.minimal_width = 75
a_label.style.horizontal_align = 'center'
a_label.style.font = 'default-large-bold'
local d_flow = player_table.add {type = 'flow'}
local d_flow = player_table.add { type = 'flow' }
local d_label =
d_flow.add(
{
type = 'label',
caption = p_data.drive and '✔️' or '✖️',
name = drive_player_name,
tooltip = ({'ic.drive_tooltip'})
}
)
{
type = 'label',
caption = p_data.drive and '✔️' or '✖️',
name = drive_player_name,
tooltip = ({ 'ic.drive_tooltip' })
}
)
d_label.style.minimal_width = 75
d_label.style.horizontal_align = 'center'
d_label.style.font = 'default-large-bold'
local kick_flow = player_table.add {type = 'flow'}
local kick_flow = player_table.add { type = 'flow' }
local kick_player_button =
kick_flow.add(
{
type = 'button',
caption = ({'ic.kick'}),
name = kick_player_name
}
)
{
type = 'button',
caption = ({ 'ic.kick' }),
name = kick_player_name
}
)
if player.name == t_label.caption then
kick_player_button.enabled = false
a_label.tooltip = ({'ic.not_self'})
d_label.tooltip = ({'ic.not_self'})
a_label.tooltip = ({ 'ic.not_self' })
d_label.tooltip = ({ 'ic.not_self' })
end
kick_player_button.style.minimal_width = 75
Gui.set_data(a_label, p)
@@ -348,25 +350,25 @@ end
local function draw_main_frame(player)
local main_frame =
player.gui.screen.add(
{
type = 'frame',
name = main_frame_name,
caption = ({'ic.car_settings'}),
direction = 'vertical',
style = 'inner_frame_in_outer_frame'
}
)
{
type = 'frame',
name = main_frame_name,
caption = ({ 'ic.car_settings' }),
direction = 'vertical',
style = 'inner_frame_in_outer_frame'
}
)
main_frame.auto_center = true
local main_frame_style = main_frame.style
main_frame_style.width = 450
main_frame_style.use_header_filler = true
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' }
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table = inside_frame.add { type = 'table', column_count = 1 }
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 5
inside_table_style.top_padding = 10
@@ -377,52 +379,54 @@ local function draw_main_frame(player)
local player_list = Functions.get_trusted_system(player)
local add_player_frame = inside_table.add({type = 'button', caption = ({'ic.add_player'}), name = add_player_name})
local transfer_car_frame = inside_table.add({type = 'button', caption = ({'ic.car_settings'}), name = transfer_car_name})
local destroy_surface_frame = inside_table.add({type = 'button', caption = ({'ic.destroy_surface'}), name = destroy_surface_name})
local add_player_frame = inside_table.add({ type = 'button', caption = ({ 'ic.add_player' }), name = add_player_name })
local transfer_car_frame = inside_table.add({ type = 'button', caption = ({ 'ic.car_settings' }),
name = transfer_car_name })
local destroy_surface_frame = inside_table.add({ type = 'button', caption = ({ 'ic.destroy_surface' }),
name = destroy_surface_name })
local allow_anyone_to_enter =
inside_table.add(
{
type = 'switch',
name = allow_anyone_to_enter_name,
switch_state = player_list.allow_anyone,
allow_none_state = false,
left_label_caption = ({'ic.allow_anyone'}),
right_label_caption = ({'ic.off'})
}
)
{
type = 'switch',
name = allow_anyone_to_enter_name,
switch_state = player_list.allow_anyone,
allow_none_state = false,
left_label_caption = ({ 'ic.allow_anyone' }),
right_label_caption = ({ 'ic.off' })
}
)
local auto_upgrade =
inside_table.add(
{
type = 'switch',
name = auto_upgrade_name,
switch_state = player_list.auto_upgrade,
allow_none_state = false,
left_label_caption = ({'ic.auto_upgrade'}),
right_label_caption = ({'ic.off'})
}
)
{
type = 'switch',
name = auto_upgrade_name,
switch_state = player_list.auto_upgrade,
allow_none_state = false,
left_label_caption = ({ 'ic.auto_upgrade' }),
right_label_caption = ({ 'ic.off' })
}
)
local notify_on_driver_change =
inside_table.add(
{
type = 'switch',
name = notify_on_driver_change_name,
switch_state = player_list.notify_on_driver_change,
allow_none_state = false,
left_label_caption = ({'ic.notify_on_driver_change'}),
right_label_caption = ({'ic.off'})
}
)
{
type = 'switch',
name = notify_on_driver_change_name,
switch_state = player_list.notify_on_driver_change,
allow_none_state = false,
left_label_caption = ({ 'ic.notify_on_driver_change' }),
right_label_caption = ({ 'ic.off' })
}
)
local player_table =
inside_table.add {
type = 'table',
column_count = 4,
draw_horizontal_lines = true,
draw_vertical_lines = true,
vertical_centering = true
}
type = 'table',
column_count = 4,
draw_horizontal_lines = true,
draw_vertical_lines = true,
vertical_centering = true
}
local player_table_style = player_table.style
player_table_style.vertical_spacing = 10
player_table_style.width = 400
@@ -430,45 +434,45 @@ local function draw_main_frame(player)
local name_label =
player_table.add(
{
type = 'label',
caption = ({'ic.name'}),
tooltip = ''
}
)
{
type = 'label',
caption = ({ 'ic.name' }),
tooltip = ''
}
)
name_label.style.minimal_width = 75
name_label.style.horizontal_align = 'center'
local trusted_label =
player_table.add(
{
type = 'label',
caption = ({'ic.allowed'}),
tooltip = ''
}
)
{
type = 'label',
caption = ({ 'ic.allowed' }),
tooltip = ''
}
)
trusted_label.style.minimal_width = 75
trusted_label.style.horizontal_align = 'center'
local allowed_to_drive =
player_table.add(
{
type = 'label',
caption = ({'ic.drive'}),
tooltip = ''
}
)
{
type = 'label',
caption = ({ 'ic.drive' }),
tooltip = ''
}
)
allowed_to_drive.style.minimal_width = 75
allowed_to_drive.style.horizontal_align = 'center'
local operations_label =
player_table.add(
{
type = 'label',
caption = ({'ic.operations'}),
tooltip = ''
}
)
{
type = 'label',
caption = ({ 'ic.operations' }),
tooltip = ''
}
)
operations_label.style.minimal_width = 75
operations_label.style.horizontal_align = 'center'
@@ -515,21 +519,21 @@ add_toolbar = function(player, remove)
return
end
local tooltip = ({'ic.control'})
local tooltip = ({ 'ic.control' })
if Gui.get_mod_gui_top_frame() then
local b =
Gui.add_mod_button(
player,
{
type = 'sprite-button',
name = main_toolbar_name,
sprite = 'item/spidertron',
tooltip = tooltip,
style = Gui.button_style
}
)
player,
{
type = 'sprite-button',
name = main_toolbar_name,
sprite = 'item/spidertron',
tooltip = tooltip,
style = Gui.button_style
}
)
if b then
b.style.font_color = {165, 165, 165}
b.style.font_color = { 165, 165, 165 }
b.style.font = 'heading-3'
b.style.minimal_height = 36
b.style.maximal_height = 36
@@ -539,14 +543,14 @@ add_toolbar = function(player, remove)
else
local button =
player.gui.top.add(
{
type = 'sprite-button',
sprite = 'item/spidertron',
name = main_toolbar_name,
tooltip = tooltip,
style = Gui.button_style
}
)
{
type = 'sprite-button',
sprite = 'item/spidertron',
name = main_toolbar_name,
tooltip = tooltip,
style = Gui.button_style
}
)
button.style.minimal_height = 38
button.style.maximal_height = 38
end
@@ -745,10 +749,13 @@ Gui.on_click(
if frame and frame.valid then
if player_list.notify_on_driver_change == 'right' then
player_list.notify_on_driver_change = 'left'
player.print('[IC] You will now be notified whenever someone not trusted tries to drive your car!', Color.success)
player.print('[IC] You will now be notified whenever someone not trusted tries to drive your car!',
Color.success)
else
player_list.notify_on_driver_change = 'right'
player.print('[IC] No notifications will be sent to you when someone not trusted tries to drive your car.', Color.warning)
player.print(
'[IC] No notifications will be sent to you when someone not trusted tries to drive your car.',
Color.warning)
end
if player.gui.screen[main_frame_name] then
@@ -852,7 +859,8 @@ Gui.on_click(
player.print('[IC] Please try again.', Color.warning)
else
player.print('[IC] You have successfully transferred your car to ' .. name, Color.success)
player_to_add.print('[IC] You have become the rightfully owner of ' .. player.name .. "'s car!", Color.success)
player_to_add.print('[IC] You have become the rightfully owner of ' .. player.name .. "'s car!",
Color.success)
end
remove_main_frame(event.element)
@@ -867,16 +875,16 @@ Gui.on_click(
local clear_misc_settings =
Task.register(
function(data)
local player_index = data.player_index
local misc_settings = ICT.get('misc_settings')
if not misc_settings[player_index] then
return
end
function(data)
local player_index = data.player_index
local misc_settings = ICT.get('misc_settings')
if not misc_settings[player_index] then
return
end
misc_settings[player_index] = nil
end
)
misc_settings[player_index] = nil
end
)
Gui.on_click(
save_destroy_surface_button_name,
@@ -905,14 +913,16 @@ Gui.on_click(
}
player.print('[IC] ARE YOU SURE? This action is irreversible!', Color.warning)
Task.set_timeout_in_ticks(600, clear_misc_settings, {player_index = player.index})
Task.set_timeout_in_ticks(600, clear_misc_settings, { player_index = player.index })
return
end
if not misc_settings[player.index].final_warning then
misc_settings[player.index].final_warning = true
player.print('[IC] WARNING! WARNING WARNING! Pressing the save button ONE MORE TIME will DELETE your surface. This action is irreversible!', Color.red)
Task.set_timeout_in_ticks(600, clear_misc_settings, {player_index = player.index})
player.print(
'[IC] WARNING! WARNING WARNING! Pressing the save button ONE MORE TIME will DELETE your surface. This action is irreversible!',
Color.red)
Task.set_timeout_in_ticks(600, clear_misc_settings, { player_index = player.index })
return
end
@@ -928,9 +938,13 @@ Gui.on_click(
local suc, count = Functions.kill_car_but_save_surface(entity)
if suc then
game.print('[IC] ' .. player.name .. ' has destroyed their surface!', Color.warning)
Discord.send_notification_raw(scenario_name, player.name .. ' deleted their vehicle surface at x = ' .. position.x .. ' y = ' .. position.y .. '.')
Discord.send_notification_raw(scenario_name,
player.name ..
' deleted their vehicle surface at x = ' .. position.x .. ' y = ' .. position.y .. '.')
else
player.print('[IC] Entities are still on the surface. Please remove any entities and retry this operation. Found ' .. count .. ' entities!', Color.warning)
player.print(
'[IC] Entities are still on the surface. Please remove any entities and retry this operation. Found ' ..
count .. ' entities!', Color.warning)
end
end

View File

@@ -539,7 +539,7 @@ local function refresh_main_frame(data)
chestitem.enabled = false
chestitem.tooltip = '[Antigrief] You have not grown accustomed to this technology yet.'
end
Gui.set_data_parent(volatile_tbl, chestitem, {name = nil, unit_number = unit_number, share = source_chest.share.name})
Gui.set_data(chestitem, {name = nil, unit_number = unit_number, share = source_chest.share.name})
end
end
end
@@ -1290,13 +1290,8 @@ Gui.on_click(
Gui.remove_data_recursively(element)
return
end
local parent = player_data.volatile_tbl
if not parent or not parent.valid then
Gui.remove_data_recursively(element)
return
end
local data = Gui.get_data_parent(parent, element)
local data = Gui.get_data(element)
if not data then
return
end
@@ -1333,10 +1328,10 @@ Gui.on_click(
container.chest.minable = false
this.linked_gui[event.player.name].updated = false
refresh_main_frame({unit_number = container.unit_number, player = event.player})
if element and element.valid then
Gui.remove_data_recursively(element)
end
refresh_main_frame({unit_number = container.unit_number, player = event.player})
end
end
)
@@ -1497,6 +1492,7 @@ function Public.reset()
this.pre_reset_run = false
end
Event.on_init(Public.reset)
Event.add(defines.events.on_built_entity, on_built_entity)
Event.add(defines.events.on_robot_built_entity, built_entity_robot)
Event.add(defines.events.on_pre_player_mined_item, on_pre_player_mined_item)

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
local Event = require 'utils.event'
local Global = require 'utils.global'
local Gui = require 'utils.gui'
local Commands = require 'utils.commands'
local this = {
renders = {},
@@ -30,11 +31,11 @@ local this = {
local Public = {}
Public.metatable = {__index = Public}
Public.metatable = { __index = Public }
Global.register(
this,
function(tbl)
function (tbl)
this = tbl
for _, render in pairs(this.renders) do
setmetatable(render, Public.metatable)
@@ -59,7 +60,7 @@ function Public:new_render()
rendering.destroy(self.render_id)
end
self.render_id = rendering.draw_sprite {target = self.position, sprite = self.sprite, surface = surface}
self.render_id = rendering.draw_sprite { target = self.position, sprite = self.sprite, surface = surface }
return self
end
@@ -71,13 +72,13 @@ function Public:new_target()
return
end
local position
local entities = surface.find_entities_filtered {type = this.valid_targets, force = 'player'}
local entities = surface.find_entities_filtered { type = this.valid_targets, force = 'player' }
if entities and #entities > 0 then
position = entities[random(#entities)].position
end
local chunk = surface.get_random_chunk()
local random_position = {x = (chunk.x + random()) * 32, y = (chunk.y + random()) * 32}
local random_position = { x = (chunk.x + random()) * 32, y = (chunk.y + random()) * 32 }
if not position then
return random_position, random_position
end
@@ -91,7 +92,7 @@ function Public:subtr()
if not self.position and self.target_position then
return 0
end
return {x = self.target_position.x - self.position.x, y = self.target_position.y - self.position.y}
return { x = self.target_position.x - self.position.x, y = self.target_position.y - self.position.y }
end
--- Sets the render scale.
@@ -101,7 +102,7 @@ function Public:set_render_scalar_size()
end
rendering.set_y_scale(self.render_id, 3.5) -- 1.5
rendering.set_x_scale(self.render_id, 7) -- 2
rendering.set_x_scale(self.render_id, 7) -- 2
rendering.set_color(
self.render_id,
{
@@ -115,7 +116,7 @@ end
--- Gets a random position.
---@return table
function Public:random_position()
return {x = self.position.x + (random() - 0.5) * 64, y = self.position.y + (random() - 0.5) * 64}
return { x = self.position.x + (random() - 0.5) * 64, y = self.position.y + (random() - 0.5) * 64 }
end
--- Sets a random sprite
@@ -150,12 +151,12 @@ function Public:change_position(max_abs, value)
local multiply = sqrt(subtr.x * subtr.x + subtr.y * subtr.y)
if (multiply > max_abs) then
local close = max_abs / multiply
subtr = {x = subtr.x * close, y = subtr.y * close}
subtr = { x = subtr.x * close, y = subtr.y * close }
end
if value then
subtr.y = subtr.y * scalar
end
return {x = self.position.x + subtr.x, y = self.position.y + subtr.y}
return { x = self.position.x + subtr.x, y = self.position.y + subtr.y }
end
--- If a render is stuck, give it a new position.
@@ -168,7 +169,7 @@ function Public:switch_position()
return
end
local chunk = surface.get_random_chunk()
self.target_position = {x = (chunk.x + math.random()) * 32, y = (chunk.y + math.random()) * 32}
self.target_position = { x = (chunk.x + math.random()) * 32, y = (chunk.y + math.random()) * 32 }
end
end
@@ -198,13 +199,13 @@ function Public:render_chart()
self.chart =
game.forces[self.force].add_chart_tag(
surface,
{
icon = {type = 'virtual', name = 'signal-info'},
position = self.position,
text = 'Beam'
}
)
surface,
{
icon = { type = 'virtual', name = 'signal-info' },
position = self.position,
text = 'Beam'
}
)
end
--- Sets a new position for a render.
@@ -233,12 +234,12 @@ function Public:render_fire_damage()
return
end
surface.create_entity({name = 'fire-flame', position = {x = self.position.x, y = self.position.y + 5}})
surface.create_entity({ name = 'fire-flame', position = { x = self.position.x, y = self.position.y + 5 } })
if random(1, 5) == 1 then
surface.create_entity(
{
name = 'medium-scorchmark',
position = {x = self.position.x, y = self.position.y + 5},
position = { x = self.position.x, y = self.position.y + 5 },
force = 'neutral'
}
)
@@ -257,13 +258,13 @@ function Public:damage_entities_nearby()
local damage = random(10, 15)
local entities =
surface.find_entities_filtered(
{
position = self.position,
radius = 20,
type = 'simple-entity',
invert = true
}
)
{
position = self.position,
radius = 20,
type = 'simple-entity',
invert = true
}
)
for _, entity in pairs(entities) do
if entity.valid then
if entity.health then
@@ -351,7 +352,7 @@ function Public.new(sprite, surface, ttl, scalar, delayed)
render.delayed = game.tick + delayed
render.ttl = ttl or (game.tick + delayed) + 7200 -- 2 minutes duration
else
render.ttl = ttl or game.tick + 7200 -- 2 minutes duration
render.ttl = ttl or game.tick + 7200 -- 2 minutes duration
render:validate()
if not scalar then
render:set_render_scalar_size()
@@ -396,7 +397,7 @@ end
Event.add(
defines.events.on_tick,
function()
function ()
if #this.renders == 0 then
return
end
@@ -418,20 +419,13 @@ Event.add(
end
)
if _DEBUG then
commands.add_command(
'laser',
'new laser',
function()
local player = game.player
if player and player.valid then
if not player.admin then
return
end
Commands.new('laser', 'new laser')
:require_admin()
:callback(
function (player)
Public.new_beam_delayed(player.surface, 222)
end
end
)
)
end
return Public

View File

@@ -1,10 +1,11 @@
local Public = require 'modules.rpg.table'
local Utils = require 'utils.core'
local Color = require 'utils.color_presets'
local Commands = require 'utils.commands'
local round = math.round
local validate_args = function(data)
local validate_args = function (data)
local player = data.player
local target = data.target
local rpg_t = Public.get_value_from_player(target.index)
@@ -62,7 +63,7 @@ local validate_args = function(data)
return true
end
local print_stats = function(target)
local print_stats = function (target)
if not target then
return
end
@@ -88,146 +89,84 @@ local print_stats = function(target)
return output
end
commands.add_command(
'stats',
'Check what stats a user has!',
function(cmd)
local player = game.player
Commands.new('stats', 'Check what stats a user has!')
:add_parameter('player', false, 'player')
:callback(
function (player, target)
local data = {
player = player,
target = target
}
if not player or not player.valid then
return
if validate_args(data) then
local msg = print_stats(target)
player.play_sound { path = 'utility/scenario_message', volume_modifier = 1 }
player.print(msg)
else
player.print('[Stats] Please type a name of a player who is connected.', Color.warning)
return false
end
end
)
local param = cmd.parameter
if not param then
return
end
if param == '' then
return
end
local target = game.players[param]
if not target or not target.valid then
return
end
local data = {
player = player,
target = target
}
if validate_args(data) then
local msg = print_stats(target)
player.play_sound {path = 'utility/scenario_message', volume_modifier = 1}
player.print(msg)
else
player.print('[Stats] Please type a name of a player who is connected.', Color.warning)
end
end
)
if _DEBUG then
commands.add_command(
'give_xp',
'DEBUG ONLY - if you are seeing this then this map is running on debug-mode.',
function(cmd)
local p
local player = game.player
local param = tonumber(cmd.parameter)
Commands.new('give_xp', 'Give a player XP!')
:require_admin()
:add_parameter('amount', false, 'number')
:callback(
function (_, amount)
Public.give_xp(amount)
game.print('Distributed ' .. amount .. ' of xp.')
end
)
if player then
if player ~= nil then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
Commands.new('rpg_debug_module', 'Toggle debug mode for RPG module!')
:require_admin()
:callback(
function ()
Public.toggle_debug()
end
)
Commands.new('rpg_debug_aoe_punch', 'Toggle debug mode for RPG module!')
:require_admin()
:callback(
function ()
Public.toggle_debug_aoe_punch()
end
)
Commands.new('rpg_cheat_stats', 'Cheat stats for testing purposes!')
:require_admin()
:callback(
function ()
local data = Public.get('rpg_t')
for k, _ in pairs(data) do
data[k].dexterity = 999
data[k].enable_entity_spawn = true
data[k].explosive_bullets = true
data[k].level = 1000
data[k].magicka = 999
data[k].mana = 50000
data[k].mana_max = 50000
data[k].debug_mode = true
data[k].aoe_punch = true
data[k].stone_path = true
data[k].strength = 3000
data[k].vitality = 3000
data[k].xp = 456456
local p = game.get_player(k)
if p and p.valid then
Public.update_player_stats(p)
end
if not param then
return
end
p('Distributed ' .. param .. ' of xp.')
Public.give_xp(param)
end
end
end
)
commands.add_command(
'rpg_debug_module',
'',
function()
local player = game.player
if not (player and player.valid) then
return
end
if not player.admin then
return
end
Public.toggle_debug()
end
)
commands.add_command(
'rpg_debug_aoe_punch',
'',
function()
local player = game.player
if not (player and player.valid) then
return
end
if not player.admin then
return
end
Public.toggle_debug_aoe_punch()
end
)
commands.add_command(
'rpg_cheat_stats',
'',
function()
local player = game.player
if not (player and player.valid) then
return
end
if not player.admin then
return
end
local data = Public.get('rpg_t')
for k, _ in pairs(data) do
data[k].dexterity = 999
data[k].enable_entity_spawn = true
data[k].explosive_bullets = true
data[k].level = 1000
data[k].magicka = 999
data[k].mana = 50000
data[k].mana_max = 50000
data[k].debug_mode = true
data[k].aoe_punch = true
data[k].stone_path = true
data[k].strength = 3000
data[k].vitality = 3000
data[k].xp = 456456
local p = game.get_player(k)
if p and p.valid then
Public.update_player_stats(p)
end
end
end
)
)
end
local RPG_Interface = {
rpg_reset_player = function(player_name)
rpg_reset_player = function (player_name)
if player_name then
local player = game.get_player(player_name)
if player and player.valid then
@@ -239,14 +178,14 @@ local RPG_Interface = {
error('Remote call parameter to RPG rpg_reset_player must be a valid player name and not nil.')
end
end,
give_xp = function(amount)
give_xp = function (amount)
if type(amount) == 'number' then
return Public.give_xp(amount)
else
error('Remote call parameter to RPG give_xp must be number and not nil.')
end
end,
gain_xp = function(player_name, amount)
gain_xp = function (player_name, amount)
if player_name then
local player = game.get_player(player_name)
if player and player.valid and type(amount) == 'number' then

View File

@@ -5,6 +5,7 @@ local Color = require 'utils.color_presets'
local SpamProtection = require 'utils.spam_protection'
local Event = require 'utils.event'
local Gui = require 'utils.gui'
local Commands = require 'utils.commands'
local this = {
data = {},
@@ -14,7 +15,7 @@ local Public = {}
Global.register(
this,
function(tbl)
function (tbl)
this = tbl
end
)
@@ -63,7 +64,7 @@ local function add_style(guiIn, styleIn)
end
local function adjust_space(guiIn)
add_style(guiIn.add {type = 'line', direction = 'horizontal'}, space)
add_style(guiIn.add { type = 'line', direction = 'horizontal' }, space)
end
local function is_valid(obj)
@@ -158,19 +159,19 @@ end
local function get_inventory_type(player, inventory_type)
local target_types = {
['Main'] = function()
['Main'] = function ()
return unpack_inventory(player.get_main_inventory())
end,
['Armor'] = function()
['Armor'] = function ()
return unpack_inventory(player.get_inventory(defines.inventory.character_armor))
end,
['Guns'] = function()
['Guns'] = function ()
return unpack_inventory(player.get_inventory(defines.inventory.character_guns))
end,
['Ammo'] = function()
['Ammo'] = function ()
return unpack_inventory(player.get_inventory(defines.inventory.character_ammo))
end,
['Trash'] = function()
['Trash'] = function ()
return unpack_inventory(player.get_inventory(defines.inventory.character_trash))
end
}
@@ -180,7 +181,7 @@ end
local function redraw_inventory(gui, source, target, caption, panel_type)
gui.clear()
local items_table = gui.add({type = 'table', column_count = 11})
local items_table = gui.add({ type = 'table', column_count = 11 })
local types = game.item_prototypes
local screen = source.gui.screen
@@ -196,20 +197,20 @@ local function redraw_inventory(gui, source, target, caption, panel_type)
if panel_type[i] and panel_type[i].valid_for_read then
local name = panel_type[i].name
local count = panel_type[i].count
local flow = items_table.add({type = 'flow'})
local flow = items_table.add({ type = 'flow' })
flow.style.vertical_align = 'bottom'
local button =
flow.add(
{
type = 'sprite-button',
sprite = 'item/' .. name,
number = count,
name = name,
tooltip = types[name].localised_name,
style = 'slot_button'
}
)
{
type = 'sprite-button',
sprite = 'item/' .. name,
number = count,
name = name,
tooltip = types[name].localised_name,
style = 'slot_button'
}
)
button.enabled = false
if caption == 'Armor' then
@@ -218,15 +219,15 @@ local function redraw_inventory(gui, source, target, caption, panel_type)
for k, v in pairs(p_armor) do
local armor_gui =
flow.add(
{
type = 'sprite-button',
sprite = 'item/' .. k,
number = v,
name = k,
tooltip = types[name].localised_name,
style = 'slot_button'
}
)
{
type = 'sprite-button',
sprite = 'item/' .. k,
number = v,
name = k,
tooltip = types[name].localised_name,
style = 'slot_button'
}
)
armor_gui.enabled = false
end
end
@@ -238,15 +239,15 @@ end
local function add_inventory(panel, source, target, caption, panel_type)
local data = get_player_data(source)
data.panel_type = data.panel_type or {}
local pane_name = panel.add({type = 'tab', caption = caption, name = caption})
local pane_name = panel.add({ type = 'tab', caption = caption, name = caption })
local scroll_pane =
panel.add {
type = 'scroll-pane',
name = caption .. 'tab',
direction = 'vertical',
vertical_scroll_policy = 'always',
horizontal_scroll_policy = 'never'
}
type = 'scroll-pane',
name = caption .. 'tab',
direction = 'vertical',
vertical_scroll_policy = 'always',
horizontal_scroll_policy = 'never'
}
scroll_pane.style.maximal_height = 200
scroll_pane.style.horizontally_stretchable = true
scroll_pane.style.minimal_height = 200
@@ -281,13 +282,13 @@ local function open_inventory(source, target)
local frame =
screen.add(
{
type = 'frame',
caption = 'Inventory',
direction = 'vertical',
name = main_frame_name
}
)
{
type = 'frame',
caption = 'Inventory',
direction = 'vertical',
name = main_frame_name
}
)
if not (frame and frame.valid) then
return
@@ -299,7 +300,7 @@ local function open_inventory(source, target)
adjust_space(frame)
local panel = frame.add({type = 'tabbed-pane', name = 'tabbed_pane'})
local panel = frame.add({ type = 'tabbed-pane', name = 'tabbed_pane' })
panel.selected_tab_index = 1
local data = get_player_data(source)
@@ -416,42 +417,29 @@ local function update_gui(event)
end
end
commands.add_command(
'inventory',
'Opens a players inventory!',
function(cmd)
local player = game.player
if this.module_disabled then
return
end
if validate_player(player) then
if not cmd.parameter then
return
Commands.new('inventory', 'Open another players inventory')
:add_parameter('player', false, 'player-online')
:callback(
function (player, target)
if this.module_disabled then
return false
end
local target_player = game.get_player(cmd.parameter)
if target_player == player and not player.admin then
return player.print('Cannot open self.', Color.warning)
end
local valid, opened = player_opened(player)
if valid then
if target_player == opened then
return player.print('You are already viewing this players inventory.', Color.warning)
if target and target.valid then
local valid, opened = player_opened(player)
if valid then
if target.index == opened then
player.print('You are already viewing this players inventory.', Color.warning)
return false
end
end
end
if validate_player(target_player) then
open_inventory(player, target_player)
open_inventory(player, target)
else
player.print('[Inventory] Please type a name of a player who is connected.', Color.warning)
end
else
return
end
end
)
)
function Public.show_inventory(player, target_player)
if not player or not player.valid then
@@ -501,7 +489,7 @@ end
Gui.on_custom_close(
main_frame_name,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not this.data[player.index] then
return

View File

@@ -1,95 +1,80 @@
local Public = require 'modules.wave_defense.table'
local Commands = require 'utils.commands'
local module_name = '[WD]'
commands.add_command(
'wd_debug_module',
'',
function(cmd)
local p
local player = game.player
if not player or not player.valid then
p = print
else
p = player.print
if not player.admin then
return
Commands.new('wd_debug_module', 'Usable only for admins - controls wave defense module!')
:require_admin()
:require_validation()
:add_parameter('skip/toggle_es/toggle_es_boss/spawn/next/next_50/next_1500/log_all/debug_health', false, 'string')
:callback(
function (player, action)
if action == 'skip' then
Public.get('enable_grace_time').enabled = false
player.print(module_name .. ' grace skipped!')
return true
end
end
local param = tostring(cmd.parameter)
if param == 'nil' then
p('[ERROR] Arguments are:\nskip\toggle_es\toggle_es_boss\nspawn\nnext\nnext_50\nnext_1500\nlog_all\ndebug_health')
return
end
if action == 'toggle_es' then
Public.set_module_status()
player.print(module_name .. ' ES has been toggled!')
return true
end
if param == 'skip' then
Public.get('enable_grace_time').enabled = false
p(module_name .. ' grace skipped!')
return
end
if action == 'toggle_es_boss' then
Public.set_track_bosses_only()
player.print(module_name .. ' ES bosses has been toggled!')
return true
end
if param == 'toggle_es' then
Public.set_module_status()
p(module_name .. ' ES has been toggled!')
return
end
if action == 'spawn' then
Public.spawn_unit_group({ true }, true)
player.print(module_name .. ' wave spawned!')
return true
end
if param == 'toggle_es_boss' then
Public.set_track_bosses_only()
p(module_name .. ' ES bosses has been toggled!')
return
end
if param == 'spawn' then
Public.spawn_unit_group({true}, true)
p(module_name .. ' wave spawned!')
return
end
if param == 'next' then
Public.set_next_wave()
Public.spawn_unit_group({true}, true)
p(module_name .. ' wave spawned!')
return
end
if param == 'next_50' then
for _ = 1, 50 do
if action == 'next' then
Public.set_next_wave()
Public.spawn_unit_group({ true }, true)
player.print(module_name .. ' wave spawned!')
return true
end
Public.spawn_unit_group({true}, true)
p(module_name .. ' wave spawned!')
return
end
if param == 'next_1500' then
for _ = 1, 1500 do
Public.set_next_wave()
if action == 'next_50' then
for _ = 1, 50 do
Public.set_next_wave()
end
Public.spawn_unit_group({ true }, true)
player.print(module_name .. ' wave spawned!')
return true
end
if action == 'next_1500' then
for _ = 1, 1500 do
Public.set_next_wave()
end
Public.spawn_unit_group({ true }, true)
player.print(module_name .. ' wave spawned!')
return true
end
if action == 'log_all' then
Public.toggle_debug()
player.print(module_name .. ' debug toggled!')
return true
end
if action == 'debug_health' then
Public.toggle_debug_health()
local this = Public.get()
this.next_wave = 1000
this.wave_interval = 200
this.wave_enforced = true
this.debug_only_on_wave_500 = true
player.print(module_name .. ' debug health toggled!')
return true
end
Public.spawn_unit_group({true}, true)
p(module_name .. ' wave spawned!')
return
end
if param == 'log_all' then
Public.toggle_debug()
p(module_name .. ' debug toggled!')
return
end
if param == 'debug_health' then
local this = Public.get()
Public.toggle_debug_health()
this.next_wave = 1000
this.wave_interval = 200
this.wave_enforced = true
this.debug_only_on_wave_500 = true
p(module_name .. ' debug health toggled!')
end
end
)
)
return Public

View File

@@ -6,6 +6,7 @@ local Task = require 'utils.task'
local Server = require 'utils.server'
local SpamProtection = require 'utils.spam_protection'
local Alert = require 'utils.alert'
local Commands = require 'utils.commands'
local main_frame_name = Gui.uid_name()
local save_button_name = Gui.uid_name()
@@ -29,33 +30,33 @@ function Public.main_gui(player, text)
end
main_frame =
player.gui.screen.add(
{
type = 'frame',
name = main_frame_name,
caption = 'A stretch is needed.',
direction = 'vertical'
}
)
{
type = 'frame',
name = main_frame_name,
caption = 'A stretch is needed.',
direction = 'vertical'
}
)
main_frame.auto_center = true
local main_frame_style = main_frame.style
main_frame_style.width = 500
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame = main_frame.add { type = 'frame', style = 'inside_shallow_frame' }
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table = inside_frame.add { type = 'table', column_count = 1 }
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 0
inside_table.add({type = 'line'})
inside_table.add({ type = 'line' })
local info_main =
inside_table.add(
{
type = 'label',
caption = '[color=yellow]' .. text .. ',[/color]'
}
)
{
type = 'label',
caption = '[color=yellow]' .. text .. ',[/color]'
}
)
local info_main_style = info_main.style
info_main_style.font = 'default-large-bold'
info_main_style.padding = 0
@@ -63,17 +64,17 @@ function Public.main_gui(player, text)
info_main_style.horizontal_align = 'left'
info_main_style.vertical_align = 'bottom'
info_main_style.single_line = false
info_main_style.font_color = {0.55, 0.55, 0.99}
info_main_style.font_color = { 0.55, 0.55, 0.99 }
inside_table.add({type = 'line'})
inside_table.add({ type = 'line' })
local info_sub =
inside_table.add(
{
type = 'label',
caption = 'We have played for ' .. Server.format_time(game.ticks_played) .. ' now.\nIf you want to take a quick break,\nplease vote to pause the waves for 5 minutes.'
}
)
{
type = 'label',
caption = 'We have played for ' .. Server.format_time(game.ticks_played) .. ' now.\nIf you want to take a quick break,\nplease vote to pause the waves for 5 minutes.'
}
)
local info_sub_style = info_sub.style
info_sub_style.font = 'default-game'
info_sub_style.padding = 0
@@ -82,21 +83,21 @@ function Public.main_gui(player, text)
info_sub_style.vertical_align = 'bottom'
info_sub_style.single_line = false
inside_table.add({type = 'line'})
inside_table.add({ type = 'line' })
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' })
local left_flow = bottom_flow.add({type = 'flow'})
local left_flow = bottom_flow.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'I cannot rest!'})
local close_button = left_flow.add({ type = 'button', name = discard_button_name, caption = 'I cannot rest!' })
close_button.style = 'back_button'
local right_flow = bottom_flow.add({type = 'flow'})
local right_flow = bottom_flow.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
local save_button = right_flow.add({type = 'button', name = save_button_name, caption = 'I need to stretch'})
local save_button = right_flow.add({ type = 'button', name = save_button_name, caption = 'I need to stretch' })
save_button.style = 'confirm_button'
player.opened = main_frame
@@ -128,7 +129,7 @@ local function pause_waves_state(state)
if state then
if custom_callback then
custom_callback({start = false})
custom_callback({ start = false })
end
local pause_wave_in_ticks = Public.get('pause_wave_in_ticks')
@@ -136,16 +137,16 @@ local function pause_waves_state(state)
Public.set('last_pause', game.tick)
Public.set('paused_waves_for', game.tick + pause_wave_in_ticks)
local pause_for = floor(pause_wave_in_ticks / 60 / 60)
local message = ({'wave_defense.pause_waves', pause_for})
local message = ({ 'wave_defense.pause_waves', pause_for })
Alert.alert_all_players(30, message, nil, 'achievement/tech-maniac', 0.75)
local next_wave = Public.get('next_wave')
Public.set('next_wave', next_wave + 18000)
else
if custom_callback then
custom_callback({start = true})
custom_callback({ start = true })
end
local message = ({'wave_defense.start_waves'})
local message = ({ 'wave_defense.start_waves' })
Alert.alert_all_players(30, message, nil, 'achievement/tech-maniac', 0.75)
Public.normalize_spawn_position()
Public.set('paused', false)
@@ -172,7 +173,7 @@ function Public.toggle_pause_wave_without_votes()
return
end
Public.set('pause_waves', {index = 0})
Public.set('pause_waves', { index = 0 })
local pause_wave_in_ticks = Public.get('pause_wave_in_ticks')
pause_waves_state(true)
Task.set_timeout_in_ticks(pause_wave_in_ticks, pause_waves_state_token, false) -- 5 minutes
@@ -180,7 +181,7 @@ end
Gui.on_click(
save_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'WD Save Button')
if is_spamming then
return
@@ -200,13 +201,13 @@ Gui.on_click(
local divided = total_players / 2
if pause_waves.index >= divided then
Public.set('pause_waves', {index = 0})
Public.set('pause_waves', { index = 0 })
local players = game.connected_players
for i = 1, #players do
local p = players[i]
local screen = p.gui.screen
local frame = screen[main_frame_name]
p.surface.play_sound({path = 'utility/new_objective', position = p.position, volume_modifier = 0.75})
p.surface.play_sound({ path = 'utility/new_objective', position = p.position, volume_modifier = 0.75 })
if frame and frame.valid then
Gui.remove_data_recursively(frame)
@@ -230,7 +231,7 @@ Gui.on_click(
Gui.on_click(
discard_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'WD Discard Button')
if is_spamming then
return
@@ -250,7 +251,7 @@ Gui.on_click(
Event.on_nth_tick(
216000, -- 1 hour
function()
function ()
if game.ticks_played < 100 then
return
end
@@ -280,51 +281,37 @@ Event.on_nth_tick(
end
)
commands.add_command(
'wave_defense_pause_waves',
'Usable only for admins - pauses the wave defense waves!',
function()
local player = game.player
if player and player.valid then
if not player.admin then
return
end
Commands.new('wave_defense_pause_waves', 'Usable only for admins - pauses the wave defense waves!')
:require_admin()
:require_validation()
:callback(
function (player)
local paused = Public.get('paused')
if paused then
return
return false
end
print('[Wave Defense] ' .. player.name .. ' paused wave defense.')
Public.toggle_pause_wave()
end
end
)
commands.add_command(
'wave_defense_force_pause_waves',
'Usable only for admins - pauses the wave defense waves!',
function()
local player = game.player
if player and player.valid then
if not player.admin then
return
end
)
Commands.new('wave_defense_force_pause_waves', 'Usable only for admins - pauses the wave defense waves!')
:require_admin()
:require_validation()
:callback(
function (player)
local paused = Public.get('paused')
if paused then
return
return false
end
print('[Wave Defense] ' .. player.name .. ' paused wave defense.')
Public.toggle_pause_wave_without_votes()
end
end
)
)
--- Toggles if we should show a gui or just pause the waves without votes.
---@param state boolean

View File

@@ -1,9 +1,10 @@
local Event = require 'utils.event'
local Global = require 'utils.global'
local Gui = require 'utils.gui'
local Token = require 'utils.token'
local Task = require 'utils.task_token'
local Color = require 'utils.color_presets'
local SpamProtection = require 'utils.spam_protection'
local Commands = require 'utils.commands'
local pairs = pairs
local next = next
@@ -11,14 +12,14 @@ local next = next
local Public = {}
local active_alerts = {}
local id_counter = {0}
local id_counter = { 0 }
local alert_zoom_to_pos = Gui.uid_name()
local on_tick
Global.register(
{active_alerts = active_alerts, id_counter = id_counter},
function(tbl)
{ active_alerts = active_alerts, id_counter = id_counter },
function (tbl)
active_alerts = tbl.active_alerts
id_counter = tbl.id_counter
end
@@ -34,6 +35,41 @@ local close_alert_name = Gui.uid_name()
-- own name you can use Public.close_alert(element)
Public.close_alert_name = close_alert_name
local delay_print_alert_token =
Task.register(
function (event)
local text = event.text
if not text then
return
end
local ttl = event.ttl
if not ttl then
ttl = 60
end
local sprite = event.sprite
local color = event.color
Public.alert_all_players(ttl, text, color, sprite, 1)
end
)
Public.set_timeout_in_ticks_alert = function (delay, data)
if not data then
return error('Data was not provided', 2)
end
if type(data) ~= 'table' then
return error("Data must be of type 'table'", 2)
end
if not delay then
return error('No delay was provided', 2)
end
Task.set_timeout_in_ticks(delay, delay_print_alert_token, data)
end
---Creates a unique ID for a alert message
local function autoincrement()
local id = id_counter[1] + 1
@@ -77,15 +113,15 @@ end
---@param duration number in seconds
---@param sound string sound to play, nil to not play anything
local function alert_to(player, duration, sound, volume)
local frame_holder = player.gui.left.add({type = 'flow'})
local frame_holder = player.gui.left.add({ type = 'flow' })
local frame = frame_holder.add({type = 'frame', name = alert_frame_name, direction = 'vertical', style = 'captionless_frame'})
local frame = frame_holder.add({ type = 'frame', name = alert_frame_name, direction = 'vertical', style = 'captionless_frame' })
frame.style.width = 300
local container = frame.add({type = 'flow', name = alert_container_name, direction = 'horizontal'})
local container = frame.add({ type = 'flow', name = alert_container_name, direction = 'horizontal' })
container.style.horizontally_stretchable = true
local progressbar = frame.add({type = 'progressbar', name = alert_progress_name})
local progressbar = frame.add({ type = 'progressbar', name = alert_progress_name })
local style = progressbar.style
style.width = 290
style.height = 4
@@ -116,7 +152,7 @@ local function alert_to(player, duration, sound, volume)
if sound then
volume = volume or 0.60
player.play_sound({path = sound, volume_modifier = volume})
player.play_sound({ path = sound, volume_modifier = volume })
end
return container
@@ -173,20 +209,20 @@ local function update_alert(id, frame, tick)
end
on_tick =
Token.register(
function(event)
if not next(active_alerts) then
Event.remove_removable_nth_tick(2, on_tick)
return
end
Task.register(
function (event)
if not next(active_alerts) then
Event.remove_removable_nth_tick(2, on_tick)
return
end
local tick = event.tick
local tick = event.tick
for id, frame in pairs(active_alerts) do
update_alert(id, frame, tick)
for id, frame in pairs(active_alerts) do
update_alert(id, frame, tick)
end
end
end
)
)
---Message a specific player, template is a callable that receives a LuaGuiElement
---to add contents to and a player as second argument.
@@ -239,23 +275,23 @@ function Public.alert_all_players_location(player, message, color, duration)
local length = duration or 15
Public.alert_all_players_template(
length,
function(container)
function (container)
local sprite =
container.add {
type = 'sprite-button',
name = alert_zoom_to_pos,
sprite = 'utility/search_icon',
style = 'slot_button'
}
type = 'sprite-button',
name = alert_zoom_to_pos,
sprite = 'utility/search_icon',
style = 'slot_button'
}
Gui.set_data(sprite, player.position)
local label =
container.add {
type = 'label',
name = Public.close_alert_name,
caption = message
}
type = 'label',
name = Public.close_alert_name,
caption = message
}
local label_style = label.style
label_style.single_line = false
label_style.font_color = color or Color.comfy
@@ -272,13 +308,13 @@ function Public.alert_player(player, duration, message, color, sprite, volume)
Public.alert_player_template(
player,
duration,
function(container)
function (container)
container.add {
type = 'sprite-button',
sprite = sprite or 'achievement/you-are-doing-it-right',
style = 'slot_button'
}
local label = container.add({type = 'label', name = close_alert_name, caption = message})
local label = container.add({ type = 'label', name = close_alert_name, caption = message })
label.style.single_line = false
label.style.font_color = color or Color.comfy
end,
@@ -296,13 +332,13 @@ function Public.alert_player_warning(player, duration, message, color)
Public.alert_player_template(
player,
duration,
function(container)
function (container)
container.add {
type = 'sprite-button',
sprite = 'achievement/golem',
style = 'slot_button'
}
local label = container.add({type = 'label', name = close_alert_name, caption = message})
local label = container.add({ type = 'label', name = close_alert_name, caption = message })
label.style.single_line = false
label.style.font_color = color or Color.comfy
end
@@ -333,94 +369,28 @@ function Public.alert_all_players(duration, message, color, sprite, volume)
end
end
commands.add_command(
'notify_all_players',
'Usable only for admins - sends an alert message to all players!',
function(cmd)
local p
local player = game.player
local param = cmd.parameter
Commands.new('notify_all_players', 'Usable only for admins - sends an alert message to all players!')
:add_parameter('message', false, 'string')
:callback(
function (player, message)
local comfy = '[color=blue]' .. player.name .. ':[/color] \n'
message = comfy .. message
Public.alert_all_players_location(player, message)
end
)
if player then
if player ~= nil then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
if not param then
return p('Valid arguments are: message_to_print')
end
Commands.new('notify_player', 'Usable only for admins - sends an alert message to a player!')
:add_parameter('player', false, 'player-online')
:add_parameter('message', false, 'string')
:callback(
function (player, target_player, message)
if target_player then
local comfy = '[color=blue]' .. player.name .. ':[/color] \n'
local message = comfy .. param
Public.alert_all_players_location(player, message)
end
else
p = log
if not param then
return p('Valid arguments are: message_to_print')
end
local comfy = '[color=blue]Server:[/color] \n'
local message = comfy .. param
p(param)
Public.alert_all_players(15, message)
end
end
)
commands.add_command(
'notify_player',
'Usable only for admins - sends an alert message to a player!',
function(cmd)
local p
local player = game.player
local param = cmd.parameter
if player then
if player ~= nil then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
local t_player
local t_message
local target_player
local str = ''
if not param then
return p('[ERROR] Valid arguments are:\nplayer = player,\nmessage = message', Color.fail)
end
local t = {}
for i in string.gmatch(param, '%S+') do
table.insert(t, i)
end
t_player = t[1]
for i = 2, #t do
str = str .. t[i] .. ' '
t_message = str
end
if game.players[t_player] then
target_player = game.players[t_player]
else
return p('[ERROR] No player was provided', Color.fail)
end
if t_message then
local comfy = '[color=blue]' .. player.name .. ':[/color] \n'
local message = comfy .. t_message
Public.alert_player_warning(target_player, 15, message)
else
p('No message was provided', Color.fail)
end
message = comfy .. message
Public.alert_player_warning(target_player, 15, message)
end
end
end
)
)
return Public

View File

@@ -1,3 +1,552 @@
require 'utils.commands.trust_system'
require 'utils.commands.misc'
require 'utils.commands.where'
---@diagnostic disable: deprecated
--luacheck: ignore 561
local Global = require 'utils.global'
local Core = require 'utils.core'
local Session = require 'utils.datastore.session_data'
local Supporters = require 'utils.datastore.supporters'
local Task = require 'utils.task_token'
local Server = require 'utils.server'
---@class CommandData
---@field name string
---@field help string
---@field aliases table
---@field parameters table
---@field parameters_count number
---@field parameters_required number
---@field check_server boolean
---@field check_backend boolean
---@field check_admin boolean
---@field check_supporter boolean
---@field check_trusted boolean
---@field check_playtime number
---@field callback function
---@field validate_self boolean
---@field validated_command boolean
---@field validate_activated boolean
---@field command_activated boolean
local this = {
commands = {}
}
local trace = debug.traceback
local output = {
backend_is_required = 'No backend is currently available. Please try again later.',
server_is_required = 'This command requires to be run from the server.',
admin_is_required = 'This command requires admin permissions to run.',
supporter_is_required = 'This command requires supporter permissions to run.',
trusted_is_required = 'This command requires trusted permissions to run.',
playtime_is_required = 'This command requires a minimum playtime to run.',
param_is_required = 'This command requires a parameter to run.',
command_failed = 'Command failed to run.',
command_success = 'Command ran successfully.',
command_needs_validation =
'This command requires validation to run. Please re-run the command if you wish to proceed.',
command_needs_custom_validation =
'This command requires validation to run. %s - please re-run the command if you wish to proceed.',
command_is_active = 'This command is already active.',
command_is_inactive = 'This command is already inactive.'
}
local check_boolean = {
['true'] = true,
['false'] = true
}
---@class MetaCommand
local Public = {}
Public.metatable = { __index = Public }
Global.register(
this,
function (tbl)
this = tbl
for _, command in pairs(this.commands) do
setmetatable(command, Public.metatable)
end
end
)
local function conv(v)
if tonumber(v) then
return tonumber(v)
end
return v
end
--- Handles errors.
---@param message string
---@param notify_sound string
local function handle_error(message, notify_sound)
message = message or ''
Core.output_message('Command failed: ' .. message, 'warning')
if notify_sound then
notify_sound = notify_sound or 'utility/wire_pickup'
if game.player then
game.player.play_sound { path = notify_sound }
end
end
end
--- Handles internal errors.
---@param has_run boolean
---@param name string
---@param message string
---@return boolean
local function internal_error(has_run, name, message)
if not has_run then
handle_error('Action has been logged!', 'utility/cannot_build')
if type(message) == 'string' then
Server.output_data('[ERROR] Command failed to run: ' .. name .. ' - ' .. message)
else
Server.output_data('[ERROR] Command failed to run: ' .. name)
end
end
return not has_run
end
---@param event EventData.on_console_command
local function execute(event)
local command_data = this.commands[event.name] --[[@as CommandData]]
local player
if event.player_index and event.player_index > 0 then
player = game.get_player(event.player_index)
else
player = {
name = 'Server',
position = { x = 0, y = 0 },
surface = game.get_surface('nauvis'),
force = game.forces.player,
print = Server.output_data
}
end
local is_server = event.player_index == nil
local function reject(error_message)
error_message = error_message or ''
command_data.validated_command = false
return handle_error(error_message, 'utility/cannot_build')
end
-- Check if player and return
local check_server = command_data.check_server or false
if (check_server and not is_server) and player and player.valid then
reject(output.server_is_required)
return
end
-- Check if player and return
local check_backend = command_data.check_backend or false
if (check_backend and not is_server) and event.player_index then
if not Server.get_current_time() then
reject(output.backend_is_required)
return
end
end
-- Check if the player is an admin and if the command requires it
local check_admin = command_data.check_admin or false
if (check_admin and not is_server) and player and not player.admin then
reject(output.admin_is_required)
return
end
-- Check if the player is trusted and if the command requires it
local check_trusted = command_data.check_trusted or false
if (check_trusted and not is_server) and Core.validate_player(player) then
local is_trusted = Session.get_trusted_player(player)
if not is_trusted then
reject(output.trusted_is_required)
return
end
end
-- Check if the player is a supporter and if the command requires it
local check_supporter = command_data.check_supporter or false
if (check_supporter and not is_server) and Core.validate_player(player) then
local is_supporter = Supporters.is_supporter(player.name)
if not is_supporter then
reject(output.supporter_is_required)
return
end
end
-- Check if the player has the required playtime and if the command requires it
local check_playtime = command_data.check_playtime or false
if (check_playtime and not is_server) and Core.validate_player(player) then
local playtime = Session.get_session_player(player)
if not playtime then
reject(output.trusted_is_required)
return
end
if playtime < check_playtime then
reject(output.playtime_is_required)
return
end
end
-- Check for parameters
if command_data.parameters_required > 0 and not event.parameter then
reject(output.param_is_required)
return
end
-- Check if the command requires the player to validate the command
local validate_self = command_data.validate_self or false
if validate_self and not command_data.validated_command then
command_data.validated_command = true
if command_data.custom_message then
handle_error(string.format(output.command_needs_custom_validation, command_data.custom_message),
'utility/cannot_build')
else
handle_error(output.command_needs_validation, 'utility/cannot_build')
end
return
end
-- Extract quoted arguments
local input_text = event.parameter or ''
local quoted_segments = {}
local processed_input =
input_text:gsub(
'"([^"]-)"',
function (segment)
local no_spaces_segment = segment:gsub('%s', '%%s')
quoted_segments[no_spaces_segment] = segment
return ' ' .. no_spaces_segment .. ' '
end
)
-- Extract unquoted arguments
local parameters = {}
local current_index = 0
local parameter_count = 0
for word in processed_input:gmatch('%S+') do
parameter_count = parameter_count + 1
local quoted_word = quoted_segments[word]
local formatted_word = quoted_word and ('"' .. quoted_word .. '"') or word
if parameter_count > command_data.parameters_count then
parameters[current_index] = parameters[current_index] .. ' ' .. formatted_word
else
current_index = current_index + 1
parameters[current_index] = formatted_word
end
end
-- Check the param count
local parameters_count = #parameters
if parameters_count < command_data.parameters_required then
reject(output.param_is_required)
return
end
-- Parse the arguments
local index = 1
local handled_parameters = {}
for _, param_data in pairs(command_data.parameters) do
if param_data.as_type then
local param = conv(parameters[index])
if param_data.as_type == 'player' and param ~= nil then
local player_name = param
if type(player_name) ~= 'string' then
return reject('Inputted value is not of type string. Valid values are: "string"')
end
local player_data = game.get_player(player_name) --[[@type LuaPlayer]]
if not player_data then
return reject('Player was not found.')
end
handled_parameters[index] = player_data
index = index + 1
end
if param_data.as_type == 'player-online' and param ~= nil then
local player_name = param
if type(player_name) ~= 'string' then
return reject('Inputted value is not of type string. Valid values are: "string"')
end
local player_data = game.get_player(player_name) --[[@type LuaPlayer]]
if not player_data or not player_data.valid then
return reject('Player was not found.')
end
if not player_data.connected then
return reject('Player is not online.')
end
handled_parameters[index] = player_data
index = index + 1
end
if param_data.as_type == 'player-admin' and param ~= nil then
local player_name = param
if type(player_name) ~= 'string' then
return reject('Inputted value is not of type string. Valid values are: "string"')
end
local player_data = game.get_player(player_name) --[[@type LuaPlayer]]
if not player_data or not player_data.valid then
return reject('Player was not found.')
end
if not player_data.admin then
return reject('Player is not an admin.')
end
handled_parameters[index] = player_data
index = index + 1
end
if param_data.as_type == 'server' and param ~= nil then
local player_name = param
if type(player_name) ~= 'string' then
return reject('Inputted value is not of type string. Valid values are: "string"')
end
local player_data = game.get_player(player_name) --[[@type LuaPlayer]]
if player_data and player_data.valid then
return reject('Not running from server.')
end
handled_parameters[index] = player_data
index = index + 1
end
if (param_data.as_type == 'number' or param_data.as_type == 'integer') and param ~= nil then
local num = tonumber(param)
if not num then
return reject('Inputted value is not of type number. Valid values are: 1, 2, 3, etc.')
end
handled_parameters[index] = num
index = index + 1
end
if param_data.as_type == 'string' and param ~= nil then
if type(param) ~= 'string' then
return reject('Inputted value is not of type string. Valid values are: "string"')
end
handled_parameters[index] = param
index = index + 1
end
if param_data.as_type == 'boolean' and param ~= nil then
if not check_boolean[param] then
return reject('Inputted value is not of type boolean. Valid values are: true, false.')
end
if command_data.command_activated and param == 'true' then
return handle_error(output.command_is_active, 'utility/cannot_build')
end
if not command_data.command_activated and param == 'false' then
return handle_error(output.command_is_inactive, 'utility/cannot_build')
end
handled_parameters[index] = param
index = index + 1
end
end
end
-- Run the command callback if everything is validated
handled_parameters[#handled_parameters + 1] = input_text
local callback = Task.get(command_data.callback)
local success, err = pcall(callback, player, unpack(handled_parameters))
if internal_error(success, command_data.name, err) then
return reject(output.command_failed)
end
-- Check if the command can only be run once
local validate_activated = command_data.validate_activated or false
if validate_activated then
if not command_data.command_activated then
command_data.command_activated = true
else
command_data.command_activated = false
end
end
command_data.validated_command = false
if err ~= nil then
if type(err) == 'boolean' then
if err == false then
Core.output_message(output.command_failed, 'warning')
else
Core.output_message(output.command_success, 'success')
end
else
Core.output_message(err)
end
else
Core.output_message(output.command_success, 'success')
end
end
--- Creates a new command.
---@param name string
---@param help string
---@return MetaCommand
function Public.new(name, help)
if this.commands[name] then
error('Command already exists: ' .. name, 2)
end
local command =
setmetatable(
{
name = name,
help = help,
aliases = {},
parameters = {},
parameters_count = 0,
parameters_required = 0,
check_admin = false,
check_server = false,
check_backend = false,
check_supporter = false,
check_trusted = false,
check_playtime = false,
validate_self = false,
validated_command = false
},
Public.metatable
)
this.commands[name] = command
return command
end
--- Requires the player to validate the command before running it.
---@param custom_message? string
---@return MetaCommand
function Public:require_validation(custom_message)
self.validate_self = true
if custom_message then
self.custom_message = custom_message
end
return self
end
--- Requires the player to validate the command before running it.
---@return MetaCommand
function Public:is_activated()
self.validate_activated = true
return self
end
--- Requires the player to be an admin to run the command.
---@return MetaCommand
function Public:require_admin()
self.check_admin = true
return self
end
--- Requires that the command is not run from a player.
---@return MetaCommand
function Public:require_server()
self.check_server = true
return self
end
--- Requires that the server is connected to a backend
---@return MetaCommand
function Public:require_backend()
self.check_backend = true
return self
end
--- Requires the player to be a supporter to run the command.
---@return MetaCommand
function Public:require_supporter()
self.check_supporter = true
return self
end
--- Requires the player to be trusted to run the command.
---@return MetaCommand
function Public:require_trusted()
self.check_trusted = true
return self
end
--- Requires the player to have a minimum playtime to run the command.
---@param playtime integer|number
---@return MetaCommand
function Public:require_playtime(playtime)
self.check_playtime = playtime or nil
return self
end
--- Adds a parameter to the command.
---@param name string
---@param optional boolean
---@param as_type? type|string
---@return MetaCommand
function Public:add_parameter(name, optional, as_type)
if self.parameters[name] then
error('Parameter: ' .. name .. ' already exists for command: ' .. self.name, 2)
end
self.parameters[name] = { optional = optional, as_type = as_type }
self.parameters_count = self.parameters_count + 1
if not optional then
self.parameters_required = self.parameters_required + 1
end
return self
end
--- Sets the command as default if marking paramaters as optional.
---@param defaults any
---@return MetaCommand
function Public:set_default(defaults)
for name, value in pairs(defaults) do
if self.parameters[name] then
self.parameters[name].default = value
end
end
return self
end
--- Registers the command to the game. Will return the player/server and the args as separate arguments.
---@param func function
function Public:callback(func)
-- Generates a description to be used
local description = ''
for param_name, param_details in pairs(self.parameters) do
if param_details.optional then
description = string.format('%s [%s]', description, param_name)
else
description = string.format('%s <%s>', description, param_name)
end
end
self.description = description
-- If command fails to run, notify the player/server
local function command_error(err)
internal_error(false, self.name, trace(err))
end
-- Registers the command as a token
local id = Task.register(func)
self.callback = id
-- Callback
local function command_callback(event)
event.name = self.name
xpcall(execute, command_error, event)
end
-- Lastly, adds the command to the game
local help = description .. ' - ' .. self.help
commands.add_command(self.name, help, command_callback)
-- Adds any aliases if any
for _, alias in pairs(self.aliases) do
if not commands.commands[alias] and not commands.game_commands[alias] then
commands.add_command(alias, help, command_callback)
end
end
end
return Public

View File

@@ -1,3 +1,4 @@
---@diagnostic disable: deprecated
local Session = require 'utils.datastore.session_data'
local Modifiers = require 'utils.player_modifiers'
local Server = require 'utils.server'
@@ -8,6 +9,7 @@ local BottomFrame = require 'utils.gui.bottom_frame'
local Gui = require 'utils.gui'
local SpamProtection = require 'utils.spam_protection'
local Discord = require 'utils.discord_handler'
local Commands = require 'utils.commands'
local this = {
players = {},
@@ -16,7 +18,7 @@ local this = {
Global.register(
this,
function(t)
function (t)
this = t
end
)
@@ -25,352 +27,254 @@ local Public = {}
local clear_corpse_button_name = Gui.uid_name()
commands.add_command(
'spaghetti',
'Does spaghett.',
function(cmd)
local player = game.player
local param = tostring(cmd.parameter)
local force = game.forces['player']
Commands.new('playtime', 'Fetches a player total playtime or nil.')
:require_backend()
:add_parameter('target', false, 'string')
:callback(
function (player, target)
Session.get_and_print_to_player(player, target)
end
)
if not (player and player.valid) then
return
end
local p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
if param == nil then
player.print('[ERROR] Arguments are true/false', Color.yellow)
return
Commands.new('refresh', 'Reloads game script')
:require_admin()
:callback(
function ()
game.print('Reloading game script...', Color.warning)
Server.to_discord_bold('Reloading game script...')
game.reload_script()
end
if param == 'true' then
if not this.spaghetti_are_you_sure then
this.spaghetti_are_you_sure = true
player.print('Spaghetti is not enabled, run this command again to enable spaghett', Color.yellow)
return
end
if this.spaghetti_enabled then
player.print('Spaghetti is already enabled.', Color.yellow)
return
end
game.print('The world has been spaghettified!', Color.success)
force.technologies['logistic-system'].enabled = false
force.technologies['construction-robotics'].enabled = false
force.technologies['logistic-robotics'].enabled = false
force.technologies['robotics'].enabled = false
force.technologies['personal-roboport-equipment'].enabled = false
force.technologies['personal-roboport-mk2-equipment'].enabled = false
force.technologies['character-logistic-trash-slots-1'].enabled = false
force.technologies['character-logistic-trash-slots-2'].enabled = false
force.technologies['auto-character-logistic-trash-slots'].enabled = false
force.technologies['worker-robots-storage-1'].enabled = false
force.technologies['worker-robots-storage-2'].enabled = false
force.technologies['worker-robots-storage-3'].enabled = false
force.technologies['character-logistic-slots-1'].enabled = false
force.technologies['character-logistic-slots-2'].enabled = false
force.technologies['character-logistic-slots-3'].enabled = false
force.technologies['character-logistic-slots-4'].enabled = false
force.technologies['character-logistic-slots-5'].enabled = false
force.technologies['character-logistic-slots-6'].enabled = false
force.technologies['worker-robots-speed-1'].enabled = false
force.technologies['worker-robots-speed-2'].enabled = false
force.technologies['worker-robots-speed-3'].enabled = false
force.technologies['worker-robots-speed-4'].enabled = false
force.technologies['worker-robots-speed-5'].enabled = false
force.technologies['worker-robots-speed-6'].enabled = false
this.spaghetti_enabled = true
elseif param == 'false' then
if this.spaghetti_enabled == false or this.spaghetti_enabled == nil then
player.print('Spaghetti is already disabled.', Color.yellow)
return
end
game.print('The world is no longer spaghett!', Color.yellow)
force.technologies['logistic-system'].enabled = true
force.technologies['construction-robotics'].enabled = true
force.technologies['logistic-robotics'].enabled = true
force.technologies['robotics'].enabled = true
force.technologies['personal-roboport-equipment'].enabled = true
force.technologies['personal-roboport-mk2-equipment'].enabled = true
force.technologies['character-logistic-trash-slots-1'].enabled = true
force.technologies['character-logistic-trash-slots-2'].enabled = true
force.technologies['auto-character-logistic-trash-slots'].enabled = true
force.technologies['worker-robots-storage-1'].enabled = true
force.technologies['worker-robots-storage-2'].enabled = true
force.technologies['worker-robots-storage-3'].enabled = true
force.technologies['character-logistic-slots-1'].enabled = true
force.technologies['character-logistic-slots-2'].enabled = true
force.technologies['character-logistic-slots-3'].enabled = true
force.technologies['character-logistic-slots-4'].enabled = true
force.technologies['character-logistic-slots-5'].enabled = true
force.technologies['character-logistic-slots-6'].enabled = true
force.technologies['worker-robots-speed-1'].enabled = true
force.technologies['worker-robots-speed-2'].enabled = true
force.technologies['worker-robots-speed-3'].enabled = true
force.technologies['worker-robots-speed-4'].enabled = true
force.technologies['worker-robots-speed-5'].enabled = true
force.technologies['worker-robots-speed-6'].enabled = true
this.spaghetti_enabled = false
end
end
)
)
commands.add_command(
'generate_map',
'Pregenerates map.',
function(cmd)
local player = game.player
local param = tonumber(cmd.parameter)
if not (player and player.valid) then
return
end
local p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
if param == nil then
player.print('[ERROR] Must specify radius!', Color.fail)
return
end
if param > 50 then
player.print('[ERROR] Value is too big.', Color.fail)
return
end
if not this.generate_map then
this.generate_map = true
player.print('[WARNING] This command will make the server LAG, run this command again if you really want to do this!', Color.yellow)
return
end
local radius = param
local surface = game.players[1].surface
if surface.is_chunk_generated({radius, radius}) then
game.print('Map generation done!', Color.success)
this.generate_map = nil
return
end
surface.request_to_generate_chunks({0, 0}, radius)
surface.force_generate_chunk_requests()
for _, pl in pairs(game.connected_players) do
pl.play_sound {path = 'utility/new_objective', volume_modifier = 1}
end
game.print('Map generation done!', Color.success)
this.generate_map = nil
end
)
commands.add_command(
'repair',
'Revives all ghost entities.',
function(cmd)
local player = game.player
local param = tonumber(cmd.parameter)
if not (player and player.valid) then
return
end
local p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
if param == nil then
player.print('[ERROR] Must specify radius!', Color.fail)
return
end
if param > 50 then
player.print('[ERROR] Value is too big.', Color.fail)
return
end
if not this.revive_warning then
this.revive_warning = true
player.print('[WARNING] This command will revive all the ghost entities in the given radius, run this command again if you really want to do this!', Color.yellow)
return
end
local radius = {{x = (player.position.x + -param), y = (player.position.y + -param)}, {x = (player.position.x + param), y = (player.position.y + param)}}
local c = 0
for _, v in pairs(player.surface.find_entities_filtered {type = 'entity-ghost', area = radius}) do
if v and v.valid then
c = c + 1
v.silent_revive()
Commands.new('spaghetti', 'Toggle between disabling bots.')
:require_admin()
:require_validation()
:is_activated()
:add_parameter('true/false', true, 'boolean')
:callback(
function (player, args)
local force = player.force
if args == 'true' then
game.print('The world has been spaghettified!', Color.success)
force.technologies['logistic-system'].enabled = false
force.technologies['construction-robotics'].enabled = false
force.technologies['logistic-robotics'].enabled = false
force.technologies['robotics'].enabled = false
force.technologies['personal-roboport-equipment'].enabled = false
force.technologies['personal-roboport-mk2-equipment'].enabled = false
force.technologies['worker-robots-storage-1'].enabled = false
force.technologies['worker-robots-storage-2'].enabled = false
force.technologies['worker-robots-storage-3'].enabled = false
force.technologies['worker-robots-speed-1'].enabled = false
force.technologies['worker-robots-speed-2'].enabled = false
force.technologies['worker-robots-speed-3'].enabled = false
force.technologies['worker-robots-speed-4'].enabled = false
force.technologies['worker-robots-speed-5'].enabled = false
force.technologies['worker-robots-speed-6'].enabled = false
this.spaghetti_enabled = true
elseif args == 'false' then
game.print('The world is no longer spaghett!', Color.yellow)
force.technologies['logistic-system'].enabled = true
force.technologies['construction-robotics'].enabled = true
force.technologies['logistic-robotics'].enabled = true
force.technologies['robotics'].enabled = true
force.technologies['personal-roboport-equipment'].enabled = true
force.technologies['personal-roboport-mk2-equipment'].enabled = true
force.technologies['worker-robots-storage-1'].enabled = true
force.technologies['worker-robots-storage-2'].enabled = true
force.technologies['worker-robots-storage-3'].enabled = true
force.technologies['worker-robots-speed-1'].enabled = true
force.technologies['worker-robots-speed-2'].enabled = true
force.technologies['worker-robots-speed-3'].enabled = true
force.technologies['worker-robots-speed-4'].enabled = true
force.technologies['worker-robots-speed-5'].enabled = true
force.technologies['worker-robots-speed-6'].enabled = true
this.spaghetti_enabled = false
end
end
)
if c == 0 then
player.print('No entities to repair were found!', Color.warning)
this.revive_warning = nil
return
Commands.new('generate_map', 'Pregenerates map.')
:require_admin()
:require_validation()
:add_parameter('radius', false, 'number')
:callback(
function (player, args)
local radius = args
local surface = player.surface
if surface.is_chunk_generated({ radius, radius }) then
player.print('Map generation done')
return true
end
surface.request_to_generate_chunks({ 0, 0 }, radius)
surface.force_generate_chunk_requests()
for _, pl in pairs(game.connected_players) do
pl.play_sound { path = 'utility/new_objective', volume_modifier = 1 }
end
player.print('Map generation done')
end
)
Discord.send_notification_raw(nil, player.name .. ' repaired ' .. c .. ' entities!')
Commands.new('repair', 'Revives all ghost entities.')
:require_admin()
:require_validation()
:add_parameter('1-50', true, 'number')
:callback(
function (player, args)
if args < 1 then
player.print('[ERROR] Value is too low.')
return false
end
player.play_sound {path = 'utility/new_objective', volume_modifier = 1}
player.print('Repaired ' .. c .. ' entities!', Color.success)
this.revive_warning = nil
end
)
if args > 50 then
player.print('[ERROR] Value is too big.')
return false
end
commands.add_command(
'dump_layout',
'Dump the current map-layout.',
function()
local player = game.player
local radius = { { x = (player.position.x + -args), y = (player.position.y + -args) }, { x = (player.position.x + args), y = (player.position.y + args) } }
if not (player and player.valid) then
return
local c = 0
for _, v in pairs(player.surface.find_entities_filtered { type = 'entity-ghost', area = radius }) do
if v and v.valid then
c = c + 1
v.silent_revive()
end
end
if c == 0 then
player.print('No entities to repair were found!')
return false
end
Discord.send_notification_raw(nil, player.name .. ' repaired ' .. c .. ' entities!')
return 'Repaired ' .. c .. ' entities!'
end
)
local p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.warning)
return
end
if not this.dump_layout then
this.dump_layout = true
player.print('[WARNING] This command will make the server LAG, run this command again if you really want to do this!', Color.yellow)
return
end
local surface = game.players[1].surface
game.write_file('layout.lua', '', false)
Commands.new('dump_layout', 'Dump the current map-layout.')
:require_admin()
:require_validation('This will lag the server if ran')
:callback(
function (player, _)
local surface = player.surface
game.write_file('layout.lua', '', false)
local area = {
left_top = {x = 0, y = 0},
right_bottom = {x = 32, y = 32}
}
local area = {
left_top = { x = 0, y = 0 },
right_bottom = { x = 32, y = 32 }
}
local entities = surface.find_entities_filtered {area = area}
local tiles = surface.find_tiles_filtered {area = area}
local entities = surface.find_entities_filtered { area = area }
local tiles = surface.find_tiles_filtered { area = area }
for _, e in pairs(entities) do
local str = '{position = {x = ' .. e.position.x
str = str .. ', y = '
str = str .. e.position.y
str = str .. '}, name = "'
str = str .. e.name
str = str .. '", direction = '
str = str .. tostring(e.direction)
str = str .. ', force = "'
str = str .. e.force.name
str = str .. '"},'
if e.name ~= 'character' then
for _, e in pairs(entities) do
local str = '{position = {x = ' .. e.position.x
str = str .. ', y = '
str = str .. e.position.y
str = str .. '}, name = "'
str = str .. e.name
str = str .. '", direction = '
str = str .. tostring(e.direction)
str = str .. ', force = "'
str = str .. e.force.name
str = str .. '"},'
if e.name ~= 'character' then
game.write_file('layout.lua', str .. '\n', true)
end
end
game.write_file('layout.lua', '\n', true)
game.write_file('layout.lua', '\n', true)
game.write_file('layout.lua', 'Tiles: \n', true)
for _, t in pairs(tiles) do
local str = '{position = {x = ' .. t.position.x
str = str .. ', y = '
str = str .. t.position.y
str = str .. '}, name = "'
str = str .. t.name
str = str .. '"},'
game.write_file('layout.lua', str .. '\n', true)
end
return 'Dumped layout as file: layout.lua'
end
)
game.write_file('layout.lua', '\n', true)
game.write_file('layout.lua', '\n', true)
game.write_file('layout.lua', 'Tiles: \n', true)
Commands.new('creative', 'Enables creative_mode.')
:require_admin()
:add_parameter('true/false', false, 'boolean')
:require_validation()
:is_activated()
:callback(
function (player, args)
local force = player.force
if args == 'true' then
game.print('[CREATIVE] ' .. player.name .. ' has activated creative-mode!', Color.warning)
Server.to_discord_bold(table.concat { '[Creative] ' .. player.name .. ' has activated creative-mode!' })
for _, t in pairs(tiles) do
local str = '{position = {x = ' .. t.position.x
str = str .. ', y = '
str = str .. t.position.y
str = str .. '}, name = "'
str = str .. t.name
str = str .. '"},'
game.write_file('layout.lua', str .. '\n', true)
player.print('Dumped layout as file: layout.lua', Color.success)
end
this.dump_layout = false
end
)
Modifiers.set('creative_enabled', true)
commands.add_command(
'creative',
'Enables creative_mode.',
function()
local player = game.player
if not (player and player.valid) then
return
end
this.creative_enabled = true
local p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
if not this.creative_are_you_sure then
this.creative_are_you_sure = true
player.print('[WARNING] This command will enable creative/cheat-mode for all connected players, run this command again if you really want to do this!', Color.yellow)
return
end
if this.creative_enabled then
player.print('[ERROR] Creative/cheat-mode is already active!', Color.fail)
return
end
game.print('[CREATIVE] ' .. player.name .. ' has activated creative-mode!', Color.warning)
Server.to_discord_bold(table.concat {'[Creative] ' .. player.name .. ' has activated creative-mode!'})
Modifiers.set('creative_enabled', true)
player.force.enable_all_prototypes()
this.creative_enabled = true
this.creative_are_you_sure = false
for _, _player in pairs(game.connected_players) do
if _player.character ~= nil then
Public.insert_all_items(_player)
end
end
end
)
commands.add_command(
'delete-uncharted-chunks',
'Deletes all chunks that are not charted. Can reduce filesize of the savegame. May be unsafe to use in certain custom maps.',
function()
local player = game.player
if not (player and player.valid) then
return
end
local p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
local forces = {}
for _, force in pairs(game.forces) do
if force.index == 1 or force.index > 3 then
table.insert(forces, force)
end
end
local is_charted
local count = 0
for _, surface in pairs(game.surfaces) do
for chunk in surface.get_chunks() do
is_charted = false
for _, force in pairs(forces) do
if force.is_chunk_charted(surface, {chunk.x, chunk.y}) then
is_charted = true
break
force.enable_all_prototypes()
for _, _player in pairs(game.connected_players) do
player.cheat_mode = true
if _player.character ~= nil then
Public.insert_all_items(_player)
end
end
if not is_charted then
surface.delete_chunk({chunk.x, chunk.y})
count = count + 1
elseif args == 'false' then
game.print('[CREATIVE] ' .. player.name .. ' has deactivated creative-mode!', Color.warning)
Server.to_discord_bold(table.concat { '[Creative] ' .. player.name .. ' has deactivated creative-mode!' })
Modifiers.set('creative_enabled', false)
this.creative_enabled = false
for _, _player in pairs(game.connected_players) do
Public.remove_all_items(player)
_player.cheat_mode = false
end
end
end
)
local message = player.name .. ' deleted ' .. count .. ' uncharted chunks!'
game.print(message, Color.warning)
Server.to_discord_bold(table.concat {message})
end
)
Commands.new('delete_uncharted_chunks', 'Deletes all chunks that are not charted. Can reduce filesize of the savegame. May be unsafe to use in certain custom maps.')
:require_admin()
:require_validation()
:callback(
function (player, _)
local forces = {}
for _, force in pairs(game.forces) do
if force.index == 1 or force.index > 3 then
table.insert(forces, force)
end
end
local is_charted
local count = 0
for _, surface in pairs(game.surfaces) do
for chunk in surface.get_chunks() do
is_charted = false
for _, force in pairs(forces) do
if force.is_chunk_charted(surface, { chunk.x, chunk.y }) then
is_charted = true
break
end
end
if not is_charted then
surface.delete_chunk({ chunk.x, chunk.y })
count = count + 1
end
end
end
local message = player.name .. ' deleted ' .. count .. ' uncharted chunks!'
game.print(message, Color.warning)
Server.to_discord_bold(table.concat { message })
end
)
local function clear_corpses(cmd)
local player
@@ -410,9 +314,9 @@ local function clear_corpses(cmd)
local i = 0
local radius = {{x = (pos.x + -param), y = (pos.y + -param)}, {x = (pos.x + param), y = (pos.y + param)}}
local radius = { { x = (pos.x + -param), y = (pos.y + -param) }, { x = (pos.x + param), y = (pos.y + param) } }
for _, entity in pairs(player.surface.find_entities_filtered {area = radius, type = 'corpse'}) do
for _, entity in pairs(player.surface.find_entities_filtered { area = radius, type = 'corpse' }) do
if entity.corpse_expires then
entity.destroy()
i = i + 1
@@ -433,12 +337,12 @@ end
commands.add_command(
'clear-corpses',
'Clears all the biter corpses..',
function(cmd)
function (cmd)
clear_corpses(cmd)
end
)
local on_player_joined_game = function(player)
local on_player_joined_game = function (player)
Public.insert_all_items(player)
end
@@ -448,7 +352,7 @@ function Public.insert_all_items(player)
if player.get_inventory(defines.inventory.character_armor) then
player.get_inventory(defines.inventory.character_armor).clear()
end
player.insert {name = 'power-armor-mk2', count = 1}
player.insert { name = 'power-armor-mk2', count = 1 }
Modifiers.update_single_modifier(player, 'character_inventory_slots_bonus', 'creative', #game.item_prototypes)
Modifiers.update_single_modifier(player, 'character_mining_speed_modifier', 'creative', 150)
Modifiers.update_single_modifier(player, 'character_health_bonus', 'creative', 2000)
@@ -461,20 +365,20 @@ function Public.insert_all_items(player)
local p_armor = player.get_inventory(5)[1].grid
if p_armor and p_armor.valid then
p_armor.put({name = 'fusion-reactor-equipment'})
p_armor.put({name = 'fusion-reactor-equipment'})
p_armor.put({name = 'fusion-reactor-equipment'})
p_armor.put({name = 'exoskeleton-equipment'})
p_armor.put({name = 'exoskeleton-equipment'})
p_armor.put({name = 'exoskeleton-equipment'})
p_armor.put({name = 'energy-shield-mk2-equipment'})
p_armor.put({name = 'energy-shield-mk2-equipment'})
p_armor.put({name = 'energy-shield-mk2-equipment'})
p_armor.put({name = 'energy-shield-mk2-equipment'})
p_armor.put({name = 'personal-roboport-mk2-equipment'})
p_armor.put({name = 'night-vision-equipment'})
p_armor.put({name = 'battery-mk2-equipment'})
p_armor.put({name = 'battery-mk2-equipment'})
p_armor.put({ name = 'fusion-reactor-equipment' })
p_armor.put({ name = 'fusion-reactor-equipment' })
p_armor.put({ name = 'fusion-reactor-equipment' })
p_armor.put({ name = 'exoskeleton-equipment' })
p_armor.put({ name = 'exoskeleton-equipment' })
p_armor.put({ name = 'exoskeleton-equipment' })
p_armor.put({ name = 'energy-shield-mk2-equipment' })
p_armor.put({ name = 'energy-shield-mk2-equipment' })
p_armor.put({ name = 'energy-shield-mk2-equipment' })
p_armor.put({ name = 'energy-shield-mk2-equipment' })
p_armor.put({ name = 'personal-roboport-mk2-equipment' })
p_armor.put({ name = 'night-vision-equipment' })
p_armor.put({ name = 'battery-mk2-equipment' })
p_armor.put({ name = 'battery-mk2-equipment' })
end
local item = game.item_prototypes
local i = 0
@@ -482,7 +386,7 @@ function Public.insert_all_items(player)
i = i + 1
if _k and _v.type ~= 'mining-tool' then
player.character_inventory_slots_bonus = Modifiers.get_single_modifier(player, 'character_inventory_slots_bonus', 'creative')
player.insert {name = _k, count = _v.stack_size}
player.insert { name = _k, count = _v.stack_size }
player.print('[CREATIVE] Inserted all base items.', Color.success)
end
end
@@ -490,6 +394,17 @@ function Public.insert_all_items(player)
end
end
function Public.remove_all_items(player)
if player.character ~= nil then
if player.get_inventory(defines.inventory.character_armor) then
player.get_inventory(defines.inventory.character_armor).clear()
end
player.clear_items_inside()
Modifiers.reset_player_modifiers(player)
this.players[player.index] = nil
end
end
local function create_clear_corpse_frame(player, bottom_frame_data)
local button
@@ -498,17 +413,17 @@ local function create_clear_corpse_frame(player, bottom_frame_data)
if Gui.get_mod_gui_top_frame() then
button =
Gui.add_mod_button(
player,
{
type = 'sprite-button',
name = clear_corpse_button_name,
sprite = 'entity/behemoth-biter',
tooltip = {'commands.clear_corpse'},
style = Gui.button_style
}
)
player,
{
type = 'sprite-button',
name = clear_corpse_button_name,
sprite = 'entity/behemoth-biter',
tooltip = { 'commands.clear_corpse' },
style = Gui.button_style
}
)
if button then
button.style.font_color = {165, 165, 165}
button.style.font_color = { 165, 165, 165 }
button.style.font = 'heading-3'
button.style.minimal_height = 36
button.style.maximal_height = 36
@@ -523,11 +438,11 @@ local function create_clear_corpse_frame(player, bottom_frame_data)
type = 'sprite-button',
sprite = 'entity/behemoth-biter',
name = clear_corpse_button_name,
tooltip = {'commands.clear_corpse'},
tooltip = { 'commands.clear_corpse' },
style = Gui.button_style
}
)
button.style.font_color = {r = 0.11, g = 0.8, b = 0.44}
button.style.font_color = { r = 0.11, g = 0.8, b = 0.44 }
button.style.font = 'heading-1'
button.style.minimal_height = 40
button.style.maximal_width = 40
@@ -564,7 +479,7 @@ function Public.set(key, value)
end
Event.on_init(
function()
function ()
Modifiers.set('creative_enabled', false)
this.creative_are_you_sure = false
this.creative_enabled = false
@@ -588,20 +503,20 @@ end
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.players[event.player_index]
on_player_joined_game(player)
create_clear_corpse_frame(player)
if this.bottom_button then
BottomFrame.add_inner_frame({player = player, element_name = clear_corpse_button_name, tooltip = {'commands.clear_corpse'}, sprite = 'entity/behemoth-biter'})
BottomFrame.add_inner_frame({ player = player, element_name = clear_corpse_button_name, tooltip = { 'commands.clear_corpse' }, sprite = 'entity/behemoth-biter' })
end
end
)
Gui.on_click(
clear_corpse_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Clear Corpse')
if is_spamming then
return
@@ -612,7 +527,7 @@ Gui.on_click(
Event.add(
BottomFrame.events.bottom_quickbar_location_changed,
function(event)
function (event)
local player_index = event.player_index
if not player_index then
return

View File

@@ -1,103 +1,55 @@
local Event = require 'utils.event'
local Session = require 'utils.datastore.session_data'
local Commands = require 'utils.commands'
commands.add_command(
'trust',
'Promotes a player to trusted!',
function(cmd)
Commands.new('trust', 'Promotes a player to trusted!')
:require_admin()
:add_parameter('player', false, 'player')
:callback(function (player, target_player)
local trusted = Session.get_trusted_table()
local player = game.player
if player and player.valid then
if not player.admin then
player.print("You're not admin!", {r = 1, g = 0.5, b = 0.1})
return
if target_player then
if trusted[target_player.name] then
game.print(target_player.name .. ' is already trusted!')
return false
end
trusted[target_player.name] = true
game.print(target_player.name .. ' is now a trusted player.', { r = 0.22, g = 0.99, b = 0.99 })
if cmd.parameter == nil then
return
end
local target_player = game.get_player(cmd.parameter)
if target_player then
if trusted[target_player.name] then
game.print(target_player.name .. ' is already trusted!')
return
for _, a in pairs(game.connected_players) do
if a.admin and a.name ~= player.name then
a.print('[ADMIN]: ' .. player.name .. ' trusted ' .. target_player.name, { r = 1, g = 0.5, b = 0.1 })
end
trusted[target_player.name] = true
game.print(target_player.name .. ' is now a trusted player.', {r = 0.22, g = 0.99, b = 0.99})
for _, a in pairs(game.connected_players) do
if a.admin and a.name ~= player.name then
a.print('[ADMIN]: ' .. player.name .. ' trusted ' .. target_player.name, {r = 1, g = 0.5, b = 0.1})
end
end
end
else
if cmd.parameter == nil then
return
end
local target_player = game.get_player(cmd.parameter)
if target_player then
if trusted[target_player.name] == true then
game.print(target_player.name .. ' is already trusted!')
return
end
trusted[target_player.name] = true
game.print(target_player.name .. ' is now a trusted player.', {r = 0.22, g = 0.99, b = 0.99})
end
end
end
)
end)
commands.add_command(
'untrust',
'Demotes a player from trusted!',
function(cmd)
Commands.new('untrust', 'Demotes a player from trusted!')
:require_admin()
:add_parameter('player', false, 'player')
:callback(function (player, target_player)
local trusted = Session.get_trusted_table()
local player = game.player
if player and player.valid then
if not player.admin then
player.print("You're not admin!", {r = 1, g = 0.5, b = 0.1})
return
if target_player then
if trusted[target_player.name] == false then
game.print(target_player.name .. ' is already untrusted!')
return false
end
trusted[target_player.name] = false
game.print(target_player.name .. ' is now untrusted.', { r = 0.22, g = 0.99, b = 0.99 })
if cmd.parameter == nil then
return
end
local target_player = game.get_player(cmd.parameter)
if target_player then
if trusted[target_player.name] == false then
game.print(target_player.name .. ' is already untrusted!')
return
for _, a in pairs(game.connected_players) do
if a.admin and a.name ~= player.name then
a.print('[ADMIN]: ' .. player.name .. ' untrusted ' .. target_player.name, { r = 1, g = 0.5, b = 0.1 })
end
trusted[target_player.name] = false
game.print(target_player.name .. ' is now untrusted.', {r = 0.22, g = 0.99, b = 0.99})
for _, a in pairs(game.connected_players) do
if a.admin == true and a.name ~= player.name then
a.print('[ADMIN]: ' .. player.name .. ' untrusted ' .. target_player.name, {r = 1, g = 0.5, b = 0.1})
end
end
end
else
if cmd.parameter == nil then
return
end
local target_player = game.get_player(cmd.parameter)
if target_player then
if trusted[target_player.name] == false then
game.print(target_player.name .. ' is already untrusted!')
return
end
trusted[target_player.name] = false
game.print(target_player.name .. ' is now untrusted.', {r = 0.22, g = 0.99, b = 0.99})
end
end
end
)
end)
Event.add(
defines.events.on_player_created,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not (player and player.valid) then
return

View File

@@ -5,6 +5,7 @@ local Event = require 'utils.event'
local Global = require 'utils.global'
local Gui = require 'utils.gui'
local SpamProtection = require 'utils.spam_protection'
local Commands = require 'utils.commands'
local this = {
players = {},
@@ -13,7 +14,7 @@ local this = {
Global.register(
this,
function(t)
function (t)
this = t
end
)
@@ -91,7 +92,7 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip)
local frame = player.gui.screen[locate_player_frame_name]
if not validate_frame(frame) then
frame = player.gui.screen.add({type = 'frame', name = locate_player_frame_name, caption = target.name})
frame = player.gui.screen.add({ type = 'frame', name = locate_player_frame_name, caption = target.name })
end
frame.force_auto_center()
@@ -105,16 +106,16 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip)
if render then
local render_object =
rendering.draw_text {
text = '',
surface = target.surface,
target = {target.position.x, target.position.y - 3},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
players = {player.index},
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
text = '',
surface = target.surface,
target = { target.position.x, target.position.y - 3 },
color = { r = 0.98, g = 0.66, b = 0.22 },
scale = 3,
players = { player.index },
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
if player_data then
player_data.render_object = render_object
@@ -123,15 +124,15 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip)
local camera =
frame.add(
{
type = 'camera',
name = player_frame_name,
position = target.position,
zoom = zoom or 0.4,
surface_index = surface,
tooltip = tooltip or ''
}
)
{
type = 'camera',
name = player_frame_name,
position = target.position,
zoom = zoom or 0.4,
surface_index = surface,
tooltip = tooltip or ''
}
)
camera.style.minimal_width = 740
camera.style.minimal_height = 580
player_data = create_player_data(player)
@@ -139,23 +140,14 @@ local function create_mini_camera_gui(player, target, zoom, render, tooltip)
return frame
end
commands.add_command(
'where',
'Locates a player',
function(cmd)
local player = game.player
if player and player.valid then
if not cmd.parameter then
return
end
Commands.new('where', 'Locates a player')
:add_parameter('player', false, 'player-online')
:callback(
function (player, target)
if this.module_disabled then
return
return false
end
local target = game.get_player(cmd.parameter)
if target and target.valid then
local player_data = create_player_data(player)
player_data.target = target
@@ -164,11 +156,9 @@ commands.add_command(
remove_player_data(player)
player.print('[Where] Please type a name of a player who is connected.', Color.warning)
end
else
return
end
end
)
)
local function on_nth_tick()
for p, data in pairs(this.players) do
@@ -197,7 +187,7 @@ end
Gui.on_click(
locate_player_frame_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Where Locate Player')
if is_spamming then
return
@@ -208,7 +198,7 @@ Gui.on_click(
Gui.on_custom_close(
locate_player_frame_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Where Locate Player')
if is_spamming then
return
@@ -219,7 +209,7 @@ Gui.on_custom_close(
Gui.on_click(
player_frame_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Where Player Frame')
if is_spamming then
return

View File

@@ -0,0 +1,3 @@
require 'utils.commands.trust_system'
require 'utils.commands.misc'
require 'utils.commands.where'

View File

@@ -138,6 +138,26 @@ function Public.iter_players(callback)
end
end
function Public.output_message(value, color, player)
color = color and Color[color] or Color.white
player = player or game.player
local message = value and type(value) == 'table' and serpent.block(value) or value or type(value) == 'userdata' and 'Cannot output userdata' or 'Cannot output nil'
if player then
player = player and type(player) == 'number' and game.get_player(player) and game.get_player(player).valid or player and player.valid and player or false
if not player then
error('Given player is not valid.', 2)
end
player.play_sound { path = 'utility/scenario_message' }
player.print(message, color)
else
Server.output_data(message)
end
end
function Public.cast_bool(var)
if var then
return true
@@ -278,9 +298,9 @@ end
-- @param command the command's name as table element
-- @param parameters the command's parameters as a table (optional)
function Public.log_command(actor, command, parameters)
local action = concat {'[Admin-Command] ', actor, ' used: ', command}
local action = concat { '[Admin-Command] ', actor, ' used: ', command }
if parameters then
action = concat {action, ' ', parameters}
action = concat { action, ' ', parameters }
end
print(action)
end
@@ -305,7 +325,7 @@ end
--- Returns a random RGB color as a table
function Public.random_RGB()
return {r = random(0, 255), g = random(0, 255), b = random(0, 255)}
return { r = random(0, 255), g = random(0, 255), b = random(0, 255) }
end
--- Sets a table element to value while also returning value.
@@ -380,8 +400,9 @@ end
--- Takes a string, number, or LuaPlayer and returns a valid LuaPlayer or nil.
-- Intended for commands as there are extra checks in place.
-- @param <string|number|LuaPlayer>
-- @param <boolean>
-- @return <LuaPlayer|nil> <string|nil> <number|nil> the LuaPlayer, their name, and their index
function Public.validate_player(player_ident)
function Public.validate_player(player_ident, check_admin)
local data_type = type(player_ident)
local player
@@ -400,6 +421,12 @@ function Public.validate_player(player_ident)
return
end
if check_admin then
if not player.admin then
return
end
end
return player, player.name, player.index
end

View File

@@ -3,6 +3,7 @@ local Token = require 'utils.token'
local Color = require 'utils.color_presets'
local Server = require 'utils.server'
local Event = require 'utils.event'
local Commands = require 'utils.commands'
local color_data_set = 'colors'
local set_data = Server.set_data
@@ -12,19 +13,19 @@ local Public = {}
local fetch =
Token.register(
function(data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player then
return
function (data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player then
return
end
if value then
player.color = value.color[1]
player.chat_color = value.chat[1]
end
end
if value then
player.color = value.color[1]
player.chat_color = value.chat[1]
end
end
)
)
--- Tries to get data from the webpanel and applies the value to the player.
-- @param data_set player token
@@ -41,7 +42,7 @@ local fetcher = Public.fetch
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player then
return
@@ -50,45 +51,27 @@ Event.add(
end
)
commands.add_command(
'save-color',
'Save your personal color preset so it´s always the same whenever you join.',
function()
local player = game.player
if not player or not player.valid then
return
Commands.new('save-color', "Save your personal color preset so it's always the same whenever you join.")
:require_backend()
:callback(
function (player)
local color = player.color
local chat = player.chat_color
set_data(color_data_set, player.name, { color = { color }, chat = { chat } })
player.print('Your personal color has been saved to the datastore.', Color.success)
end
)
local secs = Server.get_current_time()
if not secs then
return
Commands.new('remove-color', 'Removes your saved color from the datastore.')
:require_backend()
:callback(
function (player)
set_data(color_data_set, player.name, nil)
player.print('Your personal color has been removed from the datastore.', Color.success)
end
)
local color = player.color
local chat = player.chat_color
set_data(color_data_set, player.name, {color = {color}, chat = {chat}})
player.print('Your personal color has been saved to the datastore.', Color.success)
end
)
commands.add_command(
'remove-color',
'Removes your saved color from the datastore.',
function()
local player = game.player
if not player or not player.valid then
return
end
local secs = Server.get_current_time()
if not secs then
return
end
set_data(color_data_set, player.name, nil)
player.print('Your personal color has been removed from the datastore.', Color.success)
end
)
return Public

View File

@@ -1,131 +0,0 @@
-- created by Gerkiz for ComfyFactorio
local Server = require 'utils.server'
local Event = require 'utils.event'
local Gui = require 'utils.gui'
local Color = require 'utils.color_presets'
local current_time_label = 'current_time_label'
local function validate_player(player)
if not player then
return false
end
if not player.valid then
return false
end
return true
end
local function set_location(player)
local gui = player.gui
local label = gui.screen[current_time_label]
if not label or not label.valid then
return
end
local res = player.display_resolution
local uis = player.display_scale
label.location = {x = res.width - 423 * uis, y = 50 * uis}
end
local function create_label(player)
local date = Server.get_current_date_with_time()
if not date then
date = '1970-01-01'
end
local label =
player.gui.screen.add(
{
type = 'label',
name = current_time_label,
caption = date
}
)
local style = label.style
style.font = 'default-game'
return label
end
Event.add(
defines.events.on_player_joined_game,
function(event)
local player = game.get_player(event.player_index)
local label = player.gui.screen[current_time_label]
if not label or not label.valid then
label = create_label(player)
end
set_location(player)
label.visible = false
end
)
-- Update the value each second
Event.on_nth_tick(
60,
function()
local date = Server.get_current_date_with_time()
if not date then
date = '1969-01-01 00:00'
end
local players = game.connected_players
for i = 1, #players do
local player = players[i]
local label = player.gui.screen[current_time_label]
if label and label.valid then
label.caption = date
set_location(player)
end
end
end
)
commands.add_command(
'server-date',
'Toggle to show the date',
function()
local player = game.player
local secs = Server.get_current_time()
if validate_player(player) then
if not secs then
return player.print('Not running on Comfy backend.', Color.warning)
end
local label = player.gui.screen[current_time_label]
if not label or not label.valid then
label = create_label(player)
end
if label.visible then
label.visible = false
player.print('Removed date-label.', Color.warning)
else
label.visible = true
set_location(player)
player.print('Added date-label.', Color.success)
end
end
end
)
Gui.screen_to_bypass(current_time_label)
Event.add(
defines.events.on_player_display_resolution_changed,
function(event)
local player = game.get_player(event.player_index)
set_location(player)
end
)
Event.add(
defines.events.on_player_display_scale_changed,
function(event)
local player = game.get_player(event.player_index)
set_location(player)
end
)

View File

@@ -1,5 +1,4 @@
require 'utils.datastore.server_ups_data'
require 'utils.datastore.current_time_data'
require 'utils.datastore.color_data'
require 'utils.datastore.session_data'
require 'utils.datastore.statistics'

View File

@@ -10,6 +10,7 @@ local Utils = require 'utils.core'
local table = require 'utils.table'
local Gui = require 'utils.gui'
local StatData = require 'utils.datastore.statistics'
local Commands = require 'utils.commands'
StatData.add_normalize('jailed', 'Jailed')
@@ -24,10 +25,10 @@ local votejail = {}
local votefree = {}
local revoked_permissions = {}
local settings = {
playtime_for_vote = 77760000, -- 15 days
playtime_for_vote = 77760000, -- 15 days
playtime_for_instant_jail = 362880000, -- 70 days
-- playtime_for_instant_jail = 103680000, -- 20 days
clear_voted_player = 36000, -- remove player from vote-tbl after 10 minutes
clear_voted_player = 36000, -- remove player from vote-tbl after 10 minutes
clear_terms_tbl = 2000,
votejail_count = 5,
valid_surface = 'nauvis',
@@ -64,7 +65,7 @@ Global.register(
terms_tbl = terms_tbl,
revoked_permissions = revoked_permissions
},
function(t)
function (t)
jailed = t.jailed
votejail = t.votejail
votefree = t.votefree
@@ -111,7 +112,7 @@ local function add_revoked(name, admin, reason)
if not revoked_permissions[name] then
revoked_permissions[name] = true
set_data(revoked_permissions_set, name, {revoked = true, actor = admin, reason = reason, date = date})
set_data(revoked_permissions_set, name, { revoked = true, actor = admin, reason = reason, date = date })
return true
else
return false
@@ -135,67 +136,67 @@ end
local clear_terms_tbl =
Token.register(
function(data)
local player = data.player
if not player then
return
end
function (data)
local player = data.player
if not player then
return
end
if terms_tbl[player] then
terms_tbl[player] = nil
return
if terms_tbl[player] then
terms_tbl[player] = nil
return
end
end
end
)
)
local play_alert_sound =
Token.register(
function(data)
local name = data.name
if not name then
return
end
local player = game.get_player(name)
if not player or not player.valid then
return
end
function (data)
local name = data.name
if not name then
return
end
local player = game.get_player(name)
if not player or not player.valid then
return
end
player.play_sound {path = 'utility/scenario_message', volume_modifier = 1}
end
)
player.play_sound { path = 'utility/scenario_message', volume_modifier = 1 }
end
)
local clear_jail_data_token =
Token.register(
function(data)
local offender = data.offender
if not offender then
return
end
if votejail[offender] and votejail[offender].jailed then
return
end
function (data)
local offender = data.offender
if not offender then
return
end
if votejail[offender] and votejail[offender].jailed then
return
end
local msg_two = 'You have been cleared of all accusations because not enough players voted against you.'
Utils.print_to(offender, msg_two)
votejail[offender] = nil
votefree[offender] = nil
end
)
local msg_two = 'You have been cleared of all accusations because not enough players voted against you.'
Utils.print_to(offender, msg_two)
votejail[offender] = nil
votefree[offender] = nil
end
)
local clear_gui =
Token.register(
function(data)
local player = data.player
if player and player.valid then
for _, child in pairs(player.gui.center.children) do
child.destroy()
end
for _, child in pairs(player.gui.left.children) do
child.destroy()
function (data)
local player = data.player
if player and player.valid then
for _, child in pairs(player.gui.center.children) do
child.destroy()
end
for _, child in pairs(player.gui.left.children) do
child.destroy()
end
end
end
end
)
)
local function validate_playtime(player)
local tracker = Session.get_session_table()
@@ -266,46 +267,46 @@ local function create_gulag_surface()
local walls = {}
local tiles = {}
pcall(
function()
function ()
surface =
game.create_surface(
'gulag',
{
autoplace_controls = {
['coal'] = {frequency = 23, size = 3, richness = 3},
['stone'] = {frequency = 20, size = 3, richness = 3},
['copper-ore'] = {frequency = 25, size = 3, richness = 3},
['iron-ore'] = {frequency = 35, size = 3, richness = 3},
['uranium-ore'] = {frequency = 20, size = 3, richness = 3},
['crude-oil'] = {frequency = 80, size = 3, richness = 1},
['trees'] = {frequency = 0.75, size = 2, richness = 0.1},
['enemy-base'] = {frequency = 15, size = 0, richness = 1}
},
cliff_settings = {cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff'},
height = 64,
width = 256,
peaceful_mode = false,
seed = 1337,
starting_area = 'very-low',
starting_points = {{x = 0, y = 0}},
terrain_segmentation = 'normal',
water = 'normal'
}
)
'gulag',
{
autoplace_controls = {
['coal'] = { frequency = 23, size = 3, richness = 3 },
['stone'] = { frequency = 20, size = 3, richness = 3 },
['copper-ore'] = { frequency = 25, size = 3, richness = 3 },
['iron-ore'] = { frequency = 35, size = 3, richness = 3 },
['uranium-ore'] = { frequency = 20, size = 3, richness = 3 },
['crude-oil'] = { frequency = 80, size = 3, richness = 1 },
['trees'] = { frequency = 0.75, size = 2, richness = 0.1 },
['enemy-base'] = { frequency = 15, size = 0, richness = 1 }
},
cliff_settings = { cliff_elevation_0 = 1024, cliff_elevation_interval = 10, name = 'cliff' },
height = 64,
width = 256,
peaceful_mode = false,
seed = 1337,
starting_area = 'very-low',
starting_points = { { x = 0, y = 0 } },
terrain_segmentation = 'normal',
water = 'normal'
}
)
end
)
if not surface then
surface = game.create_surface('gulag', {width = 40, height = 40})
surface = game.create_surface('gulag', { width = 40, height = 40 })
end
surface.always_day = true
surface.request_to_generate_chunks({0, 0}, 9)
surface.request_to_generate_chunks({ 0, 0 }, 9)
surface.force_generate_chunk_requests()
local area = {left_top = {x = -128, y = -32}, right_bottom = {x = 128, y = 32}}
local area = { left_top = { x = -128, y = -32 }, right_bottom = { x = 128, y = 32 } }
for x = area.left_top.x, area.right_bottom.x, 1 do
for y = area.left_top.y, area.right_bottom.y, 1 do
tiles[#tiles + 1] = {name = 'black-refined-concrete', position = {x = x, y = y}}
tiles[#tiles + 1] = { name = 'black-refined-concrete', position = { x = x, y = y } }
if x == area.left_top.x or x == area.right_bottom.x or y == area.left_top.y or y == area.right_bottom.y then
walls[#walls + 1] = {name = 'stone-wall', force = 'neutral', position = {x = x, y = y}}
walls[#walls + 1] = { name = 'stone-wall', force = 'neutral', position = { x = x, y = y } }
end
end
end
@@ -319,8 +320,8 @@ local function create_gulag_surface()
rendering.draw_text {
text = 'The pit of despair ☹',
surface = surface,
target = {0, -50},
color = {r = 0.98, g = 0.66, b = 0.22},
target = { 0, -50 },
color = { r = 0.98, g = 0.66, b = 0.22 },
scale = 10,
font = 'heading-1',
alignment = 'center',
@@ -346,7 +347,7 @@ local function teleport_player_to_gulag(player, action, mute)
p_data.locked = true
p_data.muted = mute or false
end
player.teleport(gulag.find_non_colliding_position('character', {0, 0}, 128, 1), gulag.name)
player.teleport(gulag.find_non_colliding_position('character', { 0, 0 }, 128, 1), gulag.name)
local data = {
player = player
}
@@ -374,7 +375,7 @@ local function teleport_player_to_gulag(player, action, mute)
end
p_group.add_player(player)
local pos = {x = p.x, y = p.y}
local pos = { x = p.x, y = p.y }
---@diagnostic disable-next-line: missing-parameter
local get_tile = surface.get_tile(pos)
if get_tile.valid and get_tile.name == 'out-of-map' then
@@ -555,10 +556,10 @@ local function vote_to_jail(player, offender, msg)
end
if not votejail[offender] then
votejail[offender] = {index = 0, actor = player.name}
votejail[offender] = { index = 0, actor = player.name }
local message = player.name .. ' has started a vote to jail player ' .. offender
Utils.print_to(nil, message)
Task.set_timeout_in_ticks(settings.clear_voted_player, clear_jail_data_token, {offender = offender})
Task.set_timeout_in_ticks(settings.clear_voted_player, clear_jail_data_token, { offender = offender })
end
if not votejail[offender][player.name] then
@@ -583,7 +584,7 @@ local function vote_to_free(player, offender)
end
if not votefree[offender] then
votefree[offender] = {index = 0, actor = player.name}
votefree[offender] = { index = 0, actor = player.name }
local message = player.name .. ' has started a vote to free player ' .. offender
Utils.print_to(nil, message)
end
@@ -644,12 +645,12 @@ local function jail(player, offender, msg, raised, mute)
local message = offender .. ' has been jailed by ' .. player .. '. Cause: ' .. msg
jailed[offender] = {jailed = true, actor = player, reason = msg}
jailed[offender] = { jailed = true, actor = player, reason = msg }
if not raised then
set_data(jailed_data_set, offender, {jailed = true, actor = player, reason = msg, date = date})
set_data(jailed_data_set, offender, { jailed = true, actor = player, reason = msg, date = date })
end
Event.raise(Public.events.on_player_jailed, {player_index = offender.index})
Event.raise(Public.events.on_player_jailed, { player_index = offender.index })
StatData.get_data(to_jail_player.index):increase('jailed')
@@ -701,7 +702,7 @@ local function jail_temporary(player, offender, msg, mute)
local message = offender.name .. ' has been temporary jailed by ' .. player.name .. '.'
jailed[offender.name] = {jailed = true, actor = player.name, reason = msg, temporary = true}
jailed[offender.name] = { jailed = true, actor = player.name, reason = msg, temporary = true }
Utils.print_to(nil, message)
local data = Server.build_embed_data()
@@ -715,7 +716,7 @@ local function jail_temporary(player, offender, msg, mute)
votejail[offender.name].jailed = true
end
Event.raise(Public.events.on_player_jailed, {player_index = offender.index})
Event.raise(Public.events.on_player_jailed, { player_index = offender.index })
StatData.get_data(offender.index):increase('jailed')
@@ -723,7 +724,7 @@ local function jail_temporary(player, offender, msg, mute)
draw_notice_frame(offender)
Task.set_timeout_in_ticks(10800, release_player_from_temporary_prison_token, {offender_name = offender.name, actor_name = player.name})
Task.set_timeout_in_ticks(10800, release_player_from_temporary_prison_token, { offender_name = offender.name, actor_name = player.name })
return true
end
@@ -744,7 +745,7 @@ local function free(player, offender)
set_data(jailed_data_set, offender, nil)
Event.raise(Public.events.on_player_unjailed, {player_index = offender.index})
Event.raise(Public.events.on_player_unjailed, { player_index = offender.index })
Utils.print_to(nil, message)
local data = Server.build_embed_data()
@@ -759,34 +760,34 @@ end
local is_jailed =
Token.register(
function(data)
local key = data.key
local value = data.value
if value and value.jailed and value.reason then
jail('script', key, value.reason, true)
else
free('script', key)
function (data)
local key = data.key
local value = data.value
if value and value.jailed and value.reason then
jail('script', key, value.reason, true)
else
free('script', key)
end
end
end
)
)
--! start gui handler
release_player_from_temporary_prison_token =
Token.register(
function(event)
local actor_name = event.actor_name
local offender_name = event.offender_name
function (event)
local actor_name = event.actor_name
local offender_name = event.offender_name
if jailed[offender_name] and jailed[offender_name].temporary then
free('script', offender_name)
Utils.print_to(nil, module_name .. 'If you find someone abusing their jail permissions - report them to the admins of Comfy!')
if jailed[offender_name] and jailed[offender_name].temporary then
free('script', offender_name)
Utils.print_to(nil, module_name .. 'If you find someone abusing their jail permissions - report them to the admins of Comfy!')
local actor = game.get_player(actor_name)
remove_action_needed(actor)
local actor = game.get_player(actor_name)
remove_action_needed(actor)
end
end
end
)
)
local function remove_target_frame(target_frame)
Gui.remove_data_recursively(target_frame)
@@ -806,12 +807,12 @@ local function draw_main_frame(player, offender)
local warning_message =
concat {
'[font=heading-2]You have jailed player: [color=yellow]',
offender.name,
'\n[/color][/font]'
}
'[font=heading-2]You have jailed player: [color=yellow]',
offender.name,
'\n[/color][/font]'
}
local info_warning_text = inside_table.add({type = 'label', caption = warning_message})
local info_warning_text = inside_table.add({ type = 'label', caption = warning_message })
local info_warning_text_style = info_warning_text.style
info_warning_text_style.single_line = false
info_warning_text_style.width = 470
@@ -824,14 +825,14 @@ local function draw_main_frame(player, offender)
local abuse_message =
concat {
'Jailing is [color=red]NOT[/color] allowed to solve personal disputes, talk to each other instead of jailing!\n',
'Jail is only a temporary solution, the jailed offender will be released in less than one week automatically.\n',
'If the actions done by the offender was serious, report the offender to the admins on [color=yellow]https://getcomfy.eu/discord[/color]\n',
'Providing NO reason will free the offender after 3 minutes or if you close this window - note - this will log your actions to our admins.\n\n',
'[color=yellow]Explain why you jailed ' .. offender.name .. '[/color]'
}
'Jailing is [color=red]NOT[/color] allowed to solve personal disputes, talk to each other instead of jailing!\n',
'Jail is only a temporary solution, the jailed offender will be released in less than one week automatically.\n',
'If the actions done by the offender was serious, report the offender to the admins on [color=yellow]https://getcomfy.eu/discord[/color]\n',
'Providing NO reason will free the offender after 3 minutes or if you close this window - note - this will log your actions to our admins.\n\n',
'[color=yellow]Explain why you jailed ' .. offender.name .. '[/color]'
}
local info_warning_text_extended = inside_table.add({type = 'label', caption = abuse_message})
local info_warning_text_extended = inside_table.add({ type = 'label', caption = abuse_message })
local info_warning_text_extended_style = info_warning_text_extended.style
info_warning_text_extended_style.single_line = false
info_warning_text_extended_style.font = 'heading-2'
@@ -842,7 +843,7 @@ local function draw_main_frame(player, offender)
info_warning_text_extended_style.right_padding = 4
info_warning_text_extended_style.bottom_padding = 4
local placeholder_text = inside_table.add({type = 'text-box', text = '', name = placeholder_jail_text_box})
local placeholder_text = inside_table.add({ type = 'text-box', text = '', name = placeholder_jail_text_box })
local placeholder_text_style = placeholder_text.style
placeholder_text_style.width = 470
placeholder_text_style.height = 200
@@ -852,19 +853,19 @@ local function draw_main_frame(player, offender)
placeholder_text_style.horizontally_squashable = false
placeholder_text_style.vertically_squashable = false
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
local bottom_flow = main_frame.add({ type = 'flow', direction = 'horizontal' })
local left_flow = bottom_flow.add({type = 'flow'})
local left_flow = bottom_flow.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'Discard report'})
local close_button = left_flow.add({ type = 'button', name = discard_button_name, caption = 'Discard report' })
close_button.style = 'back_button'
local right_flow = bottom_flow.add({type = 'flow'})
local right_flow = bottom_flow.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
local save_button = right_flow.add({type = 'button', name = save_button_name, caption = 'Save report'})
local save_button = right_flow.add({ type = 'button', name = save_button_name, caption = 'Save report' })
save_button.style = 'confirm_button'
local data = {
@@ -878,7 +879,7 @@ local function draw_main_frame(player, offender)
player.opened = main_frame
end
remove_notice = function(player)
remove_notice = function (player)
local screen = player.gui.screen
local notice = screen[notice_frame_name]
@@ -887,7 +888,7 @@ remove_notice = function(player)
end
end
remove_action_needed = function(player)
remove_action_needed = function (player)
local screen = player.gui.screen
local action_needed = screen[jail_frame_name]
@@ -896,7 +897,7 @@ remove_action_needed = function(player)
end
end
draw_notice_frame = function(player)
draw_notice_frame = function (player)
local main_frame, inside_table = Gui.add_main_frame_with_toolbar(player, 'screen', notice_frame_name, nil, nil, 'Notice', true, 2)
if not main_frame or not inside_table then
@@ -907,20 +908,20 @@ draw_notice_frame = function(player)
main_frame_style.width = 400
main_frame.auto_center = true
local content_flow = inside_table.add {type = 'flow', direction = 'horizontal'}
local content_flow = inside_table.add { type = 'flow', direction = 'horizontal' }
content_flow.style.top_padding = 16
content_flow.style.bottom_padding = 16
content_flow.style.left_padding = 24
content_flow.style.right_padding = 24
content_flow.style.horizontally_stretchable = false
local sprite_flow = content_flow.add {type = 'flow'}
local sprite_flow = content_flow.add { type = 'flow' }
sprite_flow.style.vertical_align = 'center'
sprite_flow.style.vertically_stretchable = false
sprite_flow.add {type = 'sprite', sprite = 'utility/warning_icon'}
sprite_flow.add { type = 'sprite', sprite = 'utility/warning_icon' }
local label_flow = content_flow.add {type = 'flow'}
local label_flow = content_flow.add { type = 'flow' }
label_flow.style.horizontal_align = 'left'
label_flow.style.top_padding = 10
label_flow.style.left_padding = 24
@@ -933,7 +934,7 @@ draw_notice_frame = function(player)
end
label_flow.style.horizontally_stretchable = false
local label = label_flow.add {type = 'label', caption = warning_message}
local label = label_flow.add { type = 'label', caption = warning_message }
label.style.single_line = false
player.opened = main_frame
@@ -943,19 +944,19 @@ end
local update_jailed =
Token.register(
function(data)
local key = data.key
local value = data.value or false
local player = data.player or 'script'
local message = data.message
local mute = data.mute or false
if value then
jail(player, key, message, nil, mute)
else
free(player, key)
function (data)
local key = data.key
local value = data.value or false
local player = data.player or 'script'
local message = data.message
local mute = data.mute or false
if value then
jail(player, key, message, nil, mute)
else
free(player, key)
end
end
end
)
)
--- Tries to get data from the webpanel and updates the local table with values.
-- @param data_set player token
@@ -1058,20 +1059,20 @@ end
--- Writes the data called back from the server into the revoked_permissions table, clearing any previous entries
local sync_revoked_permissions_callback =
Token.register(
function(data)
if not data then
return
end
if not data.entries then
return
end
function (data)
if not data then
return
end
if not data.entries then
return
end
table.clear_table(revoked_permissions)
for k, v in pairs(data.entries) do
revoked_permissions[k] = v
table.clear_table(revoked_permissions)
for k, v in pairs(data.entries) do
revoked_permissions[k] = v
end
end
end
)
)
--- Signals the server to retrieve the revoked_permissions dataset
function Public.sync_revoked_permissions()
@@ -1105,7 +1106,7 @@ end
Server.on_data_set_changed(
jailed_data_set,
function(data)
function (data)
if not data then
return
end
@@ -1122,7 +1123,7 @@ Server.on_data_set_changed(
Server.on_data_set_changed(
revoked_permissions_set,
function(data)
function (data)
if not data then
return
end
@@ -1131,97 +1132,44 @@ Server.on_data_set_changed(
end
)
commands.add_command(
'jail',
'Sends the player to gulag! Valid arguments are:\n/jail <LuaPlayer>',
function()
end
)
Commands.new('jail', 'Sends the player to gulag.')
:add_parameter('offender', false, 'player')
:callback(function ()
end)
commands.add_command(
'free',
'Brings back the player from gulag.',
function()
end
)
Commands.new('free', 'Brings back the player from gulag.')
:add_parameter('offender', false, 'player')
:callback(function ()
end)
commands.add_command(
'toggle_jail_permission',
'Usable only for admins - controls who may use jail commands!',
function(cmd)
local name
local player = game.player
if not player or not player.valid then
name = 'Server'
else
name = player.name
if not player.admin then
return
end
Commands.new('toggle_jail_permission', 'Usable only for admins - controls who may use jail commands!')
:require_backend()
:add_parameter('target-player', false, 'player')
:add_parameter('reason', false, 'string')
:callback(function (player, target, reason)
if is_revoked(target.name) then
remove_revoked(target.name)
Utils.print_to(player, target.name .. ' can now utilize jail commands once again!')
return true
end
local param = cmd.parameter
local t_player
local revoke_reason
local revoke_player
local str = ''
if not param then
return Utils.print_to(player, 'Both player and reason is needed!')
if reason and string.len(reason) <= 0 then
Utils.print_to(player, 'No valid reason was given.')
return false
end
local t = {}
for i in string.gmatch(param, '%S+') do
table.insert(t, i)
if reason and string.len(reason) <= 10 then
Utils.print_to(player, 'Reason is too short.')
return false
end
t_player = t[1]
add_revoked(target.name, player.name, reason)
Utils.print_to(player, target.name .. ' is now forbidden from utilizing jail commands!')
end)
for i = 2, #t do
str = str .. t[i] .. ' '
revoke_reason = str
end
if game.get_player(t_player) then
revoke_player = game.get_player(t_player)
else
return Utils.print_to(player, 'No player was provided.')
end
if not revoke_player then
return
end
if is_revoked(revoke_player.name) then
remove_revoked(revoke_player.name)
Utils.print_to(player, revoke_player.name .. ' can now utilize jail commands once again!')
return
end
if revoke_reason then
if revoke_reason and string.len(revoke_reason) <= 0 then
Utils.print_to(player, 'No valid reason was given.')
return
end
if revoke_reason and string.len(revoke_reason) <= 10 then
Utils.print_to(player, 'Reason is too short.')
return
end
add_revoked(revoke_player.name, name, revoke_reason)
Utils.print_to(player, revoke_player.name .. ' is now forbidden from utilizing jail commands!')
else
Utils.print_to(player, 'No message was provided')
end
end
)
Event.on_init(
function()
function ()
get_gulag_permission_group()
create_gulag_surface()
end
@@ -1229,14 +1177,14 @@ Event.on_init(
Event.add(
Server.events.on_server_started,
function()
function ()
Public.sync_revoked_permissions()
end
)
Event.add(
defines.events.on_console_command,
function(event)
function (event)
local cmd = event.command
if not valid_commands[cmd] then
return
@@ -1293,11 +1241,11 @@ Event.add(
Utils.warning(player, "Jailing someone because they're afk or other stupid reasons is NOT valid!")
Utils.warning(player, 'Run this command again to if you really want to do this!')
for _ = 1, 4 do
Task.set_timeout_in_ticks(delay, play_alert_sound, {name = player.name})
Task.set_timeout_in_ticks(delay, play_alert_sound, { name = player.name })
delay = delay + 30
end
terms_tbl[player.name] = true
Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, {player = player.name})
Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, { player = player.name })
return
end
@@ -1328,11 +1276,11 @@ Event.add(
Utils.warning(player, "Jailing someone because they're afk or other stupid reasons is NOT valid!")
Utils.warning(player, 'Run this command again to if you really want to do this!')
for _ = 1, 4 do
Task.set_timeout_in_ticks(delay, play_alert_sound, {name = player.name})
Task.set_timeout_in_ticks(delay, play_alert_sound, { name = player.name })
delay = delay + 30
end
terms_tbl[player.name] = true
Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, {player = player.name})
Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, { player = player.name })
return
end
@@ -1373,7 +1321,7 @@ Event.add(
print(module_name .. 'Abusing the jail command will lead to revoked permissions. Jailing someone in case of disagreement is _NEVER_ OK!')
print(module_name .. 'Run this command again to if you really want to do this!')
terms_tbl['script'] = true
Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, {player = 'script'})
Task.set_timeout_in_ticks(settings.clear_terms_tbl, clear_terms_tbl, { player = 'script' })
return
end
@@ -1391,7 +1339,7 @@ Event.add(
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -1423,7 +1371,7 @@ Event.add(
Event.add(
defines.events.on_player_changed_surface,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -1446,7 +1394,7 @@ Event.add(
Gui.on_text_changed(
placeholder_jail_text_box,
function(event)
function (event)
local player = event.player
if not player or not player.valid then
return
@@ -1475,7 +1423,7 @@ Gui.on_text_changed(
Gui.on_click(
save_button_name,
function(event)
function (event)
local player = event.player
if not player or not player.valid then
return
@@ -1500,7 +1448,7 @@ Gui.on_click(
return Utils.print_to(player, module_name .. 'Reason is too short. Explain thoroughly why you jailed ' .. offender .. '!')
end
set_data(jailed_data_set, offender, {jailed = true, actor = player.name, reason = jailed[offender].reason, date = date})
set_data(jailed_data_set, offender, { jailed = true, actor = player.name, reason = jailed[offender].reason, date = date })
end
Utils.print_to(player, module_name .. 'Jail data has been submitted!')
@@ -1520,7 +1468,7 @@ Gui.on_click(
Gui.on_click(
discard_button_name,
function(event)
function (event)
local player = event.player
local screen = player.gui.screen
local frame = screen[jail_frame_name]

View File

@@ -1,8 +1,8 @@
-- created by Gerkiz for ComfyFactorio
local Token = require 'utils.token'
local Color = require 'utils.color_presets'
local Server = require 'utils.server'
local Event = require 'utils.event'
local Commands = require 'utils.commands'
local message_dataset = 'regulars'
local set_data = Server.set_data
@@ -12,18 +12,18 @@ local Public = {}
local fetch =
Token.register(
function(data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
function (data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
if type(value) == 'table' then
game.print('>> ' .. player.name .. ' << ' .. value.msg, value.color) -- we want the player name to be printed.
end
end
if type(value) == 'table' then
game.print('>> ' .. player.name .. ' << ' .. value.msg, value.color) -- we want the player name to be printed.
end
end
)
)
--- Tries to get data from the webpanel and applies the value to the player.
-- @param data_set player token
@@ -40,53 +40,36 @@ function Public.fetch(key)
end
end
commands.add_command(
'save-message',
'Sets your custom join message. "{name}" will be replaced with your username',
function(cmd)
local player = game.player
if not player or not player.valid then
return
end
local secs = Server.get_current_time()
if not secs then
return
end
local param = cmd.parameter
if param then
if param == '' or param == 'Name' then
return player.print('You did not specify a message.', Color.warning)
Commands.new('save-message', 'Sets your custom join message. "{name}" will be replaced with your username.')
:require_backend()
:add_parameter('message', false, 'string')
:callback(
function (player, message)
if message == '' or message == 'Name' then
player.print('You did not specify a message.')
return false
end
if string.len(param) > 64 then
return player.print('Message is too long. 64 characters maximum.', {r = 0.90, g = 0.0, b = 0.0})
if string.len(message) > 64 then
player.print('Message is too long. 64 characters maximum.')
return false
end
set_data(message_dataset, player.name, {msg = param, color = player.color})
player.print('You message has been saved.', Color.success)
else
player.print('You did not specify a message.', Color.warning)
set_data(message_dataset, player.name, { msg = message, color = player.color })
player.print('You message has been saved.')
end
end
)
)
commands.add_command(
'remove-message',
'Removes your custom join message.',
function()
local player = game.player
if not player or not player.valid then
return
Commands.new('remove-message', 'Removes your custom join message.')
:require_backend()
:callback(
function (player)
set_data(message_dataset, player.name, nil)
player.print('Your message has been removed.')
end
set_data(message_dataset, player.name, nil)
player.print('Your message has been removed.', Color.success)
end
)
)
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return

View File

@@ -1,8 +1,8 @@
-- created by Gerkiz for ComfyFactorio
local Token = require 'utils.token'
local Color = require 'utils.color_presets'
local Server = require 'utils.server'
local Event = require 'utils.event'
local Commands = require 'utils.commands'
local tag_dataset = 'tags'
local set_data = Server.set_data
@@ -12,25 +12,25 @@ local Public = {}
local fetch =
Token.register(
function(data)
if not data then
return
end
function (data)
if not data then
return
end
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
if type(value) == 'string' then
player.tag = '[' .. value .. ']'
if type(value) == 'string' then
player.tag = '[' .. value .. ']'
end
end
end
)
)
local alphanumeric = function(str)
local alphanumeric = function (str)
return (string.match(str, '[^%w]') ~= nil)
end
@@ -45,63 +45,44 @@ function Public.fetch(key)
end
end
commands.add_command(
'save-tag',
'Sets your custom tag that is persistent.',
function(cmd)
local player = game.player
if not player or not player.valid then
return
end
local secs = Server.get_current_time()
if not secs then
return
end
local param = cmd.parameter
if param then
if alphanumeric(param) then
player.print('Tag is not valid.', {r = 0.90, g = 0.0, b = 0.0})
return
Commands.new('save-tag', 'Sets your custom tag that is persistent.')
:add_parameter('tag', false, 'The tag you want to set.')
:require_backend()
:callback(
function (player, tag)
if alphanumeric(tag) then
player.print('Tag is not valid.')
return false
end
if param == '' or param == 'Name' then
return player.print('You did not specify a tag.', Color.warning)
if tag == '' or tag == 'Name' then
player.print('You did not specify a tag.')
return false
end
if string.len(param) > 32 then
player.print('Tag is too long. 64 characters maximum.', {r = 0.90, g = 0.0, b = 0.0})
return
if string.len(tag) > 32 then
player.print('Tag is too long. 64 characters maximum.')
return false
end
set_data(tag_dataset, player.name, param)
player.tag = '[' .. param .. ']'
player.print('Your tag has been saved.', Color.success)
else
player.print('You did not specify a tag.', Color.warning)
set_data(tag_dataset, player.name, tag)
player.tag = '[' .. tag .. ']'
player.print('Your tag has been saved.')
end
end
)
)
commands.add_command(
'remove-tag',
'Removes your custom tag.',
function()
local player = game.player
if not player or not player.valid then
return
Commands.new('remove-tag', 'Removes your custom tag.')
:require_backend()
:callback(
function (player)
set_data(tag_dataset, player.name, nil)
player.print('Your tag has been removed.')
end
set_data(tag_dataset, player.name, nil)
player.print('Your tag has been removed.', Color.success)
end
)
)
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return

View File

@@ -6,6 +6,7 @@ local Server = require 'utils.server'
local Event = require 'utils.event'
local Global = require 'utils.global'
local Core = require 'utils.core'
local Commands = require 'utils.commands'
local quickbar_dataset = 'quickbar'
local quickbar_dataset_modded = 'quickbar_modded'
@@ -28,7 +29,7 @@ local ignored_items = {
Global.register(
this,
function(t)
function (t)
this = t
end
)
@@ -40,7 +41,7 @@ local function apply_stash(player)
if stash then
for i, slot in pairs(stash) do
if slot and slot.name then
player.set_personal_logistic_slot(i, {name = slot.name, min = slot.min, max = slot.max})
player.set_personal_logistic_slot(i, { name = slot.name, min = slot.min, max = slot.max })
end
end
this.logistics[player.name] = nil
@@ -49,49 +50,49 @@ end
local fetch_quickbar =
Token.register(
function(data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
if value then
for i, slot in pairs(value) do
if slot and slot ~= '' then
player.set_quick_bar_slot(i, slot)
end
function (data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
end
end
)
local fetch_logistics =
Token.register(
function(data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
local tech = player.force.technologies['logistic-robotics'].researched
if value then
for i, slot in pairs(value) do
if slot and slot.name then
if tech then
player.set_personal_logistic_slot(i, {name = slot.name, min = slot.min, max = slot.max})
else
if not this.logistics[player.name] then
this.logistics[player.name] = {}
end
this.logistics[player.name][i] = {name = slot.name, min = slot.min, max = slot.max}
if value then
for i, slot in pairs(value) do
if slot and slot ~= '' then
player.set_quick_bar_slot(i, slot)
end
end
end
end
end
)
)
local fetch_logistics =
Token.register(
function (data)
local key = data.key
local value = data.value
local player = game.players[key]
if not player or not player.valid then
return
end
local tech = player.force.technologies['logistic-robotics'].researched
if value then
for i, slot in pairs(value) do
if slot and slot.name then
if tech then
player.set_personal_logistic_slot(i, { name = slot.name, min = slot.min, max = slot.max })
else
if not this.logistics[player.name] then
this.logistics[player.name] = {}
end
this.logistics[player.name][i] = { name = slot.name, min = slot.min, max = slot.max }
end
end
end
end
end
)
--- Tries to get data from the webpanel and applies the value to the player.
-- @param LuaPlayer
@@ -156,7 +157,7 @@ function Public.save_logistics(player)
for i = 1, 400 do
local slot = player.get_personal_logistic_slot(i)
if slot and slot.name then
slots[i] = {name = slot.name, min = slot.min, max = slot.max}
slots[i] = { name = slot.name, min = slot.min, max = slot.max }
end
end
if next(slots) then
@@ -200,82 +201,51 @@ local save_logistics = Public.save_logistics
local remove_quickbar = Public.remove_quickbar
local remove_logistics = Public.remove_logistics
commands.add_command(
'save-quickbar',
'Save your personal quickbar preset so it´s always the same.',
function()
local player = game.player
if not player or not player.valid then
return
Commands.new('save-quickbar', 'Save your personal quickbar preset so it´s always the same.')
:require_backend()
:callback(
function (player)
save_quickbar(player)
player.print('Quickbar saved.')
end
)
local secs = Server.get_current_time()
if not secs then
return
Commands.new('save-logistics', 'Save your personal logistics preset so it´s always the same.')
:require_backend()
:callback(
function (player)
local success, _ = pcall(save_logistics, player)
player.print('Notice: only the first 400 slots are saved.', Color.warning)
if not success then
player.print('An error occured while trying to save your logistics slots.', Color.warning)
return false
end
player.print('Logistics saved.')
end
save_quickbar(player)
end
)
)
commands.add_command(
'save-logistics',
'Save your personal logistics preset so it´s always the same.',
function()
local player = game.player
if not player or not player.valid then
return
Commands.new('remove-quickbar', 'Removes your personal quickbar preset from the datastore.')
:require_backend()
:callback(
function (player)
remove_quickbar(player)
player.print('Quickbar removed.')
end
)
local secs = Server.get_current_time()
if not secs then
return
Commands.new('remove-logistics', 'Removes your personal logistics preset from the datastore.')
:require_backend()
:callback(
function (player)
remove_logistics(player)
player.print('Logistics removed.')
end
local success, _ = pcall(save_logistics, player)
player.print('Notice: only the first 400 slots are saved.', Color.warning)
if not success then
player.print('An error occured while trying to save your logistics slots.', Color.warning)
end
end
)
)
commands.add_command(
'remove-quickbar',
'Removes your personal quickbar preset from the datastore.',
function()
local player = game.player
if not player or not player.valid then
return
end
local secs = Server.get_current_time()
if not secs then
return
end
remove_quickbar(player)
end
)
commands.add_command(
'remove-logistics',
'Removes your personal logistics preset from the datastore.',
function()
local player = game.player
if not player or not player.valid then
return
end
local secs = Server.get_current_time()
if not secs then
return
end
remove_logistics(player)
end
)
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -293,11 +263,11 @@ Event.add(
Event.add(
defines.events.on_research_finished,
function(event)
function (event)
local research = event.research
if research.name == 'logistic-robotics' then
Core.iter_connected_players(
function(player)
function (player)
apply_stash(player)
end
)

View File

@@ -2,20 +2,10 @@
local Server = require 'utils.server'
local Event = require 'utils.event'
local Gui = require 'utils.gui'
local Color = require 'utils.color_presets'
local Commands = require 'utils.commands'
local ups_label = 'ups_label'
local function validate_player(player)
if not player then
return false
end
if not player.valid then
return false
end
return true
end
local function set_location(player)
local gui = player.gui
local label = gui.screen[ups_label]
@@ -24,7 +14,7 @@ local function set_location(player)
end
local res = player.display_resolution
local uis = player.display_scale
label.location = {x = res.width - 423 * uis, y = 30 * uis}
label.location = { x = res.width - 423 * uis, y = 30 * uis }
end
local function create_label(player)
@@ -33,12 +23,12 @@ local function create_label(player)
local label =
player.gui.screen.add(
{
type = 'label',
name = ups_label,
caption = sUPS
}
)
{
type = 'label',
name = ups_label,
caption = sUPS
}
)
local style = label.style
style.font = 'default-game'
return label
@@ -46,7 +36,7 @@ end
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
local label = player.gui.screen[ups_label]
@@ -62,7 +52,7 @@ Event.add(
-- Update the value each second
Event.on_nth_tick(
60,
function()
function ()
local ups = Server.get_ups()
local caption = 'SUPS = ' .. ups
local players = game.connected_players
@@ -77,19 +67,10 @@ Event.on_nth_tick(
end
)
commands.add_command(
'server-ups',
'Toggle the server UPS display!',
function()
local player = game.player
local secs = Server.get_current_time()
if validate_player(player) then
if not secs then
return player.print('Not running on Comfy backend.', Color.warning)
end
Commands.new('server-ups', 'Toggle the server UPS display!')
:require_backend()
:callback(
function (player)
local label = player.gui.screen[ups_label]
if not label or not label.valid then
label = create_label(player)
@@ -97,21 +78,20 @@ commands.add_command(
if label.visible then
label.visible = false
player.print('Removed Server-UPS label.', Color.warning)
player.print('Removed Server-UPS label.')
else
label.visible = true
set_location(player)
player.print('Added Server-UPS label.', Color.success)
player.print('Added Server-UPS label.')
end
end
end
)
)
Gui.screen_to_bypass(ups_label)
Event.add(
defines.events.on_player_display_resolution_changed,
function(event)
function (event)
local player = game.get_player(event.player_index)
set_location(player)
end
@@ -119,7 +99,7 @@ Event.add(
Event.add(
defines.events.on_player_display_scale_changed,
function(event)
function (event)
local player = game.get_player(event.player_index)
set_location(player)
end

View File

@@ -32,7 +32,7 @@ Global.register(
trusted = trusted,
settings = settings
},
function(tbl)
function (tbl)
session = tbl.session
online_track = tbl.online_track
trusted = tbl.trusted
@@ -48,120 +48,120 @@ local Public = {
local try_download_data_token =
Token.register(
function(data)
local player_index = data.key
local value = data.value
if value then
session[player_index] = value
if value > settings.trusted_value then
trusted[player_index] = true
function (data)
local player_index = data.key
local value = data.value
if value then
session[player_index] = value
if value > settings.trusted_value then
trusted[player_index] = true
end
else
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
session[player_index] = 0
trusted[player_index] = false
-- we don't want to clutter the database with players less than 10 minutes played.
if player.online_time >= settings.required_only_time_to_save_time then
set_data(session_data_set, player_index, session[player_index])
end
end
else
end
)
local try_upload_data_token =
Token.register(
function (data)
local player_index = data.key
if not player_index then
return
end
local value = data.value
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
session[player_index] = 0
trusted[player_index] = false
-- we don't want to clutter the database with players less than 10 minutes played.
if player.online_time >= settings.required_only_time_to_save_time then
set_data(session_data_set, player_index, session[player_index])
end
end
end
)
local try_upload_data_token =
Token.register(
function(data)
local player_index = data.key
if not player_index then
return
end
local value = data.value
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
if value then
-- we don't want to clutter the database with players less than 10 minutes played.
if player.online_time <= settings.required_only_time_to_save_time then
return
end
local old_time_ingame = value
if not online_track[player_index] then
online_track[player_index] = 0
end
if online_track[player_index] > player.online_time then
-- instance has been reset but scenario owner did not clear the player.
-- so we clear it here and return.
online_track[player_index] = 0
return
end
local new_time = old_time_ingame + player.online_time - online_track[player_index]
if new_time <= 0 then
new_time = old_time_ingame + player.online_time
online_track[player_index] = 0
print('[ERROR] ' .. player_index .. ' had new time set as negative value: ' .. new_time)
return
end
if new_time > settings.trusted_value then
trusted[player_index] = true
end
set_data(session_data_set, player_index, new_time)
session[player_index] = new_time
online_track[player_index] = player.online_time
else
if player.online_time >= settings.required_only_time_to_save_time then
if not session[player_index] then
session[player_index] = 0
if value then
-- we don't want to clutter the database with players less than 10 minutes played.
if player.online_time <= settings.required_only_time_to_save_time then
return
end
local old_time_ingame = value
if not online_track[player_index] then
online_track[player_index] = 0
end
if online_track[player_index] > player.online_time then
-- instance has been reset but scenario owner did not clear the player.
-- so we clear it here and return.
online_track[player_index] = 0
return
end
local new_time = old_time_ingame + player.online_time - online_track[player_index]
if new_time <= 0 then
new_time = old_time_ingame + player.online_time
online_track[player_index] = 0
print('[ERROR] ' .. player_index .. ' had new time set as negative value: ' .. new_time)
return
end
if new_time > settings.trusted_value then
trusted[player_index] = true
end
set_data(session_data_set, player_index, new_time)
session[player_index] = new_time
online_track[player_index] = player.online_time
else
if player.online_time >= settings.required_only_time_to_save_time then
if not session[player_index] then
session[player_index] = 0
end
set_data(session_data_set, player_index, session[player_index])
end
set_data(session_data_set, player_index, session[player_index])
end
end
end
)
)
local get_total_playtime_token =
Token.register(
function(data)
if not data then
return
end
if not data.to_print then
return
end
function (data)
if not data then
return
end
if not data.to_print then
return
end
local player_index = data.key
local value = data.value
local to_print = data.to_print
local player = game.get_player(to_print)
if player and player.valid then
if player_index then
if value then
player.play_sound {path = 'utility/scenario_message', volume_modifier = 1}
player.print('[color=blue]' .. player_index .. '[/color] has a total playtime of: ' .. Core.get_formatted_playtime(value))
else
player.play_sound {path = 'utility/cannot_build', volume_modifier = 1}
player.print('[color=red]' .. player_index .. '[/color] was not found.')
local player_index = data.key
local value = data.value
local to_print = data.to_print
local player = game.get_player(to_print)
if player and player.valid then
if player_index then
if value then
player.play_sound { path = 'utility/scenario_message', volume_modifier = 1 }
player.print('[color=blue]' .. player_index .. '[/color] has a total playtime of: ' .. Core.get_formatted_playtime(value))
else
player.play_sound { path = 'utility/cannot_build', volume_modifier = 1 }
player.print('[color=red]' .. player_index .. '[/color] was not found.')
end
end
end
end
end
)
)
local nth_tick_token =
Token.register(
function(data)
local player_name = data.name
Public.try_ul_data(player_name)
end
)
function (data)
local player_name = data.name
Public.try_ul_data(player_name)
end
)
--- Uploads each connected players play time to the dataset
local function upload_data()
@@ -170,7 +170,7 @@ local function upload_data()
for i = 1, #players do
count = count + 10
local player = players[i]
set_timeout_in_ticks(count, nth_tick_token, {name = player.name})
set_timeout_in_ticks(count, nth_tick_token, { name = player.name })
end
end
@@ -283,7 +283,7 @@ function Public.get_trusted_table()
end
--- Returns the table of trusted
---@param player LuaPlayer
---@param player? LuaPlayer
---@return table|boolean
function Public.get_trusted_player(player)
return trusted and player and player.valid and trusted[player.name] or false
@@ -306,7 +306,7 @@ function Public.set_untrusted_player(player)
end
--- Returns the table of session
---@param player LuaPlayer
---@param player? LuaPlayer
---@return table|boolean
function Public.get_session_player(player)
local secs = Server.get_current_time()
@@ -349,7 +349,7 @@ end
--- don't calculate the values wrong.
Event.add(
Public.events.on_player_removed,
function()
function ()
for name, _ in pairs(online_track) do
local player = game.get_player(name)
Public.clear_player(player)
@@ -359,7 +359,7 @@ Event.add(
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -371,7 +371,7 @@ Event.add(
Event.add(
defines.events.on_player_left_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -385,7 +385,7 @@ Event.on_nth_tick(settings.nth_tick, upload_data)
Server.on_data_set_changed(
session_data_set,
function(data)
function (data)
local player = game.get_player(data.key)
if player and player.valid then
session[data.key] = data.value
@@ -400,27 +400,6 @@ Server.on_data_set_changed(
end
)
commands.add_command(
'playtime',
'Fetches a player total playtime or nil.',
function(cmd)
local player = game.player
if not (player and player.valid) then
return
end
local p = player.print
local param = cmd.parameter
if not param then
p('[ERROR] No player was provided.', Color.fail)
return
end
Public.get_and_print_to_player(player, param)
end
)
Public.upload_data = upload_data
return Public

View File

@@ -1,31 +1,20 @@
local DebugView = require 'utils.debug.main_view'
local Server = require 'utils.server'
local Commands = require 'utils.commands'
local Gui = require 'utils.gui'
commands.add_command(
'debug',
'Opens the debugger',
function(_)
local player = game.player
if not player or not player.valid then
return
Commands.new('debug', 'Usable only for admins - opens the debugger!')
:require_admin()
:callback(
function (player)
local screen = player.gui.screen
local frame = screen[DebugView.main_frame_name]
if frame and frame.valid then
Gui.destroy(frame)
end
DebugView.open_debug(player)
end
if not player.admin then
player.print('Only admins can use this command.')
return
end
local secs = Server.get_current_time()
local admins = Server.get_admins_data()
if secs and not admins[player.name] then
player.print('Only admins can use this command.')
return
end
DebugView.open_debug(player)
end
)
)
if _DEBUG then
local Model = require 'model'
@@ -35,76 +24,50 @@ if _DEBUG then
local dump = Model.dump
local log = log
commands.add_command(
'dump-log',
'Dumps value to log',
function(args)
local player = game.player
local p
if player then
p = player.print
if not player.admin then
p('Only admins can use this command.')
return
Commands.new('dump-log', 'Dumps value to log')
:require_admin()
:add_parameter('value', false, 'string')
:callback(
function (player, value)
local func, err = loadstring('return ' .. value)
if not func then
player.print(err)
return false
end
else
p = player.print
end
if args.parameter == nil then
return
end
local func, err = loadstring('return ' .. args.parameter)
if not func then
p(err)
return
end
local suc, v = pcall(func)
local suc, value = pcall(func)
if not suc then
p(value)
return
end
log(dump(value))
end
)
commands.add_command(
'dump-file',
'Dumps value to dump.lua',
function(args)
local player = game.player
local p
if player then
p = player.print
if not player.admin then
p('Only admins can use this command.')
return
if not suc then
player.print(v)
return false
end
else
p = player.print
end
if args.parameter == nil then
return
end
local func, err = loadstring('return ' .. args.parameter)
if not func then
p(err)
return
log(dump(v))
end
)
local suc, value = pcall(func)
Commands.new('dump-file', 'Dumps value to dump.lua')
:require_admin()
:add_parameter('value', false, 'string')
:callback(
function (player, value)
local func, err = loadstring('return ' .. value)
if not suc then
p(value)
return
if not func then
player.print(err)
return false
end
local suc, v = pcall(func)
if not suc then
player.print(v)
return false
end
v = dump(v)
game.write_file('dump.lua', v, false)
end
value = dump(value)
game.write_file('dump.lua', value, false)
end
)
)
end

View File

@@ -42,7 +42,7 @@ function Public.show(container)
input_text_box_style.height = 32
input_text_box_style.maximal_width = 1000
local refresh_button = right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'}
local refresh_button = right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'Refresh'}
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
refresh_button_style.height = 32

View File

@@ -75,7 +75,7 @@ function Public.show(container)
type = 'sprite-button',
name = refresh_name,
sprite = 'utility/reset',
tooltip = 'refresh'
tooltip = 'Refresh'
}
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
@@ -108,21 +108,32 @@ function Public.show(container)
Gui.set_data(refresh_button, data)
end
local function draw_element_headers(element_panel, values, selected_index)
local copy = {}
for k, v in pairs(values) do
copy[k] = v
local function rec(children, copy)
for key, child in next, children do
if child.name then
copy[key] = child
elseif type(child) == 'table' then
rec(child, copy)
end
end
end
local function deepCopy(children)
local copy = {}
rec(children, copy)
return copy
end
local function draw_element_headers(element_panel, values, selected_index)
local copy = deepCopy(values)
local selected_header = nil
local element_map = Gui.element_map()
local name_map = Gui.names
for ei, stored_data in pairs(copy) do
local ele = element_map[ei]
local ele_name = ''
if ele and ele.valid then
ele_name = ele.name
if stored_data and stored_data.name then
ele_name = stored_data.name
end
local gui_name = name_map[ele_name]
@@ -161,6 +172,8 @@ Gui.on_click(
if not header_data then
return
end
Gui.clear(element)
local values = header_data.values
local player_index = header_data.player_index
@@ -200,6 +213,7 @@ Gui.on_click(
if not header_data then
return
end
local stored_data = header_data.stored_data
local element_index = header_data.element_index

View File

@@ -5,16 +5,13 @@ local Public = {}
local pages = {
require 'utils.debug.public_global_view',
require 'utils.debug.global_view'
require 'utils.debug.global_view',
require 'utils.debug.gui_data_view',
require 'utils.debug.package_view',
require 'utils.debug._g_view',
require 'utils.debug.event_view'
}
if _DEBUG then
pages[#pages + 1] = require 'utils.debug.gui_data_view'
pages[#pages + 1] = require 'utils.debug.package_view'
pages[#pages + 1] = require 'utils.debug._g_view'
pages[#pages + 1] = require 'utils.debug.event_view'
end
local main_frame_name = Gui.uid_name()
local close_name = Gui.uid_name()
local tab_name = Gui.uid_name()
@@ -40,8 +37,8 @@ function Public.open_debug(player)
frame_style.height = 600
frame_style.width = 1100
local tab_flow = frame.add {type = 'flow', direction = 'horizontal'}
local container = frame.add {type = 'flow'}
local tab_flow = frame.add {type = 'flow', direction = 'horizontal', name = 'tab_flow'}
local container = frame.add {type = 'flow', name = 'container'}
container.style.vertically_stretchable = true
local data = {}
@@ -108,4 +105,6 @@ Gui.on_click(
end
)
Public.main_frame_name = main_frame_name
return Public

View File

@@ -106,6 +106,10 @@ end
function Public.dump_function(func)
local res = {'upvalues:\n'}
if debug.getupvalue == nil then
return concat(res)
end
local i = 1
while true do
local n, v = debug.getupvalue(func, i)

View File

@@ -13,23 +13,44 @@ local header_name = Gui.uid_name()
local left_panel_name = Gui.uid_name()
local right_panel_name = Gui.uid_name()
local input_text_box_name = Gui.uid_name()
local filter_text_box_name = Gui.uid_name()
local refresh_name = Gui.uid_name()
Public.name = 'Global'
function Public.show(container)
function Public.show(container, filter)
container.clear()
local main_flow = container.add {type = 'flow', direction = 'horizontal'}
local left_panel = main_flow.add {type = 'scroll-pane', name = left_panel_name}
local left_flow = main_flow.add({type = 'flow', direction = 'vertical'})
left_flow.style.width = 400
local left_top_flow = left_flow.add {type = 'flow', direction = 'horizontal'}
local filter_text_name = left_top_flow.add {type = 'text-box', name = filter_text_box_name, tooltip = 'Filter for tokens', text = filter or ''}
if filter then
filter_text_name.focus()
end
local left_panel = left_flow.add {type = 'scroll-pane', name = left_panel_name}
local left_panel_style = left_panel.style
left_panel_style.width = 400
for token_id, token_name in pairs(Global.names) do
local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name}
Gui.set_data(header, token_id)
if filter then
if token_name:lower():find(filter:lower()) then
local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name}
Gui.set_data(header, token_id)
end
else
local header = left_panel.add({type = 'flow'}).add {type = 'label', name = header_name, caption = token_name}
Gui.set_data(header, token_id)
end
end
local right_flow = main_flow.add {type = 'flow', direction = 'vertical'}
right_flow.style.horizontally_stretchable = true
local right_top_flow = right_flow.add {type = 'flow', direction = 'horizontal'}
@@ -39,7 +60,7 @@ function Public.show(container)
input_text_box_style.height = 32
input_text_box_style.maximal_width = 1000
local refresh_button = right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'refresh'}
local refresh_button = right_top_flow.add {type = 'sprite-button', name = refresh_name, sprite = 'utility/reset', tooltip = 'Refresh'}
local refresh_button_style = refresh_button.style
refresh_button_style.width = 32
refresh_button_style.height = 32
@@ -93,9 +114,9 @@ Gui.on_click(
local id = Global.get_global(token_id)
local content = dump(id) or 'Could not load data.'
if content:find('function_handlers') then
content = '{}' -- desync handler
end
-- if content:find('function_handlers') then
-- content = '{}' -- desync handler
-- end
right_panel.text = content
end
)
@@ -120,6 +141,19 @@ Gui.on_text_changed(
end
)
Gui.on_text_changed(
filter_text_box_name,
function(event)
local element = event.element
local text = element.text
local parent = element.parent.parent.parent.parent
Gui.remove_data_recursively(parent)
Public.show(parent, text)
end
)
Gui.on_click(
refresh_name,
function(event)

View File

@@ -111,9 +111,6 @@ local on_player_joined_game = function(event)
end
local on_player_created = function(event)
if not this.modded then
return
end
if this.disabled then
return
end
@@ -151,9 +148,6 @@ local on_player_created = function(event)
end
local on_player_respawned = function(event)
if not this.modded then
return
end
if this.disabled then
return
end
@@ -162,7 +156,7 @@ local on_player_respawned = function(event)
end
local on_cutscene_waypoint_reached = function(event)
if not this.modded then
if this.disabled then
return
end
if not crash_site.is_crash_site_cutscene(event) then
@@ -187,7 +181,7 @@ local on_cutscene_waypoint_reached = function(event)
end
local skip_crash_site_cutscene = function(event)
if not this.modded then
if this.disabled then
return
end
@@ -216,10 +210,6 @@ local skip_crash_site_cutscene = function(event)
end
local on_cutscene_cancelled = function(event)
if not this.modded then
return
end
if this.disabled then
return
end
@@ -315,7 +305,6 @@ Event.on_init(
function()
local game_has_mods = is_game_modded()
if game_has_mods then
this.modded = true
this.created_items = created_items()
this.respawn_items = respawn_items()
this.crashed_ship_items = ship_items()

View File

@@ -22,10 +22,10 @@ local local_settings = {
local main_gui_tabs = {}
local screen_elements = {}
local remove_data_recursively
local concat = table.concat
local names = {}
-- global
local data = {}
local element_map = {}
local settings = {
mod_gui_top_frame = false,
disabled_tabs = {},
@@ -34,13 +34,14 @@ local settings = {
Public.token =
Global.register(
{data = data, element_map = element_map, settings = settings},
function(tbl)
data = tbl.data
element_map = tbl.element_map
settings = tbl.settings
end
)
{ data = data, settings = settings },
function (tbl)
data = tbl.data
settings = tbl.settings
end
)
Public.names = names
Public.beam = 'file/utils/files/beam.png'
Public.beam_1 = 'file/utils/files/beam_1.png'
@@ -61,7 +62,20 @@ Public.info_icon = 'file/utils/files/info.png'
Public.mod_gui_button_enabled = false
function Public.uid_name()
return tostring(Token.uid())
if game then
return error('This function is not allowed to be called in this context.', 2)
end
local info = debug.getinfo(2, 'Sl')
local filepath = info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5)
local line = info.currentline
local token = tostring(Token.uid())
local name = concat { token, ' - ', filepath, ':line:', line }
names[token] = name
return token
end
function Public.uid()
@@ -121,9 +135,10 @@ function Public.set_data(element, value)
data[player_index] = values
end
values[element.index] = value
values[element.index] = { value = value, name = element.name }
end
end
local set_data = Public.set_data
-- Associates data with the LuaGuiElement. If data is nil then removes the data
@@ -151,58 +166,7 @@ function Public.set_data_parent(parent, element, value)
values[parent.index] = {}
end
values[parent.index][element.index] = value
end
end
-- Associates data with the LuaGuiElement along with the tag. If data is nil then removes the data
function Public.set_data_custom(tag, element, value)
if not tag then
return error('A tag is required', 2)
end
local player_index = element.player_index
local values = data[player_index]
if value == nil then
if not values then
return
end
local tags = values[tag]
if not tags then
if next(values) == nil then
data[player_index] = nil
end
return
end
if element.remove then
values[tag] = nil
return
end
tags[element.index] = nil
if next(tags) == nil then
values[tag] = nil
end
else
if not values then
values = {
[tag] = {}
}
data[player_index] = values
end
local tags = values[tag]
if not tags then
values[tag] = {}
tags = values[tag]
end
tags[element.index] = value
values[parent.index][element.index] = { value = value, name = element.name }
end
end
@@ -219,7 +183,7 @@ function Public.get_data(element)
return nil
end
return values[element.index]
return values[element.index].value
end
-- Gets the Associated data with this LuaGuiElement if any.
@@ -243,51 +207,28 @@ function Public.get_data_parent(parent, element)
return nil
end
return values[element.index]
end
-- Gets the Associated data with this LuaGuiElement if any.
function Public.get_data_custom(tag, element)
if not tag then
return error('A tag is required', 2)
end
if not element then
return error('An element is required', 2)
end
local player_index = element.player_index
local values = data[player_index]
if not values then
return nil
end
values = values[tag]
if not values then
return nil
end
return values[element.index]
return values[element.index].value
end
-- Adds a gui that is alike the factorio native gui.
function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_settings_button_name, close_main_frame_name, name, info, inside_table_count)
function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_settings_button_name,
close_main_frame_name, name, info, inside_table_count)
if not align then
return
end
local main_frame
if align == 'left' then
validate_frame_and_destroy(player.gui.left, set_frame_name)
main_frame = player.gui.left.add {type = 'frame', name = set_frame_name, direction = 'vertical'}
main_frame = player.gui.left.add { type = 'frame', name = set_frame_name, direction = 'vertical' }
elseif align == 'center' then
validate_frame_and_destroy(player.gui.center, set_frame_name)
main_frame = player.gui.center.add {type = 'frame', name = set_frame_name, direction = 'vertical'}
main_frame = player.gui.center.add { type = 'frame', name = set_frame_name, direction = 'vertical' }
elseif align == 'screen' then
validate_frame_and_destroy(player.gui.screen, set_frame_name)
main_frame = player.gui.screen.add {type = 'frame', name = set_frame_name, direction = 'vertical'}
main_frame = player.gui.screen.add { type = 'frame', name = set_frame_name, direction = 'vertical' }
end
local titlebar = main_frame.add {type = 'flow', name = 'titlebar', direction = 'horizontal'}
local titlebar = main_frame.add { type = 'flow', name = 'titlebar', direction = 'horizontal' } --[[@as LuaGuiElement]]
titlebar.style.horizontal_spacing = 8
titlebar.style = 'horizontal_flow'
@@ -302,7 +243,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s
caption = name,
ignored_by_interaction = true
}
local widget = titlebar.add {type = 'empty-widget', style = 'draggable_space', ignored_by_interaction = true}
local widget = titlebar.add { type = 'empty-widget', style = 'draggable_space', ignored_by_interaction = true }
widget.style.left_margin = 4
widget.style.right_margin = 4
widget.style.height = 24
@@ -315,7 +256,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s
name = set_settings_button_name,
style = 'frame_action_button',
sprite = Public.settings_white_icon,
mouse_button_filter = {'left'},
mouse_button_filter = { 'left' },
hovered_sprite = Public.settings_black_icon,
clicked_sprite = Public.settings_black_icon,
tooltip = 'Settings',
@@ -329,7 +270,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s
name = set_settings_button_name,
style = 'frame_action_button',
sprite = Public.info_icon,
mouse_button_filter = {'left'},
mouse_button_filter = { 'left' },
hovered_sprite = Public.info_icon,
clicked_sprite = Public.info_icon,
tooltip = 'Info',
@@ -345,7 +286,7 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s
type = 'sprite-button',
name = close_main_frame_name,
style = 'frame_action_button',
mouse_button_filter = {'left'},
mouse_button_filter = { 'left' },
sprite = 'utility/close_white',
hovered_sprite = 'utility/close_black',
clicked_sprite = 'utility/close_black',
@@ -358,10 +299,10 @@ function Public.add_main_frame_with_toolbar(player, align, set_frame_name, set_s
local inside_frame =
main_frame.add {
type = 'table',
column_count = 1 or inside_table_count,
name = 'inside_frame'
}
type = 'table',
column_count = 1 or inside_table_count,
name = 'inside_frame'
}
return main_frame, inside_frame
end
@@ -382,6 +323,7 @@ function Public.remove_data_recursively(element)
end
end
end
remove_data_recursively = Public.remove_data_recursively
local remove_children_data
@@ -399,6 +341,7 @@ function Public.remove_children_data(element)
end
end
end
remove_children_data = Public.remove_children_data
function Public.destroy(element)
@@ -475,12 +418,13 @@ local function handler_factory(event_id)
end
end
return function(element_name, handler)
return function (element_name, handler)
if not element_name then
return error('Element name is required when passing it onto the handler_factory.', 2)
end
if not handler or not type(handler) == 'function' then
return error('Handler is required when passing it onto the handler_factory and needs to be of type function.', 2)
return error(
'Handler is required when passing it onto the handler_factory and needs to be of type function.', 2)
end
if not handlers then
@@ -507,7 +451,7 @@ local function custom_raise(handlers, element, player)
return
end
handler({element = element, player = player})
handler({ element = element, player = player })
end
-- Disabled the handler so it does not clean then data table of invalid data.
@@ -639,7 +583,7 @@ function Public.add_tab_to_gui(tbl)
local only_server_sided = tbl.only_server_sided or false
if not main_gui_tabs[tbl.caption] then
main_gui_tabs[tbl.caption] = {id = tbl.id, name = tbl.name, admin = admin, only_server_sided = only_server_sided}
main_gui_tabs[tbl.caption] = { id = tbl.id, name = tbl.name, admin = admin, only_server_sided = only_server_sided }
else
error('Given name: ' .. tbl.caption .. ' already exists in table.')
end
@@ -688,7 +632,7 @@ function Public.clear_all_screen_frames(player)
end
function Public.clear_all_active_frames(player)
Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index})
Event.raise(Public.events.on_gui_closed_main_frame, { player_index = player.index })
for _, child in pairs(player.gui.left.children) do
remove_data_recursively(child)
child.destroy()
@@ -771,7 +715,8 @@ end
local function top_button(player)
if settings.mod_gui_top_frame then
local button = Public.add_mod_button(player, {type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style})
local button = Public.add_mod_button(player,
{ type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style })
if button then
button.style.minimal_height = 36
button.style.maximal_height = 36
@@ -782,7 +727,12 @@ local function top_button(player)
if player.gui.top[main_button_name] then
return
end
local button = player.gui.top.add({type = 'sprite-button', name = main_button_name, sprite = 'item/raw-fish', style = Public.button_style})
local button = player.gui.top.add({
type = 'sprite-button',
name = main_button_name,
sprite = 'item/raw-fish',
style = Public.button_style
})
button.style.minimal_height = 38
button.style.maximal_height = 38
button.style.minimal_width = 40
@@ -798,17 +748,17 @@ local function top_toggle_button(player)
if Public.get_mod_gui_top_frame() then
local b =
Public.add_mod_button(
player,
{
type = 'sprite-button',
name = main_toggle_button_name,
sprite = 'utility/preset',
tooltip = 'Click to hide top buttons!',
style = Public.button_style
}
)
player,
{
type = 'sprite-button',
name = main_toggle_button_name,
sprite = 'utility/preset',
tooltip = 'Click to hide top buttons!',
style = Public.button_style
}
)
if b then
b.style.font_color = {165, 165, 165}
b.style.font_color = { 165, 165, 165 }
b.style.font = 'heading-3'
b.style.minimal_height = 36
b.style.maximal_height = 36
@@ -819,14 +769,14 @@ local function top_toggle_button(player)
else
local b =
player.gui.top.add(
{
type = 'sprite-button',
name = main_toggle_button_name,
sprite = 'utility/preset',
style = Public.button_style,
tooltip = 'Click to hide top buttons!'
}
)
{
type = 'sprite-button',
name = main_toggle_button_name,
sprite = 'utility/preset',
style = Public.button_style,
tooltip = 'Click to hide top buttons!'
}
)
b.style.padding = 2
b.style.width = 20
b.style.maximal_height = 38
@@ -845,32 +795,33 @@ local function draw_main_frame(player)
local admins = Server.get_admins_data()
local frame, inside_frame = Public.add_main_frame_with_toolbar(player, 'left', main_frame_name, nil, close_button_name, 'Comfy Factorio')
local tabbed_pane = inside_frame.add({type = 'tabbed-pane', name = 'tabbed_pane'})
local frame, inside_frame = Public.add_main_frame_with_toolbar(player, 'left', main_frame_name, nil,
close_button_name, 'Comfy Factorio')
local tabbed_pane = inside_frame.add({ type = 'tabbed-pane', name = 'tabbed_pane' })
for name, callback in pairs(tabs) do
if not settings.disabled_tabs[name] then
local secs = Server.get_current_time()
if callback.only_server_sided then
if secs then
local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name})
local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'})
local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name })
local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' })
tabbed_pane.add_tab(tab, name_frame)
end
elseif callback.admin == true then
if player.admin then
if not secs then
local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name})
local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'})
local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name })
local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' })
tabbed_pane.add_tab(tab, name_frame)
elseif secs and admins[player.name] then
local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name})
local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'})
local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name })
local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' })
tabbed_pane.add_tab(tab, name_frame)
end
end
else
local tab = tabbed_pane.add({type = 'tab', caption = name, name = callback.name})
local name_frame = tabbed_pane.add({type = 'frame', name = name, direction = 'vertical'})
local tab = tabbed_pane.add({ type = 'tab', caption = name, name = callback.name })
local name_frame = tabbed_pane.add({ type = 'frame', name = name, direction = 'vertical' })
tabbed_pane.add_tab(tab, name_frame)
end
end
@@ -907,7 +858,7 @@ function Public.refresh(player)
for _, tab in pairs(tabbed_pane.tabs) do
if tab.content.name ~= frame.name then
tab.content.clear()
Event.raise(Public.events.on_gui_removal, {player_index = player.index})
Event.raise(Public.events.on_gui_removal, { player_index = player.index })
end
end
@@ -980,7 +931,7 @@ Public.on_value_changed = handler_factory(defines.events.on_gui_value_changed)
Public.on_click(
main_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Main button')
if is_spamming then
return
@@ -991,9 +942,10 @@ Public.on_click(
if frame then
remove_data_recursively(frame)
frame.destroy()
Event.raise(Public.events.on_gui_removal, {player_index = player.index})
Event.raise(Public.events.on_gui_removal, { player_index = player.index })
local active_frame = Public.get_player_active_frame(player)
Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index, element = active_frame or nil})
Event.raise(Public.events.on_gui_closed_main_frame,
{ player_index = player.index, element = active_frame or nil })
else
draw_main_frame(player)
end
@@ -1002,11 +954,11 @@ Public.on_click(
Public.on_click(
close_button_name,
function(event)
function (event)
local player = event.player
local frame = Public.get_parent_frame(player)
local active_frame = Public.get_player_active_frame(player)
Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index, element = active_frame or nil})
Event.raise(Public.events.on_gui_closed_main_frame, { player_index = player.index, element = active_frame or nil })
if frame then
remove_data_recursively(frame)
frame.destroy()
@@ -1016,10 +968,10 @@ Public.on_click(
Public.on_custom_close(
main_frame_name,
function(event)
function (event)
local player = event.player
local active_frame = Public.get_player_active_frame(player)
Event.raise(Public.events.on_gui_closed_main_frame, {player_index = player.index, element = active_frame or nil})
Event.raise(Public.events.on_gui_closed_main_frame, { player_index = player.index, element = active_frame or nil })
local frame = Public.get_parent_frame(player)
if frame then
remove_data_recursively(frame)
@@ -1030,7 +982,7 @@ Public.on_custom_close(
Public.on_click(
main_toggle_button_name,
function(event)
function (event)
local button = event.element
local player = event.player
local top = player.gui.top
@@ -1082,7 +1034,7 @@ Public.on_click(
Event.add(
defines.events.on_gui_click,
function(event)
function (event)
local element = event.element
if not element or not element.valid then
return
@@ -1116,7 +1068,7 @@ Event.add(
Event.add(
defines.events.on_player_created,
function(event)
function (event)
local player = game.get_player(event.player_index)
if local_settings.toggle_button then
top_toggle_button(player)
@@ -1127,67 +1079,14 @@ Event.add(
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
top_button(player)
end
)
if _DEBUG then
local concat = table.concat
local names = {}
Public.names = names
function Public.uid_name()
local info = debug.getinfo(2, 'Sl')
local filepath = info.source:match('^.+/currently%-playing/(.+)$'):sub(1, -5)
local line = info.currentline
local token = tostring(Token.uid())
local name = concat {token, ' - ', filepath, ':line:', line}
names[token] = name
return token
end
function Public.set_data(element, value)
local player_index = element.player_index
local values = data[player_index]
if value == nil then
if not values then
return
end
local index = element.index
values[index] = nil
element_map[index] = nil
if next(values) == nil then
data[player_index] = nil
end
else
if not values then
values = {}
data[player_index] = values
end
local index = element.index
values[index] = value
element_map[index] = element
end
end
set_data = Public.set_data
function Public.data()
return data
end
function Public.element_map()
return element_map
end
function Public.data()
return data
end
return Public

View File

@@ -251,7 +251,7 @@ Gui.on_click(
local element = event.element
local button = event.button
local data = Gui.get_data_custom(tag, element)
local data = Gui.get_data(element)
if not data then
return
end
@@ -288,7 +288,7 @@ Gui.on_click(
local player = event.player
local element = event.element
local data = Gui.get_data_custom(tag, element)
local data = Gui.get_data(element)
if not data then
return
end
@@ -360,7 +360,6 @@ Gui.on_click(
module_name,
function(event)
local player = event.player
Gui.set_data_custom(tag, {player_index = player.index, remove = true}, nil)
Gui.reload_active_tab(player)
end
)
@@ -403,11 +402,5 @@ Gui.on_click(
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_player_left_game, on_player_left_game)
Event.add(
Gui.events.on_gui_removal,
function(event)
Gui.set_data_custom(tag, {player_index = event.player_index, remove = true}, nil)
end
)
return Public

View File

@@ -437,7 +437,7 @@ Public.gui_data = function(data)
tooltip = tooltip
}
Gui.set_data_custom('Players', name_label, player.index)
Gui.set_data(name_label, player.index)
name_label.style.font = 'default'
name_label.style.font_color = {
@@ -591,7 +591,7 @@ Public.gui_data = function(data)
poke_flow.style.right_padding = 20
local poke_label = poke_flow.add {type = 'label', name = 'button_spacer_' .. index, caption = ''}
local poke_button = poke_flow.add {type = 'button', name = poke_player_frame_name, caption = player.pokes}
Gui.set_data_custom('Players', poke_button, player.index)
Gui.set_data(poke_button, player.index)
poke_button.style.font = 'default'
poke_button.tooltip = 'Poke ' .. player.name .. ' with a random message!\nDoes not work poking yourself :<'
poke_label.style.font_color = {r = 0.83, g = 0.83, b = 0.83}

View File

@@ -1,136 +0,0 @@
local Server = require 'utils.server'
local Global = require 'utils.globals'
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
local Public = {}
local this = {
scenarioname = '',
reset_are_you_sure = false,
restart = false,
soft_reset = false,
shutdown = false,
accepted_params = {
['restart'] = true,
['resetnow'] = true,
['shutdown'] = true,
['restartnow'] = true
}
}
Global.register(
this,
function(t)
this = t
end
)
commands.add_command(
'scenario',
'Usable only for admins - controls the scenario!',
function(cmd)
local p
local player = game.player
if not player or not player.valid then
p = log
else
p = player.print
if not player.admin then
return
end
end
local param = cmd.parameter
if this.accepted_params[param] then
goto continue
else
p('[ERROR] Arguments was invalid.')
return
end
::continue::
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
p('[WARNING] This command will disable the soft-reset feature, run this command again if you really want to do this!')
return
end
if param == 'restart' then
if this.restart then
this.reset_are_you_sure = nil
this.restart = false
this.soft_reset = true
p('[SUCCESS] Soft-reset is once again enabled.')
return
else
this.reset_are_you_sure = nil
this.restart = true
this.soft_reset = false
if this.shutdown then
this.shutdown = false
end
p('[WARNING] Soft-reset is disabled! Server will restart from scenario to load new changes.')
return
end
elseif param == 'restartnow' then
this.reset_are_you_sure = nil
p(player.name .. ' restarted the game.')
Server.start_scenario(this.scenarioname)
return
elseif param == 'shutdown' then
if this.shutdown then
this.reset_are_you_sure = nil
this.shutdown = false
this.soft_reset = true
p('[SUCCESS] Soft-reset is once again enabled.')
return
else
this.reset_are_you_sure = nil
this.shutdown = true
this.soft_reset = false
if this.restart then
this.restart = false
end
p('[WARNING] Soft-reset is disabled! Server will shutdown. Most likely because of updates.')
return
end
elseif param == 'reset' then
this.reset_are_you_sure = nil
if player and player.valid then
game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
else
game.print(mapkeeper .. ' server, has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
end
-- reset_map()
p('[WARNING] Game has been reset!')
return
end
end
)
function Public.map_reset_callback(data, callback)
if not data then
return
end
if not callback then
return
end
if not string.find(callback, '%s') and not string.find(callback, 'return') then
callback = 'return ' .. callback
end
if type(callback) == 'function' then
local success, err = pcall(callback, data)
return success, err
else
local success, err = pcall(loadstring(callback), data)
return success, err
end
end
return Public

View File

@@ -22,13 +22,13 @@ local hours_to_ticks = 60 * 60 * 60
local ticks_to_minutes = 1 / minutes_to_ticks
local ticks_to_hours = 1 / hours_to_ticks
local serialize_options = {sparse = true, compact = true}
local serialize_options = { sparse = true, compact = true }
local Public = {}
local server_time = {secs = nil, tick = 0}
local server_ups = {ups = 60}
local start_data = {server_id = nil, server_name = nil, start_time = nil}
local server_time = { secs = nil, tick = 0 }
local server_ups = { ups = 60 }
local start_data = { server_id = nil, server_name = nil, start_time = nil }
local instances = {
data = {}
}
@@ -47,7 +47,7 @@ Global.register(
instances = instances,
admins = admins
},
function(tbl)
function (tbl)
server_time = tbl.server_time
server_ups = tbl.server_ups
start_data = tbl.start_data
@@ -109,6 +109,8 @@ local function output_data(primary, secondary)
return false
end
secondary = type(secondary) == 'table' and '' or secondary
if start_data and start_data.output then
local write = game.write_file
write(start_data.output, primary .. (secondary or '') .. newline, true, 0)
@@ -168,7 +170,7 @@ end
-- function()
-- Trigger some sort of automated restart whenever the game ends.
-- end)
Public.events = {on_server_started = Event.generate_event_name('on_server_started'), on_changes_detected = Event.generate_event_name('on_changes_detected')}
Public.events = { on_server_started = Event.generate_event_name('on_server_started'), on_changes_detected = Event.generate_event_name('on_changes_detected') }
--- Sends a message to the linked discord channel. The message is sanitized of markdown server side.
-- @param message<string> message to send.
@@ -210,28 +212,28 @@ end
-- @param message<string> message to send.
function Public.to_discord_named(channel_name, message)
assert_non_empty_string_and_no_spaces(channel_name, 'channel_name')
output_data(concat({discord_named_tag, channel_name, ' ', message}))
output_data(concat({ discord_named_tag, channel_name, ' ', message }))
end
--- Sends a message to the named discord channel. The message is not sanitized of markdown.
-- @param message<string> message to send.
function Public.to_discord_named_raw(channel_name, message)
assert_non_empty_string_and_no_spaces(channel_name, 'channel_name')
output_data(concat({discord_named_raw_tag, channel_name, ' ', message}))
output_data(concat({ discord_named_raw_tag, channel_name, ' ', message }))
end
--- Sends a message to the named discord channel. The message is sanitized of markdown server side, then made bold.
-- @param message<string> message to send.
function Public.to_discord_named_bold(channel_name, message)
assert_non_empty_string_and_no_spaces(channel_name, 'channel_name')
output_data(concat({discord_named_bold_tag, channel_name, ' ', message}))
output_data(concat({ discord_named_bold_tag, channel_name, ' ', message }))
end
--- Sends an embed message to the named discord channel. The message is sanitized of markdown server side.
-- @param message<string> the content of the embed.
function Public.to_discord_named_embed(channel_name, message)
assert_non_empty_string_and_no_spaces(channel_name, 'channel_name')
output_data(concat({discord_named_embed_tag, channel_name, ' ', message}))
output_data(concat({ discord_named_embed_tag, channel_name, ' ', message }))
end
--- Sends an embed message that is parsed to the named discord channel. The message is sanitized of markdown server side.
@@ -260,7 +262,7 @@ end
-- @param message<string> the content of the embed.
function Public.to_discord_named_embed_raw(channel_name, message)
assert_non_empty_string_and_no_spaces(channel_name, 'channel_name')
output_data(concat({discord_named_embed_raw_tag, channel_name, ' ', message}))
output_data(concat({ discord_named_embed_raw_tag, channel_name, ' ', message }))
end
--- Sends a message to the linked admin discord channel. The message is sanitized of markdown server side.
@@ -284,6 +286,7 @@ function Public.to_banned(message, locale)
output_data(discord_banned_tag .. message)
end
end
--- Sends a message to the linked banned discord channel. The message is sanitized of markdown server side.
-- @param message<string> message to send.
-- @param locale<boolean> if the message should be handled as localized.
@@ -305,6 +308,7 @@ function Public.to_jailed(message, locale)
output_data(discord_jailed_tag .. message)
end
end
--- Sends a message to the linked connected discord channel. The message is sanitized of markdown server side.
-- @param message<string> message to send.
-- @param locale<boolean> if the message should be handled as localized.
@@ -553,20 +557,20 @@ end
local default_ping_token =
Token.register(
function(sent_tick)
local now = game.tick
local diff = now - sent_tick
function (sent_tick)
local now = game.tick
local diff = now - sent_tick
local message = concat({'Pong in ', diff, ' tick(s) ', 'sent tick: ', sent_tick, ' received tick: ', now})
game.print(message)
end
)
local message = concat({ 'Pong in ', diff, ' tick(s) ', 'sent tick: ', sent_tick, ' received tick: ', now })
game.print(message)
end
)
--- Pings the web server.
-- @param func_token<token> The function that is called when the web server replies.
-- The function is passed the tick that the ping was sent.
function Public.ping(func_token)
local message = concat({ping_tag, func_token or default_ping_token, ' ', game.tick})
local message = concat({ ping_tag, func_token or default_ping_token, ' ', game.tick })
output_data(message)
end
@@ -628,15 +632,15 @@ function Public.set_data(data_set, key, value)
local message
local vt = type(value)
if vt == 'nil' then
message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '"}'})
message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '"}' })
elseif vt == 'string' then
value = double_escape(value)
message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"\\"', value, '\\""}'})
message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"\\"', value, '\\""}' })
elseif vt == 'number' then
message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', value, '"}'})
message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', value, '"}' })
elseif vt == 'boolean' then
message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', tostring(value), '"}'})
message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, '",value:"', tostring(value), '"}' })
elseif vt == 'function' then
error('value cannot be a function', 2)
else -- table
@@ -646,7 +650,7 @@ function Public.set_data(data_set, key, value)
-- Need to escape single quotes as serpent uses double quotes for strings.
value = value:gsub('\\', '\\\\'):gsub("'", "\\'")
message = concat({data_set_tag, '{data_set:"', data_set, '",key:"', key, "\",value:'", value, "'}"})
message = concat({ data_set_tag, '{data_set:"', data_set, '",key:"', key, "\",value:'", value, "'}" })
end
output_data(message)
@@ -678,14 +682,14 @@ local function send_try_get_data(data_set, key, callback_token)
data_set = double_escape(data_set)
key = double_escape(key)
local message = concat {data_get_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '"}'}
local message = concat { data_get_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '"}' }
output_data(message)
end
local function send_try_get_ban(username, callback_token)
username = double_escape(username)
local message = concat {ban_get_tag, callback_token, ' {', 'username:"', username, '"}'}
local message = concat { ban_get_tag, callback_token, ' {', 'username:"', username, '"}' }
output_data(message)
end
@@ -694,7 +698,7 @@ local function send_try_get_data_and_print(data_set, key, to_print, callback_tok
key = double_escape(key)
to_print = double_escape(to_print)
local message = concat {data_get_and_print_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '",to_print:"', to_print, '"}'}
local message = concat { data_get_and_print_tag, callback_token, ' {', 'data_set:"', data_set, '",key:"', key, '",to_print:"', to_print, '"}' }
output_data(message)
end
@@ -702,33 +706,33 @@ local function log_antigrief_data(category, action)
category = double_escape(category)
action = double_escape(action)
local message = concat {antigrief_tag, '{', 'category:"', category, '",action:"', action, '"}'}
local message = concat { antigrief_tag, '{', 'category:"', category, '",action:"', action, '"}' }
output_data(message)
end
local cancelable_callback_token =
Token.register(
function(data)
local data_set = data.data_set
local keys = requests[data_set]
if not keys then
return
end
function (data)
local data_set = data.data_set
local keys = requests[data_set]
if not keys then
return
end
local key = data.key
local callbacks = keys[key]
if not callbacks then
return
end
local key = data.key
local callbacks = keys[key]
if not callbacks then
return
end
keys[key] = nil
keys[key] = nil
for c, _ in next, callbacks do
local func = Token.get(c)
func(data)
for c, _ in next, callbacks do
local func = Token.get(c)
func(data)
end
end
end
)
)
--- Gets data from the web server's persistent data storage.
-- The callback is passed a table {data_set: string, key: string, value: any}.
@@ -827,7 +831,7 @@ local function cancel_try_get_data(data_set, key, callback_token)
callbacks[callback_token] = nil
local func = Token.get(callback_token)
local data = {data_set = data_set, key = key, cancelled = true}
local data = { data_set = data_set, key = key, cancelled = true }
func(data)
return true
@@ -851,10 +855,10 @@ end
local timeout_token =
Token.register(
function(data)
cancel_try_get_data(data.data_set, data.key, data.callback_token)
end
)
function (data)
cancel_try_get_data(data.data_set, data.key, data.callback_token)
end
)
--- Same as Server.try_get_data but the request is cancelled if the timeout expires before the request is complete.
-- If the request is cancelled before it is complete the callback will be called with data.cancelled = true.
@@ -892,7 +896,7 @@ function Public.try_get_data_timeout(data_set, key, callback_token, timeout_tick
try_get_data_cancelable(data_set, key, callback_token)
Task.set_timeout_in_ticks(timeout_ticks, timeout_token, {data_set = data_set, key = key, callback_token = callback_token})
Task.set_timeout_in_ticks(timeout_ticks, timeout_token, { data_set = data_set, key = key, callback_token = callback_token })
end
--- Gets all the data for the data_set from the web server's persistent data storage.
@@ -925,7 +929,7 @@ function Public.try_get_all_data(data_set, callback_token)
data_set = double_escape(data_set)
local message = concat {data_get_all_tag, callback_token, ' {', 'data_set:"', data_set, '"}'}
local message = concat { data_get_all_tag, callback_token, ' {', 'data_set:"', data_set, '"}' }
output_data(message)
end
@@ -1022,7 +1026,7 @@ function Public.on_data_set_changed(data_set, handler)
local handlers = data_set_handlers[data_set]
if handlers == nil then
handlers = {handler}
handlers = { handler }
data_set_handlers[data_set] = handlers
else
handlers[#handlers + 1] = handler
@@ -1051,7 +1055,7 @@ function Public.on_scenario_changed(scenario, handler)
local handlers = scenario_handlers[scenario]
if handlers == nil then
handlers = {handler}
handlers = { handler }
scenario_handlers[scenario] = handlers
else
handlers[#handlers + 1] = handler
@@ -1072,7 +1076,7 @@ Public.log_antigrief_data = log_antigrief_data
--- Called by the web server to determine which data_sets are being tracked.
function Public.get_tracked_data_sets()
local message = {data_tracked_tag, '['}
local message = { data_tracked_tag, '[' }
for k, _ in pairs(data_set_handlers) do
k = double_escape(k)
@@ -1096,7 +1100,7 @@ end
--- Called by the web server to determine which scenarios is being tracked.
function Public.get_tracked_scenario()
local message = {scenario_tag, ''}
local message = { scenario_tag, '' }
for k, _ in pairs(scenario_handlers) do
k = double_escape(k)
@@ -1245,7 +1249,7 @@ function Public.ban_sync(username, reason, admin)
reason = escape(reason)
admin = escape(admin)
local message = concat({ban_sync_tag, '{username:"', username, '",reason:"', reason, '",admin:"', admin, '"}'})
local message = concat({ ban_sync_tag, '{username:"', username, '",reason:"', reason, '",admin:"', admin, '"}' })
output_data(message)
end
@@ -1283,7 +1287,7 @@ function Public.unban_sync(username, admin)
username = escape(username)
admin = escape(admin)
local message = concat({unbanned_sync_tag, '{username:"', username, '",admin:"', admin, '"}'})
local message = concat({ unbanned_sync_tag, '{username:"', username, '",admin:"', admin, '"}' })
output_data(message)
end
@@ -1401,7 +1405,7 @@ function Public.get_current_date(pretty, as_table, current_time)
end
if as_table then
return {year = date.year, month = date.month, day = date.day}
return { year = date.year, month = date.month, day = date.day }
elseif pretty then
return date.year .. '-' .. date.month .. '-' .. date.day
else
@@ -1452,7 +1456,7 @@ end
--- Called by the web server to re sync which players are online.
function Public.query_online_players()
local message = {query_players_tag, '['}
local message = { query_players_tag, '[' }
for _, p in ipairs(game.connected_players) do
message[#message + 1] = '"'
@@ -1504,6 +1508,7 @@ local function command_handler(callback, ...)
local success, err = pcall(callback, ...)
return success, err
else
---@diagnostic disable-next-line: deprecated, param-type-mismatch
local success, err = pcall(loadstring(callback), ...)
return success, err
end
@@ -1513,8 +1518,8 @@ end
-- Doing this, enables achievements and the web-panel can communicate without any interruptions.
commands.add_command(
'cc',
'Evaluate command',
function(cmd)
'<callback> - Evaluate command',
function (cmd)
local player = game.player
if player then
return
@@ -1544,7 +1549,7 @@ commands.add_command(
-- players joining or leaving. So we send our own [PLAYER-JOIN] and [PLAYER-LEAVE] tags.
Event.add(
defines.events.on_player_joined_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -1575,7 +1580,7 @@ local leave_reason_map = {
Event.add(
defines.events.on_player_left_game,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player then
return
@@ -1593,7 +1598,7 @@ Event.add(
Event.add(
defines.events.on_player_died,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
@@ -1607,7 +1612,7 @@ Event.add(
local cause = event.cause
local message = {discord_bold_tag, player.name}
local message = { discord_bold_tag, player.name }
if cause and cause.valid then
message[#message + 1] = ' was killed by '
@@ -1628,5 +1633,6 @@ Event.add(
)
Public.build_embed_data = build_embed_data
Public.output_data = output_data
return Public

52
utils/start.lua Normal file
View File

@@ -0,0 +1,52 @@
local Event = require 'utils.event'
local Public = {}
local bp =
'0eNqlm91O20AUhN9lrx2UM7b3J69SocrAUiwlTuQYKEV59yYEF1RXqWe4QiE7Xud82fXq08mru1k/5l3fdoNbvbr2dtvt3erbq9u3P7pmffrf8LLLbuXaIW9c4bpmc3q1bze7dV7kbmiHl8VzOzwsts9d7t2hcG13l3+6lR2uC/c2oM3na55Hf+8eNzfHkSv7/9UKt9vujxfYdqc7OV4UV3XhXo5/y6v6ONVd2+fb89u+cE9N3zbnV3YoJvNBmS99YcLyCx+wNH6+6isf8P8THnEO7fqd5d+XeS/S4c8t9Pm+7fLd4viNuu3zkN3phv+dqqRULaX8R2rG6ECNjtTopNx/uZRSxqVKiWYp0SwnXPbDtsuLXTM8XBgfyPGRHJ+48Z+5zBpPEqkkItVkpVy+t2rC4qH51fQfkyzW+X64kAxyMqrJ+ZWvpMrXUuXryVq4fG/1hNTcKtTkeqgn329upvn1rqV6e6nenqy3l+vtyf3Kk3w8uV95macneXqJZ5B4BpJnkHkGkmcgeQaSZ5B5BpJnkHhGiWckeUbyyRVJipGkGEmKkTxFRJJdlNgliV0i2SX5FJHkU0SSTxGJrHySKm9LqfRjbHbtx4CwEY7RwM6V5LnmV30MsGU3rezGlt30shu5dY2BwAYiG0jypyHAmgZWEw4GFix0sGA5QS872LJrYsA0M2AlW/ZSfoZYKT9ErJSfIsZqANM8gGkiYIzNB8CqA6vYbaxil0fFbmMVeQgz1iiYphRMcwrGSgXTrcIY9Xo06NGoR5McJbBrZsOmamPO8Pm4dalhrNUwVmsY6zXMs6uX9Rk2FRoXeQQOH6swLLBbbtDXKGsxjNUYFlh8rL6wwOGLHD7WWFjUVx9rL4zVF8b6C2MFhrEGwyKHT3MXxsqLMaBg1MWH6ebDdPUxRpMcJXBr3gSaNwHrTbAkN98x4NlAYAORDSQyMB8iNAsDzcKAtTDQLQxMXrswee3C5LUL3dGAdTTQHA3EphDW0UB3NAC7iqHDBrs8WakDTepAkzpgpc4YUDixXSLQLRDYjhGwLSNgZRE0WQRNFoGVRWBlEVhZBFYWgZVFYGURWFkETRZBk0VgZRF0WQRdFkGXRahZxLoiAquIoCkiaN0vYFURPLtiWUEEr4NlVRH0Hhiw0ghaFwy0NhiwEgl6Iwx0nYSgww76EVhvlQErm6A1y0DrlgErn8D2y4BVTmCVE1jlBFY5gVVO0LpmoKknJK27PWnt7Ynrb09cg3viOtyT1uKetB73OWrpujj/gmX16QcvhXvK/f7tQohWhYQQfVqWy+pw+A3SPoD5'
function Public.blueprint(surface)
local position = {x = 0, y = 0}
if not surface or not surface.valid then
return
end
local item = surface.create_entity {name = 'item-on-ground', position = position, stack = {name = 'blueprint', count = 1}}
if not item then
return
end
local success = item.stack.import_stack(bp)
if success <= 0 then
local ghosts = item.stack.build_blueprint {surface = surface, force = 'player', position = position, force_build = true}
for _, ghost in pairs(ghosts) do
local _, ent = ghost.silent_revive({raise_revive = true})
if ent and ent.valid then
ent.destructible = false
ent.minable = false
end
end
end
if item.valid then
item.destroy()
end
end
Event.add(
defines.events.on_player_created,
function(event)
if event.player_index ~= 1 then
return
end
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
end
Public.blueprint(player.surface)
end
)
return Public

View File

@@ -2,7 +2,6 @@
local Token = require 'utils.token'
local Task = require 'utils.task'
local Alert = require 'utils.alert'
local Public = {}
@@ -19,39 +18,4 @@ Public.set_queue_speed = Task.set_queue_speed
Public.delay = Task.queue_task
Public.priority_delay = Task.set_timeout_in_ticks
local delay_print_alert_token =
Token.register(
function(event)
local text = event.text
if not text then
return
end
local ttl = event.ttl
if not ttl then
ttl = 60
end
local sprite = event.sprite
local color = event.color
Alert.alert_all_players(ttl, text, color, sprite, 1)
end
)
Public.set_timeout_in_ticks_alert = function(delay, data)
if not data then
return error('Data was not provided', 2)
end
if type(data) ~= 'table' then
return error("Data must be of type 'table'", 2)
end
if not delay then
return error('No delay was provided', 2)
end
Task.set_timeout_in_ticks(delay, delay_print_alert_token, data)
end
return Public

View File

@@ -0,0 +1,2 @@
require 'utils.start'
require 'utils.freeplay'.set('disabled', false)