Merge branch 'dev' into fix/autofill

This commit is contained in:
Cooldude2606
2023-03-07 21:11:26 +00:00
committed by GitHub
152 changed files with 4311 additions and 273 deletions

View File

@@ -4,7 +4,7 @@
local Event = require 'utils.event' --- @dep utils.event
local Global = require 'utils.global' --- @dep utils.global
local config = require 'config.death_logger' --- @dep config.death_logger
local format_time, move_items = _C.format_time, _C.move_items --- @dep expcore.common
local format_time, move_items = _C.format_time, _C.move_items_stack --- @dep expcore.common
-- Max amount of ticks a corpse can be alive
local corpse_lifetime = 60*60*15
@@ -64,7 +64,7 @@ Event.add(defines.events.on_player_died, function(event)
local player = game.players[event.player_index]
local corpse = player.surface.find_entity('character-corpse', player.position)
if config.use_chests_as_bodies then
local items = corpse.get_inventory(defines.inventory.character_corpse).get_contents()
local items = corpse.get_inventory(defines.inventory.character_corpse)
local chest = move_items(items, corpse.surface, corpse.position)
chest.destructible = false
corpse.destroy()
@@ -140,7 +140,7 @@ end
if config.auto_collect_bodies then
Event.add(defines.events.on_character_corpse_expired, function(event)
local corpse = event.corpse
local items = corpse.get_inventory(defines.inventory.character_corpse).get_contents()
local items = corpse.get_inventory(defines.inventory.character_corpse)
move_items(items, corpse.surface, {x=0, y=0})
end)
end

View File

@@ -0,0 +1,89 @@
--- Log certain actions into a file when events are triggered
-- @addon Deconlog
local Event = require 'utils.event' --- @dep utils.event
local Roles = require 'expcore.roles' --- @dep expcore.roles
local format_time = _C.format_time
local config = require 'config.deconlog' --- @dep config.deconlog
local filepath = "log/decon.log"
local function add_log(data)
game.write_file(filepath, data .. "\n", true, 0) -- write data
end
local function get_secs ()
return format_time(game.tick, { hours = true, minutes = true, seconds = true, string = true })
end
local function pos_tostring (pos)
return tostring(pos.x) .. "," .. tostring(pos.y)
end
Event.on_init(function()
game.write_file(filepath, "\n", false, 0) -- write data
end)
if config.decon_area then
Event.add(defines.events.on_player_deconstructed_area, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
add_log(get_secs() .. "," .. player.name .. ",decon_area," .. pos_tostring(e.area.left_top) .. "," .. pos_tostring(e.area.right_bottom))
end)
end
if config.built_entity then
Event.add(defines.events.on_built_entity, function (e)
if not e.player_index then return end
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
local ent = e.created_entity
add_log(get_secs() .. "," .. player.name .. ",built_entity," .. ent.name .. "," .. pos_tostring(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
end
if config.mined_entity then
Event.add(defines.events.on_player_mined_entity, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
local ent = e.entity
add_log(get_secs() .. "," .. player.name .. ",mined_entity," .. ent.name .. "," .. pos_tostring(ent.position) .. "," .. tostring(ent.direction) .. "," .. tostring(ent.orientation))
end)
end
if config.fired_rocket then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then return end
if item.name == "rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-rocket," .. pos_tostring(player.position) .. "," .. pos_tostring(player.shooting_state.position))
end
end)
end
if config.fired_explosive_rocket then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then return end
if item.name == "explosive-rocket" then
add_log(get_secs() .. "," .. player.name .. ",shot-explosive-rocket," .. pos_tostring(player.position) .. "," .. pos_tostring(player.shooting_state.position))
end
end)
end
if config.fired_nuke then
Event.add(defines.events.on_player_ammo_inventory_changed, function (e)
local player = game.get_player(e.player_index)
if Roles.player_has_flag(player, "deconlog-bypass") then return end
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
local item = ammo_inv[player.character.selected_gun_index]
if not item or not item.valid or not item.valid_for_read then return end
if item.name == "atomic-bomb" then
add_log(get_secs() .. "," .. player.name .. ",shot-nuke," .. pos_tostring(player.position) .. "," .. pos_tostring(player.shooting_state.position))
end
end)
end

19
modules/addons/fagc.lua Normal file
View File

@@ -0,0 +1,19 @@
--- Allows the FAGC clientside bot to receive information about bans and unbans and propagate that information to other servers
-- @addon FAGC
local Event = require 'utils.event' --- @dep utils.event
-- Clear the file on startup to minimize its size
Event.on_init(function()
game.write_file("fagc-actions.txt", "", false, 0)
end)
Event.add(defines.events.on_player_banned, function(e)
local text = "ban;" .. e.player_name .. ";" .. (e.by_player or "") .. ";" .. (e.reason or "") .. "\n"
game.write_file("fagc-actions.txt", text, true, 0)
end)
Event.add(defines.events.on_player_unbanned, function(e)
local text = "unban;" .. e.player_name .. ";" .. (e.by_player or "") .. ";" .. (e.reason or "") .. "\n"
game.write_file("fagc-actions.txt", text, true, 0)
end)

View File

@@ -3,13 +3,13 @@
local Event = require 'utils.event' --- @dep utils.event
local events = require 'config.inventory_clear' --- @dep config.inventory_clear
local move_items = _C.move_items --- @dep expcore.common
local move_items_stack = _C.move_items_stack --- @dep expcore.common
local function clear_items(event)
local player = game.players[event.player_index]
local inv = player.get_main_inventory()
move_items(inv.get_contents())
move_items_stack(inv)
inv.clear()
end
for _, event_name in ipairs(events) do Event.add(event_name, clear_items) end
for _, event_name in ipairs(events) do Event.add(event_name, clear_items) end

View File

@@ -0,0 +1,36 @@
--- Disable new players from having certain items in their inventory, most commonly nukes
-- @addon Nukeprotect
local Event = require 'utils.event' --- @dep utils.event
local Roles = require 'expcore.roles' --- @dep expcore.roles
local config = require 'config.nukeprotect' --- @dep config.nukeprotect
local move_items_stack = _C.move_items_stack --- @dep expcore.common
local function check_items(player, type)
-- if the player has perms to be ignored, then they should be
if config.ignore_permisison and Roles.player_allowed(player, config.ignore_permisison) then return end
-- if the players
if config.ignore_admins and player.admin then return end
local inventory = player.get_inventory(type)
for i = 1, #inventory do
local item = inventory[i]
if item.valid and item.valid_for_read and config[tostring(type)][item.name] then
player.print({ "nukeprotect.found", { "item-name." .. item.name } })
-- insert the items into the table so all items are transferred at once
move_items_stack({ item })
end
end
end
for _, inventory in ipairs(config.inventories) do
if #inventory.items > 0 then
Event.add(inventory.event, function(event)
local player = game.get_player(event.player_index)
if player and player.valid then
check_items(player, inventory.inventory)
end
end)
end
end

View File

@@ -4,6 +4,8 @@
local Event = require 'utils.event' --- @dep utils.event
local Global = require 'utils.global' --- @dep utils.global
local Roles = require 'expcore.roles' --- @dep expcore.roles
local Gui = require 'expcore.gui' --- @dep expcore.gui
local PlayerData = require 'expcore.player_data' --- @dep expcore.player_data
-- Global queue used to store trees that need to be removed, also chache for player roles
local chache = {}
@@ -13,6 +15,22 @@ Global.register({ tree_queue, chache }, function(tbl)
chache = tbl[2]
end)
-- Left menu button to toggle between fast decon and normal decon marking
local HasEnabledDecon = PlayerData.Settings:combine('HasEnabledDecon')
HasEnabledDecon:set_default(false)
Gui.toolbar_button("entity/tree-01", {'tree-decon.main-tooltip'}, function (player)
return Roles.player_allowed(player, "fast-tree-decon")
end)
:on_click(function(player, element)
local status = HasEnabledDecon:get(player)
HasEnabledDecon:set(player, not status)
Gui.toolbar_button_style(element, not status)
player.print(status and {'tree-decon.toggle-msg', {'tree-decon.disabled'}} or {'tree-decon.toggle-msg', {'tree-decon.enabled'}})
end)
-- Add trees to queue when marked, only allows simple entities and for players with role permission
Event.add(defines.events.on_marked_for_deconstruction, function(event)
-- Check which type of decon a player is allowed
@@ -40,6 +58,10 @@ Event.add(defines.events.on_marked_for_deconstruction, function(event)
-- Allowed to decon this entity, but not fast
if allow ~= 'fast' then return end
local player = game.get_player(index)
if not HasEnabledDecon:get(player) then return end
-- Allowed fast decon on this entity, just trees
local head = tree_queue._head + 1
if not last_user and entity.type ~= 'cliff' then

View File

@@ -4,7 +4,7 @@
]]
local Commands = require 'expcore.commands' --- @dep expcore.commands
local move_items = _C.move_items --- @dep expcore.common
local move_items_stack = _C.move_items_stack --- @dep expcore.common
require 'config.expcore.command_role_parse'
--- Clears a players inventory
@@ -14,10 +14,10 @@ Commands.new_command('clear-inventory', 'Clears a players inventory')
:add_param('player', false, 'player-role')
:add_alias('clear-inv', 'move-inventory', 'move-inv')
:register(function(_, player)
local inv = player.get_main_inventory()
if not inv then
return Commands.error{'expcore-commands.reject-player-alive'}
end
move_items(inv.get_contents())
inv.clear()
end)
local inv = player.get_main_inventory()
if not inv then
return Commands.error{'expcore-commands.reject-player-alive'}
end
move_items_stack(inv)
inv.clear()
end)

