commit 149b085cb7f2c669136ee99dc2feb92f61742ea4 Author: Jan Grießhaber Date: Sun Dec 28 18:48:24 2025 +0100 Initial Commit diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e474c2e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,36 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "factoriomod", + "request": "launch", + "name": "Factorio Mod Debug", + "factorioArgs": [ + "--enable-lua-udp=55555" + ] + }, + { + "type": "factoriomod", + "request": "launch", + "name": "Factorio Mod Debug (Settings & Data)", + "hookSettings": true, + "hookData": true, + "factorioArgs": [ + "--enable-lua-udp=55555" + ] + }, + { + "type": "factoriomod", + "request": "launch", + "name": "Factorio Mod Debug (Profile)", + "hookMode": "profile", + "factorioArgs": [ + "--enable-lua-udp=55555" + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1bd2da8 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,15 @@ +{ + "Lua.workspace.userThirdParty": [ + "c:\\Users\\jangr\\AppData\\Roaming\\Code\\User\\workspaceStorage\\8bef1fd407f1cda3acb8320784a68ee6\\justarandomgeek.factoriomod-debug\\sumneko-3rd" + ], + "Lua.workspace.checkThirdParty": "ApplyInMemory", + "factorio.versions": [ + { + "name": "Factorio 2.0.72 local", + "factorioPath": "d:\\SteamLibrary\\steamapps\\common\\Factorio\\bin\\x64\\factorio.exe" + } + ], + "Lua.diagnostics.globals": [ + "create_stats_string" + ] +} \ No newline at end of file diff --git a/control.lua b/control.lua new file mode 100644 index 0000000..65e15d0 --- /dev/null +++ b/control.lua @@ -0,0 +1,48 @@ +require("production-stats") + +-- control.lua for factorio-prometheus-exporter +-- Adds a handler for player movement (on_player_changed_position) +---@param event EventData.on_tick +local function SendSurfaceStats(event) + if event.tick % 300 ~= 0 then return end + + helpers.send_udp(52555, game.tick,1) + for _,surface in pairs(game.surfaces) do + local surface_name = surface.name + local productionStat = CreateItemStatisticsString(game.forces["player"].get_item_production_statistics(surface_name), surface) + local fluidStat = CreateFluidStatisticsString(game.forces["player"].get_fluid_production_statistics(surface_name), surface) + local deathStat = CreateDeathStatisticsString(game.forces["player"].get_kill_count_statistics(surface_name), surface) + helpers.send_udp(52555, productionStat..fluidStat..deathStat,1) + end +end + + + + +-- Register the handler for the player movement event +--script.on_event(defines.events.on_player_changed_position, on_player_moved) + +script.on_event(defines.events.on_player_died, function(event) + local player = game.get_player(event.player_index) + if not player then return end + local index = event.player_index + helpers.send_udp(52555, ("player-death %s %d"):format(player.name, player.index),index) +end) + +script.on_event(defines.events.on_player_joined_game, function(event) + local player = game.get_player(event.player_index) + if not player then return end + local index = event.player_index + helpers.send_udp(52555, ("player-join %s %d"):format(player.name, player.index),index) +end) + +function GetAllPlayers() + for _,player in pairs(game.players) do + + end +end + +--script.on_event(defines.events.on_player_joined_game, on_player_joined) +--script.on_nth_tick(300, SendSurfaceStats) +script.on_event(defines.events.on_tick, SendSurfaceStats) + diff --git a/data.lua b/data.lua new file mode 100644 index 0000000..e69de29 diff --git a/game-stats.lua b/game-stats.lua new file mode 100644 index 0000000..a9b1ffa --- /dev/null +++ b/game-stats.lua @@ -0,0 +1,22 @@ +---Sends all mod infos for the current game, should only be called on the first load of the map since mods don't change during runtime +function GetMods() + local mods = script.active_mods + local modstring = "---mod-info---\n" + for k,v in pairs(mods) do + modstring = modstring .. ("mod-info:%s:%s\n"):format(k,v) + + end + helpers.send_udp(52555, modstring,1) +end + +---Concats all player online times into a single string +---Takes all players that ever visited the server into account +---@return string +function GetPlayerTime() + local timeParts = {} + timeParts[#timeParts+1] = "---player-times---\n" + for _,player in pairs(game.players) do + timeParts[#timeParts+1] = ("player-time:%s:%d:%d"):format(player.name, player.index, player.online_time) + end + return table.concat(timeParts, "\n") +end \ No newline at end of file diff --git a/implemetation-plans.md b/implemetation-plans.md new file mode 100644 index 0000000..ef2b927 --- /dev/null +++ b/implemetation-plans.md @@ -0,0 +1,10 @@ +Production Statistics Input and Output + +Player Kills|Deaths|Time + +Power Grids| Power Stats + +Rockets launched + +Research Speed| Level| current queue, estimated time to completion + diff --git a/info.json b/info.json new file mode 100644 index 0000000..d92118a --- /dev/null +++ b/info.json @@ -0,0 +1,19 @@ +{ + "name": "factorio-prometheus-exporter", + "version": "0.1.0", + "title": "Prometheus Exporter", + "author": "Your Name", + "contact": "your.email@example.com", + "homepage": "", + "description": "Exports Factorio metrics for collection by Prometheus.", + "factorio_version": "2.0", + "dependencies": [ + "base >= 2.0.0" + ], + "license": "MIT", + "tags": [ + "monitoring", + "metrics", + "prometheus" + ] +} \ No newline at end of file diff --git a/locale/de-DE/locale.cfg b/locale/de-DE/locale.cfg new file mode 100644 index 0000000..e69de29 diff --git a/locale/en/locale.cfg b/locale/en/locale.cfg new file mode 100644 index 0000000..e69de29 diff --git a/pollution-stats.lua b/pollution-stats.lua new file mode 100644 index 0000000..2db252f --- /dev/null +++ b/pollution-stats.lua @@ -0,0 +1,18 @@ +function GetPollutionStats() + for _,surface in pairs(game.surfaces) do + local surface_name = surface.name + local pollutionParts = {} + local pollution_stats = game.surfaces[surface_name].pollution_statistics + local pollution_input = pollution_stats.input_counts + local pollution_output = pollution_stats.output_counts + pollutionParts[#pollutionParts+1] = ("---pollution-input---%s\n"):format(surface_name) + for name, stat in pairs(pollution_input) do + pollutionParts[#pollutionParts+1] = ("%s:%d"):format(name, stat) + end + pollutionParts[#pollutionParts+1] = ("---pollution-output---%s\n"):format(surface_name) + for name, stat in pairs(pollution_output) do + pollutionParts[#pollutionParts+1] = ("%s:%d"):format(name, stat) + end + helpers.send_udp(52555, table.concat(pollutionParts,"\n"),1) + end +end \ No newline at end of file diff --git a/production-stats.lua b/production-stats.lua new file mode 100644 index 0000000..7288a20 --- /dev/null +++ b/production-stats.lua @@ -0,0 +1,56 @@ +---@param productionStatsTable LuaFlowStatistics +---@param surface LuaSurface +---@return string +function CreateItemStatisticsString(productionStatsTable --[[LuaFlowStatistics]], surface --[[LuaSurface]]) + local parts = {} + parts[#parts+1] = surface.name + parts[#parts+1] = "---input---" + for itemName, itemCount in pairs(productionStatsTable.input_counts) do + parts[#parts+1] = itemName .. ":" .. itemCount + end + parts[#parts+1] = "---output---" + for itemName, itemCount in pairs(productionStatsTable.output_counts) do + parts[#parts+1] = itemName .. ":" .. itemCount + end + parts[#parts+1] = surface.name + return table.concat(parts, "\n") +end + + +---comment +---@param fluidStatsTable LuaFlowStatistics +---@param surface LuaSurface +---@return string +function CreateFluidStatisticsString(fluidStatsTable --[[LuaFlowStatistics]], surface --[[LuaSurface]]) + local parts = {} + parts[#parts+1] = surface.name + parts[#parts+1] = "---input---" + for fluidName, fluidCount in pairs(fluidStatsTable.input_counts) do + parts[#parts+1] = fluidName .. ":" .. fluidCount + end + parts[#parts+1] = "---output---" + for fluidName, fluidCount in pairs(fluidStatsTable.output_counts) do + parts[#parts+1] = fluidName .. ":" .. fluidCount + end + parts[#parts+1] = surface.name + return table.concat(parts, "\n") +end + +---comment +---@param deathStatsTable LuaFlowStatistics +---@param surface LuaSurface +---@return string +function CreateDeathStatisticsString(deathStatsTable --[[LuaFlowStatistics]], surface --[[LuaSurface]]) + local parts = {} + parts[#parts+1] = surface.name.."{" + parts[#parts+1] = "---input---" + for name, count in pairs(deathStatsTable.input_counts) do + parts[#parts+1] = name .. ":" .. count + end + parts[#parts+1] = "---output---" + for name, count in pairs(deathStatsTable.output_counts) do + parts[#parts+1] = name .. ":" .. count + end + parts[#parts+1] = surface.name + return table.concat(parts, "\n") +end \ No newline at end of file diff --git a/research-stats.lua b/research-stats.lua new file mode 100644 index 0000000..62b3edb --- /dev/null +++ b/research-stats.lua @@ -0,0 +1,20 @@ +local researches = {} + + +---comment +---@param event EventData.on_research_finished +function onResearchFinished(event) + for id, tech in pairs(game.forces["player"].technologies) do + researches[id] = tech + end + end + +---comment +---@param event EventData.on_research_started +function onResearchStarted(event) +end + +---comment +---@param event EventData.on_research_queued +function onResearchQueued(event) +end diff --git a/settings.lua b/settings.lua new file mode 100644 index 0000000..56cd86a --- /dev/null +++ b/settings.lua @@ -0,0 +1,52 @@ +data:extend({ + { + type = "bool-setting", + name = "factorio-prometheus-exporter-enable", + setting_type = "startup", + default_value = true, + order = "a" + }, + { + type = "string-setting", + name = "factorio-prometheus-exporter-udp-address", + setting_type = "startup", + allow_blank = true, + default_value = "", + order = "b" + }, + { + type = "bool-setting", + name = "factorio-prometheus-exporter-export_production_stats", + setting_type = "startup", + default_value = true, + order = "c" + }, + { + type = "bool-setting", + name = "factorio-prometheus-exporter-export_player_deaths", + setting_type = "startup", + default_value = true, + order = "d" + }, + { + type = "bool-setting", + name = "factorio-prometheus-exporter-export_fluid_stats", + setting_type = "startup", + default_value = true, + order = "e" + }, + { + type = "bool-setting", + name = "factorio-prometheus-exporter-export_power_stats", + setting_type = "startup", + default_value = false, + order = "f" + }, + { + type = "bool-setting", + name = "factorio-prometheus-exporter-export_pollution_stats", + setting_type = "startup", + default_value = true, + order = "g" + } +}) \ No newline at end of file