You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
10 KiB
310 lines
10 KiB
local ParcelDefinition = { |
|
server = { |
|
game = { |
|
id = nil, |
|
}, |
|
modes = { |
|
cheat_mode_enabled = false, |
|
cheat_mode_enabled_ever = false, |
|
}, |
|
}, |
|
forces = {} |
|
} |
|
|
|
-- http://lua-users.org/wiki/CopyTable |
|
local function deepcopy(orig) |
|
local orig_type = type(orig) |
|
local copy |
|
if orig_type == 'table' then |
|
copy = {} |
|
for orig_key, orig_value in next, orig, nil do |
|
copy[deepcopy(orig_key)] = deepcopy(orig_value) |
|
end |
|
setmetatable(copy, deepcopy(getmetatable(orig))) |
|
else -- number, string, boolean, etc |
|
copy = orig |
|
end |
|
return copy |
|
end |
|
|
|
|
|
|
|
|
|
|
|
|
|
-- get_flow_stats() uses these to generate stats |
|
-- in theory, its better for external graphing to manage time |
|
-- and simply send last 1 minute of data |
|
local times = { |
|
one_minute = defines.flow_precision_index.one_minute, |
|
-- ten_minutes = defines.flow_precision_index.ten_minutes, |
|
-- one_hour = defines.flow_precision_index.one_hour, |
|
-- ten_hours = defines.flow_precision_index.ten_hours, |
|
-- fifty_hours = defines.flow_precision_index.fifty_hours, |
|
-- two_hundred_fifty_hours = defines.flow_precision_index.two_hundred_fifty_hours, |
|
-- one_thousand_hours = defines.flow_precision_index.one_thousand_hours |
|
} |
|
|
|
|
|
local function get_technology_stats(research) |
|
if research == nil then |
|
return nil |
|
end |
|
|
|
return { |
|
name = research.name, |
|
localised_name = research.localised_name, |
|
localised_description = research.localised_description, |
|
enabled = research.enabled, |
|
visible_when_disabled = research.visible_when_disabled, |
|
upgrade = research.upgrade, |
|
researched = research.researched, |
|
research_unit_count = research.research_unit_count, |
|
research_unit_energy = research.research_unit_energy, |
|
level = research.level, |
|
research_unit_count_formula = research.research_unit_count_formula |
|
} |
|
end |
|
|
|
local function get_surface_stats(surface) |
|
return { |
|
-- chunks |
|
-- trains |
|
name = surface.name, |
|
total_pollution = surface.get_total_pollution(), |
|
pollution_statistics = { |
|
input_counts = game.pollution_statistics.input_counts, |
|
output_counts = game.pollution_statistics.output_counts |
|
}, |
|
active_entities_count = game.get_active_entities_count(surface.index), |
|
always_day = surface.always_day, |
|
daytime = surface.daytime, |
|
darkness = surface.darkness, |
|
wind_speed = surface.wind_speed, |
|
wind_orientation = surface.wind_orientation, |
|
peaceful_mode = surface.peaceful_mode, |
|
freeze_daytime = surface.freeze_daytime, |
|
ticks_per_day = surface.ticks_per_day, |
|
dusk = surface.dusk, |
|
dawn = surface.dawn, |
|
evening = surface.evening, |
|
morning = surface.morning, |
|
solar_power_multiplier = surface.solar_power_multiplier, |
|
min_brightness = surface.min_brightness |
|
} |
|
end |
|
|
|
local function get_flow_stats(flow, prototypes) |
|
|
|
local stats = { |
|
input_counts = flow.input_counts, |
|
output_counts = flow.output_counts, |
|
count = {}, |
|
per_time_frame = {} |
|
} |
|
|
|
for time_name, time_definition in pairs(times) do |
|
stats.count[time_name] = {} |
|
stats.per_time_frame[time_name] = {} |
|
|
|
for index, val in pairs(stats.input_counts) do |
|
stats.count[time_name][index] = flow.get_flow_count({ |
|
name = prototypes[index].name, |
|
input=true, |
|
precision_index=time_definition, |
|
count=true |
|
}) |
|
stats.per_time_frame[time_name][index] = flow.get_flow_count({ |
|
name = prototypes[index].name, |
|
input=true, |
|
precision_index=time_definition, |
|
count=false |
|
}) |
|
end |
|
end |
|
|
|
--input_counts_5m = flow.get_flow_count() |
|
return stats |
|
end |
|
|
|
local function table_length(table) |
|
if table == nil then return 0 end |
|
|
|
local count = 0 |
|
for k,v in pairs(table) do count = count + 1 end |
|
return count |
|
end |
|
|
|
local function get_force_surface_details(force, surface) |
|
return { |
|
spawn_position = force.get_spawn_position(surface), |
|
logistic_networks_count = table_length(force.logistic_networks[surface]) |
|
} |
|
end |
|
|
|
local function get_force_stats(force) |
|
local force_stats = { |
|
index = force.index, |
|
name = force.name, |
|
|
|
-- CAPABILITIES |
|
|
|
ai_controllable = force.ai_controllable, |
|
ghost_time_to_live = force.ghost_time_to_live, |
|
deconstruction_time_to_live = force.deconstruction_time_to_live, |
|
max_successful_attempts_per_tick_per_construction_queue = force.max_successful_attempts_per_tick_per_construction_queue, |
|
max_failed_attempts_per_tick_per_construction_queue = force.max_failed_attempts_per_tick_per_construction_queue, |
|
auto_character_trash_slots = force.auto_character_trash_slots, |
|
zoom_to_world_enabled = force.zoom_to_world_enabled, |
|
zoom_to_world_ghost_building_enabled = force.zoom_to_world_ghost_building_enabled, |
|
zoom_to_world_blueprint_enabled = force.zoom_to_world_blueprint_enabled, |
|
zoom_to_world_deconstruction_planner_enabled = force.zoom_to_world_deconstruction_planner_enabled, |
|
zoom_to_world_selection_tool_enabled = force.zoom_to_world_selection_tool_enabled, |
|
character_logistic_requests = force.character_logistic_requests, |
|
friendly_fire = force.friendly_fire, |
|
share_chart = force.share_chart, |
|
research_queue_enabled = force.research_queue_enabled, |
|
research_enabled = force.research_enabled, |
|
|
|
-- 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, |
|
|
|
-- BONUSES |
|
|
|
manual_mining_speed_modifier = force.manual_mining_speed_modifier, |
|
laboratory_speed_modifier = force.laboratory_speed_modifier, |
|
laboratory_productivity_bonus = force.laboratory_productivity_bonus, |
|
worker_robots_speed_modifier = force.worker_robots_speed_modifier, |
|
worker_robots_battery_modifier = force.worker_robots_battery_modifier, |
|
worker_robots_storage_bonus = force.worker_robots_storage_bonus, |
|
inserter_stack_size_bonus = force.inserter_stack_size_bonus, |
|
stack_inserter_capacity_bonus = force.stack_inserter_capacity_bonus, |
|
character_trash_slot_count = force.character_trash_slot_count, |
|
maximum_following_robot_count = force.maximum_following_robot_count, |
|
following_robots_lifetime_modifier = force.following_robots_lifetime_modifier, |
|
|
|
character_running_speed_modifier = force.character_running_speed_modifier, |
|
artillery_range_modifier = force.artillery_range_modifier, |
|
character_build_distance_bonus = force.character_build_distance_bonus, |
|
character_item_drop_distance_bonus = force.character_item_drop_distance_bonus, |
|
character_reach_distance_bonus = force.character_reach_distance_bonus, |
|
character_resource_reach_distance_bonus = force.character_resource_reach_distance_bonus, |
|
character_item_pickup_distance_bonus = force.character_item_pickup_distance_bonus, |
|
character_loot_pickup_distance_bonus = force.character_loot_pickup_distance_bonus, |
|
character_inventory_slots_bonus = force.character_inventory_slots_bonus, |
|
character_health_bonus = force.character_health_bonus, |
|
mining_drill_productivity_bonus = force.mining_drill_productivity_bonus, |
|
train_braking_force_bonus = force.train_braking_force_bonus, |
|
|
|
-- technologies |
|
-- recipes |
|
|
|
|
|
-- SURFACES |
|
surfaces = {}, |
|
|
|
|
|
-- ENTITIES |
|
--get_entity_count(name) -- this has performance hit apparently |
|
|
|
-- and ammo and turret prototypes for modifiers |
|
|
|
-- loop through item entities: |
|
-- get_item_launched() |
|
|
|
-- loop through surfaces |
|
-- get_trains() |
|
|
|
-- players |
|
-- logistic_networks |
|
|
|
-- stats per opposing force? |
|
|
|
|
|
entity_build_count_statistics = get_flow_stats(force.entity_build_count_statistics, game.entity_prototypes), |
|
item_production_statistics = get_flow_stats(force.item_production_statistics, game.item_prototypes), |
|
fluid_production_statistics = get_flow_stats(force.fluid_production_statistics, game.fluid_prototypes), |
|
kill_count_statistics = get_flow_stats(force.kill_count_statistics, game.entity_prototypes), |
|
rockets_launched = force.rockets_launched, |
|
items_launched = force.items_launched, |
|
--connected_players = force.connected_players, |
|
previous_research = get_technology_stats(force.previous_research), |
|
current_research = get_technology_stats(force.current_research), |
|
--research_queue |
|
} |
|
|
|
for index, surface in pairs(game.surfaces) do |
|
force_stats.surfaces[index] = get_force_surface_details(force, surface) |
|
end |
|
|
|
return force_stats |
|
end |
|
|
|
|
|
|
|
|
|
|
|
local dump_stats = function() |
|
local parcel = deepcopy(ParcelDefinition) |
|
|
|
parcel.server.game.id = global.statorio.game_id |
|
parcel.server.modes.cheat_mode_enabled = global.statorio.cheat_mode_enabled |
|
parcel.server.modes.cheat_mode_enabled_ever = global.statorio.cheat_mode_enabled_ever |
|
|
|
-- forces |
|
for index, force in pairs(game.forces) do |
|
parcel.forces[index] = get_force_stats(force) |
|
end |
|
|
|
-- Load other data onto here |
|
|
|
|
|
game.print("Writing statistics to file "..game.tick..".json") |
|
-- game.write_file(game.tick..".json", game.table_to_json(parcel)) |
|
game.write_file("stats.json", game.table_to_json(parcel)) |
|
end |
|
|
|
|
|
script.on_init(function() |
|
-- when game starts, or mod added to existing save |
|
-- use to initialize global variables |
|
global.statorio = { |
|
game_id = math.random(), |
|
next_update_tick = game.tick, |
|
cheat_mode_enabled = false, |
|
cheat_mode_enabled_ever = false, |
|
} |
|
end) |
|
|
|
script.on_event(defines.events.on_tick, function(e) |
|
-- A tick occured before the mod initialized |
|
if global.statorio == nil then return end |
|
|
|
-- Nothing to do yet |
|
if game.tick < global.statorio.next_update_tick then return end |
|
|
|
-- Generate stats |
|
dump_stats() |
|
|
|
-- Set next update tick |
|
global.statorio.next_update_tick = game.tick + 600 |
|
end) |
|
|
|
script.on_configuration_changed(function(data) |
|
-- mod changes, deal with prototype or game setting changes |
|
-- data contains changes |
|
-- http://lua-api.factorio.com/latest/Concepts.html#ConfigurationChangedData |
|
end) |
|
|
|
script.on_event(defines.events.on_player_cheat_mode_enabled, function(e) |
|
global.statorio.cheat_mode_enabled_ever = true |
|
global.statorio.cheat_mode_enabled = true |
|
end) |
|
|
|
script.on_event(defines.events.on_player_cheat_mode_disabled, function(e) |
|
global.statorio.cheat_mode_enabled = false |
|
end)
|
|
|