View File

@@ -18,7 +18,6 @@
local Roles = require 'expcore.roles' --- @dep expcore.roles
local Game = require 'utils.game' --- @dep utils.game
local Global = require 'utils.global' --- @dep utils.global
local valid_player = Game.get_player_from_any
local assign_roles = Roles.assign_player
@@ -43,12 +42,6 @@ local Jail = {
}
}
local old_roles = Jail.old_roles
Global.register(old_roles, function(tbl)
Jail.old_roles = tbl
old_roles = tbl
end)
--- Used to emit the jail related events
-- @tparam number event the name of the event that will be emited
-- @tparam LuaPlayer player the player who is being acted on
@@ -89,7 +82,6 @@ function Jail.jail_player(player, by_player_name, reason)
if has_role(player, 'Jail') then return end
local roles = get_roles(player)
old_roles[player.name] = roles
player.walking_state = { walking = false }
player.riding_state = { acceleration = defines.riding.acceleration.nothing, direction = player.riding_state.direction }
@@ -98,8 +90,9 @@ function Jail.jail_player(player, by_player_name, reason)
player.picking_state = false
player.repair_state = { repairing = false }
assign_roles(player, 'Jail', by_player_name, nil, true)
unassign_roles(player, roles, by_player_name, nil, true)
assign_roles(player, 'Jail', by_player_name, nil, true)
assign_roles(player, roles, by_player_name, nil, true)
event_emit(Jail.events.on_player_jailed, player, by_player_name, reason)
@@ -116,9 +109,7 @@ function Jail.unjail_player(player, by_player_name)
if not by_player_name then return end
if not has_role(player, 'Jail') then return end
local roles = old_roles[player.name] or {}
assign_roles(player, roles, by_player_name, nil, true)
unassign_roles(player, 'Jail', by_player_name, nil, true)
event_emit(Jail.events.on_player_unjailed, player, by_player_name)
@@ -126,4 +117,4 @@ function Jail.unjail_player(player, by_player_name)
return true
end
return Jail
return Jail

