Skip to content

Instantly share code, notes, and snippets.

@Nebual
Created April 30, 2024 08:42
Show Gist options
  • Save Nebual/dac57f09552b6af41f21f0341c223a3f to your computer and use it in GitHub Desktop.
Save Nebual/dac57f09552b6af41f21f0341c223a3f to your computer and use it in GitHub Desktop.
Factorio mod patch: Logistic network statistics
--drones_analytics
--control.lua
if script.active_mods["gvv"] then
require("__gvv__.gvv")()
end
--@
local function print(s)
local DEBUG = false
if DEBUG then
game.print(math.random(10000, 99999) .. " " .. s)
--game.print(s)
end
end
--@
local function print_table(t, name)
local count = 0
if name then
game.print(" ╒ " .. name:upper() .. ":")
else
game.print("╒ TABLE:")
end
for key, value in pairs(t) do
game.print(
"├ " .. tostring(key) .. " [" .. type(key) .. "] : " .. tostring(value) .. " [" .. type(value) .. "]"
)
count = count + 1
end
game.print("╘ count: " .. count)
end
function tprint(tbl, indent)
if not indent then
indent = 0
end
local toprint = string.rep(" ", indent) .. "{\r\n"
indent = indent + 2
for k, v in pairs(tbl) do
toprint = toprint .. string.rep(" ", indent)
if (type(k) == "number") then
toprint = toprint .. "[" .. k .. "] = "
elseif (type(k) == "string") then
toprint = toprint .. k .. "= "
end
if (type(v) == "number") then
toprint = toprint .. v .. ",\r\n"
elseif (type(v) == "string") then
toprint = toprint .. '"' .. v .. '",\r\n'
elseif (type(v) == "table") then
toprint = toprint .. tprint(v, indent + 2) .. ",\r\n"
else
toprint = toprint .. '"' .. tostring(v) .. '",\r\n'
end
end
toprint = toprint .. string.rep(" ", indent - 2) .. "}"
return toprint
end
local invtype_robot_cargo = defines.inventory.robot_cargo
local function scan(scan_data)
--print("scan start")
-- все боты на поверхности
--print_table(game.surfaces[1].find_entities_filtered{type="logistic-robot"})
local scanned_items = scan_data.items
for key, ent in pairs(scan_data.surface.find_entities_filtered {type = "logistic-robot"}) do
local robot_inventory = ent.get_inventory(invtype_robot_cargo)
if not robot_inventory.is_empty() then
local contents = robot_inventory.get_contents()
for inv_name, inv_value in pairs(contents) do
--print(inv_name .. ' --- '.. tostring(inv_value))
--print('[img=item.' .. inv_name .. '] ' .. inv_name .. ' --- '.. tostring(inv_value))
if scanned_items[inv_name] ~= nil then
scanned_items[inv_name] = scanned_items[inv_name] + 1
else
scanned_items[inv_name] = 1
end
end
end
end
end
local function print_stat(scan_data)
print("print_stat")
local player = scan_data.player
if player == nil then return end
--сделать таблицу {{name, n},{name, n}}
local _sorted_table = {}
for key, value in pairs(scan_data.items) do
table.insert(_sorted_table, {key, value})
--print(key .. value .. type(value))
end
--отсортировать талицу
function compare(a, b)
return a[2] > b[2]
end
table.sort(_sorted_table, compare)
--печать таблицы
player.print(scan_data.surface.name .. " logistic bot trip load:")
for key, value in ipairs(_sorted_table) do
if key == 21 then
break
end
player.print(
{
"",
" " .. tostring(key) .. ". [img=item." .. value[1] .. "] ",
game.item_prototypes[value[1]].localised_name,
": " .. tostring(value[2])
}
)
end
end
local function run_scanner()
for scan_id, scan_data in pairs(global.scans) do
print("run_scanner scan_id: " .. tostring(scan_id) .. ", counter: " .. tostring(scan_data.timer_counter))
scan(scan_data)
scan_data.timer_counter = scan_data.timer_counter + 1
if scan_data.timer_counter >= global.timer_sec_max / global.timer_sec then
print("stop scan " .. tostring(scan_data.timer_counter))
print_stat(scan_data)
global.scans[scan_id] = nil
end
end
if next(global.scans) == nil then
script.on_nth_tick(global.timer_sec * 60, nil)
end
end
local function main_start(event)
if event.player_index == nil then return end
local player = game.get_player(event.player_index)
player.print(
"Logistic network statistics: scanning " .. player.surface.name .. ", " .. tostring(global.timer_sec_max / global.timer_sec) .. " samples, results in " .. tostring(global.timer_sec_max) .. "s"
)
local should_start_scan = next(global.scans) == nil
local key = tostring(event.player_index) .. "-" .. tostring(player.surface_index)
global.scans[key] = {}
global.scans[key].surface = player.surface
global.scans[key].player = player
global.scans[key].items = {}
global.scans[key].timer_counter = 0
if should_start_scan then
script.on_nth_tick(global.timer_sec * 60, run_scanner)
end
end
local function reload_mods()
game.reload_mods()
game.print("reload_mods")
end
script.on_init(
function()
global.scans = {}
global.timer_sec = 2 --sec
global.timer_sec_max = 10
global.timer_counter = 0
end
)
script.on_event(
defines.events.on_lua_shortcut,
function(event)
if event.prototype_name == "Logistic_network_statistics_shortcut" then
main_start(event)
end
end
)
commands.add_command("lnstat", nil, main_start)
commands.add_command(
"lntimer",
nil,
function(command)
if command.player_index == nil then return end
local player = game.get_player(command.player_index)
local param = tonumber(command.parameter)
if type(param) == "number" then
global.timer_sec = param
player.print("lnstat: timer_sec " .. tostring(global.timer_sec))
-- clear any running scans
script.on_nth_tick(global.timer_sec * 60, nil)
global.scans = {}
else
player.print("lnstat: command type err")
end
end
)
commands.add_command(
"lnmax",
nil,
function(command)
if command.player_index == nil then return end
local player = game.get_player(command.player_index)
local param = tonumber(command.parameter)
if type(param) == "number" then
global.timer_sec_max = param
player.print("lnstat: timer_sec_max " .. tostring(global.timer_sec_max))
else
player.print("lnstat: command type err")
end
end
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment