From f40e219a2e9f4f93ce9b3a080b35e954b08df1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Grie=C3=9Fhaber?= Date: Sun, 4 Jan 2026 01:37:25 +0100 Subject: [PATCH] Update version to 0.2.1, add player color retrieval, and enhance train trip statistics Performance improvments for power stats --- .vscode/settings.json | 2 +- control.lua | 2 ++ game-stats.lua | 11 ++++++ info.json | 2 +- logistic-network-stats.lua | 7 ++-- power-stats.lua | 25 ++++++++++---- research-stats.lua | 5 ++- train-stats.lua | 69 +++++++++++++++++++++++++++++++++++--- 8 files changed, 108 insertions(+), 15 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7faf9ba..e72654f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "Lua.workspace.userThirdParty": [ - "c:\\Users\\jangr\\AppData\\Roaming\\Code\\User\\workspaceStorage\\d5b7556f3ceaa76c3801170429d1766d\\justarandomgeek.factoriomod-debug\\sumneko-3rd" + "c:\\Users\\jangr\\AppData\\Roaming\\Code\\User\\workspaceStorage\\f0146bacf23a7548830b73867851c66a\\justarandomgeek.factoriomod-debug\\sumneko-3rd" ], "Lua.workspace.checkThirdParty": "ApplyInMemory", "factorio.versions": [ diff --git a/control.lua b/control.lua index 00dc56a..e76b970 100644 --- a/control.lua +++ b/control.lua @@ -44,6 +44,7 @@ script.on_init(function () storage.constructedEntites = {} storage.deconstructedEntities = {} storage.trainStats = {} + storage.networkCache = {} ---@type LuaTrain[] storage.trains = {} @@ -102,6 +103,7 @@ script.on_configuration_changed(function() storage.playerDeathCause = storage.playerDeathCause or {} storage.constructedEntites = storage.constructedEntites or {} storage.deconstructedEntities = storage.deconstructedEntities or{} + storage.networkCache =storage.networkCache or {} storage.trains = storage.trains or {} ---@type table storage.trainStats = storage.trainStats or {} diff --git a/game-stats.lua b/game-stats.lua index 212c1b1..8450133 100644 --- a/game-stats.lua +++ b/game-stats.lua @@ -8,6 +8,17 @@ function GetMods() helpers.send_udp(udpAddress, modstring,serverIndex) end +function GetPlayerColors() + local colorParts = {} + colorParts[#colorParts+1] = "---player-colors---\n" + for index, player in pairs(game.players) do + local colorSettings = player.color + colorParts[#colorParts+1] = ("%d:%s:%d:%d:%d:%d"):format(index,player.name,colorSettings.r,colorSettings.g,colorSettings.b,colorSettings.a) + end + return table.concat(colorParts,"\n") +end + + function GetPlayerKills() local killParts = {} killParts[#killParts+1] = "---player-kills---\n" diff --git a/info.json b/info.json index 7d64dc3..8f79398 100644 --- a/info.json +++ b/info.json @@ -1,6 +1,6 @@ { "name": "factorio-metrics-exporter", - "version": "0.2.0", + "version": "0.2.1", "title": "Prometheus Metrics Exporter", "author": "Jan Grießhaber", "contact": "jan@griesshaber.systems", diff --git a/logistic-network-stats.lua b/logistic-network-stats.lua index d720903..6523048 100644 --- a/logistic-network-stats.lua +++ b/logistic-network-stats.lua @@ -33,7 +33,10 @@ end function SendLogisticStats() if options.enableRobots then - local send = GetAllLogisticGrids().."\n"..GetLogisticNetworkContents() - helpers.send_udp(udpAddress,send,serverIndex) + local returnParts = {} + returnParts[#returnParts+1] = GetAllLogisticGrids() + returnParts[#returnParts+1] = GetLogisticNetworkContents() + --local send = GetAllLogisticGrids().."\n"..GetLogisticNetworkContents() + helpers.send_udp(udpAddress,table.concat(returnParts,"\n"),serverIndex) end end diff --git a/power-stats.lua b/power-stats.lua index d1dc6d2..a49d993 100644 --- a/power-stats.lua +++ b/power-stats.lua @@ -1,7 +1,11 @@ function AddPowerPole(event) local e = event.entity - if e and e.valid and e.type == "electric-pole" then + if e then storage.representativePoles[e.unit_number] = e + -- Update cache with new network + if e.electric_network_id then + storage.networkCache[e.electric_network_id] = e + end end end @@ -9,31 +13,40 @@ function RemovePowerPole(event) local e = event.entity if e then storage.representativePoles[e.unit_number] = nil + -- Invalidate cache - force rebuild to find new representative if needed + storage.networkCache = nil end end function GetNetworks() + -- Return cached networks if available, otherwise rebuild + if storage.networkCache then + return storage.networkCache + end + local networks = {} - for _, pole in pairs(storage.representativePoles) do if pole.valid then - local net = pole.electric_network_id - if net then - networks[net] = pole + local netID = pole.electric_network_id + if netID then + networks[netID] = pole end end end - + + storage.networkCache = networks return networks end function ScanNetworks() storage.representativePoles = {} + storage.networkCache = {} for _, surface in pairs(game.surfaces) do for _, pole in pairs(surface.find_entities_filtered{type = "electric-pole"}) do if pole.valid and pole.electric_network_id then storage.representativePoles[pole.unit_number] = pole + storage.networkCache[pole.electric_network_id] = pole end end end diff --git a/research-stats.lua b/research-stats.lua index cda621d..f3ee4bf 100644 --- a/research-stats.lua +++ b/research-stats.lua @@ -50,8 +50,11 @@ function GetEstimatedResearchTime() local returnSpeed = "---research-speed---\n"..totalSpeed.."\n" local returnTime = "---research-time---\n"..estimatedSeconds.."\n" local returnNameID = "---research-info---\n"..researchName.."\n" + local returnProgress = "---research-progress---\n"..playerForce.research_progress.."\n" - return returnSpeed..returnTime..returnNameID + log("Reseach remaining "..returnTime) + + return returnSpeed..returnTime..returnNameID..returnProgress end function UpdateLabInfos() diff --git a/train-stats.lua b/train-stats.lua index 7553ba8..f9f0ac8 100644 --- a/train-stats.lua +++ b/train-stats.lua @@ -79,6 +79,8 @@ end ---@class trainStat trainStat = { + trainID = 0, + trainName = "", lastInventory={}, currentInventory={}, lastState = 0, @@ -87,8 +89,16 @@ trainStat = { totalCargoCount = 0, totalCargo = {}, lastArrivalTime = 0, - currentArrivalTime = 0 + currentArrivalTime = 0, + ---@type trip + trips = {} } +---@class trip + trip = { + startStation= {}, + endStation = {}, + timeTaken = 0 + } ---@param inv table[] ---@return table @@ -150,9 +160,13 @@ function onTrainStateChange(event) local trainID = train.id ---@type trainStat local stat = storage.trainStats[trainID] or {} + stat.trips = stat.trips or {} + stat.trainID = trainID + stat.trainName = GetTrainName(train) if event.train.state == defines.train_state.wait_station then + if train.station.unit_number == stat.lastStationUnitNumber then return end stat.lastStationUnitNumber = stat.currentStationUnitNumber stat.lastInventory = stat.currentInventory stat.lastArrivalTime = stat.currentArrivalTime @@ -160,12 +174,20 @@ function onTrainStateChange(event) stat.currentStationUnitNumber = train.station.unit_number stat.currentInventory = train.get_contents() stat.currentArrivalTime = game.tick - + + if stat.lastStationUnitNumber + and stat.currentStationUnitNumber then + local tripIdentifier = tostring(stat.lastStationUnitNumber) .. tostring(stat.currentStationUnitNumber) + stat.trips[tripIdentifier] = { + startStation = game.get_entity_by_unit_number(stat.lastStationUnitNumber), + endStation = game.get_entity_by_unit_number(stat.currentStationUnitNumber), + timeTaken = stat.currentArrivalTime-stat.lastArrivalTime} + end 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 + stat.totalCargoCount = (stat.totalCargoCount or 0) + math.abs(value.delta) end end @@ -174,25 +196,64 @@ function onTrainStateChange(event) --log("inEvent") end +function GetTrainTripStats() + local tripParts = {} + tripParts[#tripParts+1] = "---train-trips---\n" + for trainID,stats in pairs(storage.trainStats) do + for _,trip in pairs(stats.trips or {}) do + tripParts[#tripParts+1] = + ("%d:%s:%s:%s:%d"):format( + trainID, + stats.trainName, + trip.startStation.backer_name, + trip.endStation.backer_name, + trip.timeTaken) + end + end + return table.concat(tripParts,"\n") +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 or 0) + trainParts[#trainParts+1] = ("%d:%s:%d"):format(trainID,stat.trainName,stat.totalCargoCount or 0) end return table.concat(trainParts,"\n") end +---Purges stats for trains that no longer exist +---@param trainID integer|nil If provided, purges only that train. If nil, purges all dead trains. +function PurgeDeadTrainStats(trainID) + if trainID then + -- Purge a specific train if it doesn't exist + if not storage.trains[trainID] then + storage.trainStats[trainID] = nil + return true + end + else + -- Purge all trains not in storage.trains + for statTrainID in pairs(storage.trainStats) do + if not storage.trains[statTrainID] then + storage.trainStats[statTrainID] = nil + end + end + end + return false +end + function SendTrainStats() if options.enableTrains then ScanTrains() + PurgeDeadTrainStats() local returnParts = {} returnParts[#returnParts+1] = GetTrainPlayerKills() returnParts[#returnParts+1] = GetTrainTotalKills() returnParts[#returnParts+1] = GetTrainStates() returnParts[#returnParts+1] = GetTrainStatistics() returnParts[#returnParts+1] = GetTrainsInDepot() + returnParts[#returnParts+1] = GetTrainTripStats() helpers.send_udp(udpAddress,table.concat(returnParts,"\n"),serverIndex) end end \ No newline at end of file