View File

@@ -0,0 +1,190 @@
local Event = require("utils.event")
local general = require("modules.graftorio.general")
local config = require("config.graftorio")
local lib = {}
lib.collect_production = function()
for _, force in pairs(game.forces) do
---@class ProductionStatistics
---@field item_input table<string, double|uint64>
---@field item_output table<string, double|uint64>
---@field fluid_input table<string, double|uint64>
---@field fluid_output table<string, double|uint64>
---@field kill_input table<string, double|uint64>
---@field kill_output table<string, double|uint64>
---@field build_input table<string, double|uint64>
---@field build_output table<string, double|uint64>
local stats = {
item_input = {},
item_output = {},
fluid_input = {},
fluid_output = {},
kill_input = {},
kill_output = {},
build_input = {},
build_output = {},
}
for name, count in pairs(force.item_production_statistics.input_counts) do
local itemstats = stats.item_input[name] or {}
itemstats.count = count
stats.item_input[name] = itemstats
end
for name, count in pairs(force.item_production_statistics.output_counts) do
local itemstats = stats.item_output[name] or {}
itemstats.count = count
stats.item_output[name] = itemstats
end
for name, count in pairs(force.fluid_production_statistics.input_counts) do
local fluidstats = stats.fluid_input[name] or {}
fluidstats.count = count
stats.fluid_input[name] = fluidstats
end
for name, count in pairs(force.fluid_production_statistics.output_counts) do
local fluidstats = stats.fluid_output[name] or {}
fluidstats.count = count
stats.fluid_output[name] = fluidstats
end
for name, count in pairs(force.kill_count_statistics.input_counts) do
local killstats = stats.kill_input[name] or {}
killstats.count = count
stats.kill_input[name] = killstats
end
for name, count in pairs(force.kill_count_statistics.output_counts) do
local killstats = stats.kill_output[name] or {}
killstats.count = count
stats.kill_output[name] = killstats
end
for name, count in pairs(force.entity_build_count_statistics.input_counts) do
local buildstats = stats.build_input[name] or {}
buildstats.count = count
stats.build_input[name] = buildstats
end
for name, count in pairs(force.entity_build_count_statistics.output_counts) do
local buildstats = stats.build_output[name] or {}
buildstats.count = count
stats.build_output[name] = buildstats
end
general.data.output[force.name].production = stats
end
end
lib.collect_loginet = function()
for _, force in pairs(game.forces) do
---@class RobotStatistics
---@field all_construction_robots uint
---@field available_construction_robot uint
---@field all_logistic_robots uint
---@field available_logistic_robots uint
---@field charging_robot_count uint
---@field to_charge_robot_count uint
---@field items table<string, uint>
---@field pickups table<string, uint>
---@field deliveries table<string, uint>
local stats = {
all_construction_robots = 0,
available_construction_robots = 0,
all_logistic_robots = 0,
available_logistic_robots = 0,
charging_robot_count = 0,
to_charge_robot_count = 0,
items = {},
pickups = {},
deliveries = {},
}
for _, networks in pairs(force.logistic_networks) do
for _, network in pairs(networks) do
stats.available_construction_robots = network.available_construction_robots
stats.all_construction_robots = network.all_construction_robots
stats.available_logistic_robots = network.available_logistic_robots
stats.all_logistic_robots = network.all_logistic_robots
stats.charging_robot_count = 0
stats.to_charge_robot_count = 0
for _, cell in pairs(network.cells) do
stats.charging_robot_count = (stats.charging_robot_count) + cell.charging_robot_count
stats.to_charge_robot_count = (stats.to_charge_robot_count) + cell.to_charge_robot_count
end
if config.modules.logistorage then
for name, v in pairs(network.get_contents()) do
stats.items[name] = (stats.items[name] or 0) + v
end
-- pickups and deliveries of items
for _, point_list in pairs({ network.provider_points, network.requester_points, network.storage_points }) do
for _, point in pairs(point_list) do
for name, qty in pairs(point.targeted_items_pickup) do
stats.pickups[name] = (stats.pickups[name] or 0) + qty
end
for name, qty in pairs(point.targeted_items_deliver) do
stats.deliveries[name] = (stats.deliveries[name] or 0) + qty
end
end
end
end
end
end
general.data.output[force.name].robots = stats
end
end
---@class ResearchStatistics
---@field current Research
---@field queue Research[]
---@class Research
---@field name string
---@field level uint
---@field progress double
Event.add(defines.events.on_research_finished, function(evt)
local research = evt.research
if not general.data.output[research.force.name] then general.data.output[research.force.name] = {} end
if not general.data.output[research.force.name].research then general.data.output[research.force.name].research = {} end
local force_research = general.data.output[research.force.name].research or {}
table.remove(force_research, 1)
general.data.output[research.force.name].research = force_research
end)
Event.add(defines.events.on_research_started, function(evt)
-- move queue up
local research = evt.research
if not general.data.output[research.force.name].research then general.data.output[research.force.name].research = {} end
local force_research = general.data.output[research.force.name].research or {}
table.remove(force_research, 1)
general.data.output[research.force.name].research = force_research
end)
Event.on_nth_tick(60, function()
for _, force in pairs(game.forces) do
if not general.data.output[force.name].research then general.data.output[force.name].research = {} end
local force_research = {}
-- this works even if the queue is disabled, but it will always be just 1 long in that case
for _, research in pairs(force.research_queue) do
table.insert(force_research, {
name = research.name,
level = research.level,
progress = force.get_saved_technology_progress(research) or 0,
})
end
general.data.output[force.name].research = force_research
end
end)
return lib

