Private
Public Access
1
0
Files
lua-prometheus-exporter/train-stats.lua

186 lines
5.8 KiB
Lua

function ScanTrains()
storage.trains = {}
for _,train in pairs(game.train_manager.get_trains({})) do
storage.trains[train.id] = train
end
end
---comment Get the first locomotive in the front, if non, in the back, if none empty string
---@param train LuaTrain
function GetTrainName(train)
if train.locomotives.front_movers[1] then
return train.locomotives.front_movers[1].backer_name
else if train.locomotives.back_movers[1] then
return train.locomotives.back_movers[1].backer_name
end
end
return ""
end
function GetTrainPlayerKills()
local trainKills = {}
trainKills[#trainKills+1] = "---train-player-kills---"
---@type LuaTrain
for _, train in pairs(storage.trains ) do
for killedPlayerID,killedPlayerCount in pairs(train.killed_players) do
trainKills[#trainKills+1] = ("%s:%s:%s:%s:%d"):format(train.id,GetTrainName(train),killedPlayerID,game.players[killedPlayerID].name,killedPlayerCount)
end
end
return table.concat(trainKills,"\n")
end
function GetTrainTotalKills()
local trainKills = {}
trainKills[#trainKills+1] = "---train-total-kills---"
---@type LuaTrain
for _, train in pairs(storage.trains) do
trainKills[#trainKills+1] = ("%s:%s:%d"):format(train.id,GetTrainName(train),train.kill_count)
end
return table.concat(trainKills,"\n")
end
function GetTrainStates()
local trainsDriving = 0
local trainsWaiting = 0
local trainsProblems = 0
local trainsManual = 0
for _, train in pairs(storage.trains) do
if train.state == defines.train_state.wait_station
or train.state == defines.train_state.destination_full
or train.state == defines.train_state.no_schedule
then trainsWaiting = trainsWaiting + 1 end
if train.state == defines.train_state.on_the_path
or train.state == defines.train_state.arrive_signal
or train.state == defines.train_state.wait_signal
then trainsDriving = trainsDriving + 1 end
if train.state == defines.train_state.manual_control
or train.state == defines.train_state.manual_control_stop
then trainsManual = trainsManual + 1 end
if train.state == defines.train_state.no_path
then trainsProblems = trainsProblems + 1 end
end
return ("---trains-states---\n%d:%d:%d:%d"):format(trainsDriving,trainsManual,trainsProblems,trainsWaiting)
end
---@class trainStat
trainStat = {
lastInventory={},
currentInventory={},
lastState = 0,
lastStationUnitNumber = 0,
currentStationUnitNumber = 0,
totalCargoCount = 0,
totalCargo = {},
lastArrivalTime = 0,
currentArrivalTime = 0
}
---@param inv table[]
---@return table<string, table>
local function toLookup(inv)
local t = {}
for _, item in ipairs(inv) do
local key = item.name .. ":" .. (item.quality or 0) -- eindeutiger Key
t[key] = item.count
end
return t
end
---@param oldInv table[]
---@param newInv table[]
---@return table[]
local function inventoryDiff(oldInv, newInv)
local oldLookup = toLookup(oldInv)
local newLookup = toLookup(newInv)
local diff = {}
-- Items, die neu hinzugekommen oder verändert wurden
for key, newCount in pairs(newLookup) do
local oldCount = oldLookup[key] or 0
if newCount ~= oldCount then
local name, quality = key:match("([^:]+):([^:]+)")
table.insert(diff, {
name = name,
quality = tonumber(quality),
oldCount = oldCount,
newCount = newCount,
delta = newCount - oldCount
})
end
end
-- Items, die komplett entfernt wurden
for key, oldCount in pairs(oldLookup) do
if newLookup[key] == nil then
local name, quality = key:match("([^:]+):([^:]+)")
table.insert(diff, {
name = name,
quality = tonumber(quality),
oldCount = oldCount,
newCount = 0,
delta = -oldCount
})
end
end
return diff
end
function onTrainStateChange(event)
-- Train arrived at station, so we store current data
---@type LuaTrain
local train = event.train
local trainID = train.id
---@type trainStat
local stat = storage.trainStats[trainID] or {}
if event.train.state == defines.train_state.wait_station then
stat.lastStationUnitNumber = stat.currentStationUnitNumber
stat.lastInventory = stat.currentInventory
stat.lastArrivalTime = stat.currentArrivalTime
stat.currentStationUnitNumber = train.station.unit_number
stat.currentInventory = train.get_contents()
stat.currentArrivalTime = game.tick
if stat.currentInventory and stat.lastInventory then
--Get Total Cargo
for key, value in pairs(inventoryDiff(stat.lastInventory,stat.currentInventory)) do
stat.totalCargoCount = (stat.totalCargoCount or 0) + value.delta
end
end
storage.trainStats[trainID] = stat
end
--log("inEvent")
end
function GetTrainStatistics()
local trainParts = {}
trainParts[#trainParts+1] = "---train-total-statistics---\n"
for trainID, stat in pairs(storage.trainStats) do
trainParts[#trainParts+1] = ("%d:%s:%d"):format(trainID,GetTrainName(storage.trains[trainID]),stat.totalCargoCount)
end
return table.concat(trainParts,"\n")
end
function SendTrainStats()
if options.enableTrains then
ScanTrains()
local returnParts = {}
returnParts[#returnParts+1] = GetTrainPlayerKills()
returnParts[#returnParts+1] = GetTrainTotalKills()
returnParts[#returnParts+1] = GetTrainStates()
returnParts[#returnParts+1] = GetTrainStatistics()
helpers.send_udp(udpAddress,table.concat(returnParts,"\n"),serverIndex)
end
end