View File

@@ -0,0 +1,65 @@
local Event = require("utils.event")
local Global = require("utils.global")
local lib = {}
lib.data = {
output = {}
}
Global.register(lib.data, function(tbl)
lib.data = tbl
end)
---@class Statistics
---@field trains TrainStatistics
---@field power PowerStatistics
---@field production ProductionStatistics
---@field robots RobotStatistics
---@field other OtherStatistics
Event.on_init(function()
---@type table<string, Statistics>
lib.data.output = {}
for _, force in pairs(game.forces) do
lib.data.output[force.name] = {}
end
end)
---@class OtherStatistics
---@field tick uint
---@field evolution EvolutionStatistics
---@field research ResearchStatistics
---@class EvolutionStatistics
---@field evolution_factor double
---@field evolution_factor_by_pollution double
---@field evolution_factor_by_time double
---@field evolution_factor_by_killing_spawners double
lib.collect_other = function()
for _, force in pairs(game.forces) do
---@type OtherStatistics
local other = lib.data.output[force.name].other or {}
other.evolution = {
evolution_factor = force.evolution_factor,
evolution_factor_by_pollution = force.evolution_factor_by_pollution,
evolution_factor_by_time = force.evolution_factor_by_time,
evolution_factor_by_killing_spawners = force.evolution_factor_by_killing_spawners
}
for k, v in pairs(other) do
lib.data.output[force.name].other[k] = v
end
end
end
Event.add(defines.events.on_force_created, function(evt)
lib.data.output[evt.force.name] = {}
end)
Event.add(defines.events.on_forces_merged, function(evt)
lib.data.output[evt.source_name] = nil
end)
return lib

View File

@@ -0,0 +1,26 @@
local Commands = require("expcore.commands")
local config = require("config.graftorio")
local statics = require("modules.graftorio.statics")
local forcestats = nil
local general = nil
if config.modules.forcestats then
forcestats = require("modules.graftorio.forcestats")
end
if config.modules.general then
general = require("modules.graftorio.general")
end
Commands.new_command("collectdata", "Collect data for RCON usage")
:add_param("location", true)
:register(function()
-- this must be first as it overwrites the stats
-- also makes the .other table for all forces
statics.collect_statics()
if config.modules.general then general.collect_other() end
if config.modules.forcestats then
forcestats.collect_production()
forcestats.collect_loginet()
end
rcon.print(game.table_to_json(general.data.output))
return Commands.success()
end)

View File

@@ -0,0 +1,35 @@
local general = require("modules.graftorio.general")
local lib = {}
---@class StaticStatistics
---@field tick uint
---@field online_players string[]
---@field mods table<string, string>
---@field seed table<string, uint>
lib.collect_statics = function()
local stats = {}
stats.tick = game.tick
stats.online_players = {}
for _, player in pairs(game.connected_players) do
table.insert(stats.online_players, player.name)
end
stats.mods = {}
for name, version in pairs(game.active_mods) do
stats.mods[name] = version
end
-- reason behind this is that the map gen settings can be changed during runtime so just get them fresh
stats.seed = {}
for _, surface in pairs(game.surfaces) do
stats.seed[surface.name] = surface.map_gen_settings.seed
end
for _, force in pairs(game.forces) do
general.data.output[force.name].other = stats
end
end
return lib

View File

@@ -183,7 +183,7 @@ end)
if not value then value = 0 end
local clamped = math.clamp(value, 0, 1000)
local item_name = element.parent.tooltip
local entity_name = element.parent.parent.parent.parent.name
local entity_name = element.parent.parent.parent.name
if not autofill_player_settings[player.name] then return end
local setting = autofill_player_settings[player.name][entity_name]
if not setting then return end

View File

@@ -764,8 +764,8 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing), function()
end
-- Check if the force has any warps
local closest_warp
local closest_distance
local closest_warp = nil
local closest_distance = nil
if #warp_ids > 0 then
local surface = player.surface
local pos = player.position
@@ -794,7 +794,7 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing), function()
end
-- Check the dist to the closest warp
local in_range = closest_warp.warp_id == warp_ids.spawn and closest_distance < rs2 or closest_distance < r2
local in_range = closest_warp ~= nil and (closest_warp.warp_id == warp_ids.spawn and closest_distance < rs2 or closest_distance < r2)
if was_in_range and not in_range then
PlayerInRange:set(player, nil)
elseif not was_in_range and in_range then
@@ -804,17 +804,16 @@ Event.on_nth_tick(math.floor(60/config.update_smoothing), function()
-- Change the enabled state of the add warp button
local frame = Gui.get_left_element(player, warp_list_container)
local add_warp_element = frame.container.header.alignment[add_new_warp.name]
local old_closest_warp_name = add_warp_element.tooltip[2] or closest_warp.name
local old_closest_warp_name = add_warp_element.tooltip[2] or closest_warp and closest_warp.name
local was_able_to_make_warp = add_warp_element.enabled
local can_make_warp = closest_distance > mr2
local can_make_warp = closest_distance == nil or closest_distance > mr2
if can_make_warp and not was_able_to_make_warp then
add_warp_element.enabled = true
add_warp_element.tooltip = {'warp-list.add-tooltip'}
elseif not can_make_warp and was_able_to_make_warp or old_closest_warp_name ~= closest_warp.name then
elseif not can_make_warp and was_able_to_make_warp or closest_warp and (old_closest_warp_name ~= closest_warp.name) then
add_warp_element.enabled = false
add_warp_element.tooltip = {'warp-list.too-close', closest_warp.name}
end
end
end