@expcluster/legacy 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/dist/browser/package.json +40 -0
- package/dist/browser/tsconfig.browser.tsbuildinfo +1 -0
- package/dist/browser/web/index.d.ts +1 -0
- package/dist/browser/web/index.d.ts.map +1 -0
- package/dist/browser/web/index.js +2 -0
- package/dist/browser/web/index.js.map +1 -0
- package/dist/node/index.d.ts +3 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +10 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/instance.d.ts +4 -0
- package/dist/node/instance.d.ts.map +1 -0
- package/dist/node/instance.js +8 -0
- package/dist/node/instance.js.map +1 -0
- package/dist/node/tsconfig.node.tsbuildinfo +1 -0
- package/dist/web/manifest.json +7 -0
- package/dist/web/static/exp_legacy.9b6538559ed5e689539c.js +355 -0
- package/dist/web/static/index_ts.8f9d451c8d3f7f293da6.js +22 -0
- package/dist/web/static/main.94e1b48804112ca8bdfc.js +118 -0
- package/dist/web/static/package_json.a83729efdb0697b12396.js +22 -0
- package/dist/web/static/web_index_tsx.e5a01ac0e4b0a6f6517f.js +21 -0
- package/index.ts +8 -0
- package/instance.ts +7 -0
- package/module/config/_file_loader.lua +29 -0
- package/module/config/advanced_start.lua +112 -0
- package/module/config/afk_kick.lua +14 -0
- package/module/config/bonus.lua +105 -0
- package/module/config/chat_reply.lua +136 -0
- package/module/config/compilatron.lua +25 -0
- package/module/config/death_logger.lua +15 -0
- package/module/config/deconlog.lua +11 -0
- package/module/config/discord_alerts.lua +25 -0
- package/module/config/expcore/permission_groups.lua +143 -0
- package/module/config/graftorio.lua +7 -0
- package/module/config/gui/autofill.lua +129 -0
- package/module/config/gui/player_list_actions.lua +201 -0
- package/module/config/gui/rockets.lua +47 -0
- package/module/config/gui/science.lua +21 -0
- package/module/config/gui/tasks.lua +13 -0
- package/module/config/gui/warps.lua +52 -0
- package/module/config/inventory_clear.lua +9 -0
- package/module/config/join_messages.lua +8 -0
- package/module/config/lawnmower.lua +6 -0
- package/module/config/logging.lua +30 -0
- package/module/config/miner.lua +8 -0
- package/module/config/module.lua +86 -0
- package/module/config/nukeprotect.lua +30 -0
- package/module/config/pollution_grading.lua +9 -0
- package/module/config/popup_messages.lua +10 -0
- package/module/config/preset_player_colours.lua +33 -0
- package/module/config/preset_player_quickbar.lua +6 -0
- package/module/config/protection.lua +17 -0
- package/module/config/repair.lua +8 -0
- package/module/config/research.lua +179 -0
- package/module/config/scorched_earth.lua +116 -0
- package/module/config/spawn_area.lua +255 -0
- package/module/config/station_auto_name.lua +11 -0
- package/module/config/statistics.lua +46 -0
- package/module/config/vlayer.lua +180 -0
- package/module/config/warnings.lua +38 -0
- package/module/control.lua +46 -0
- package/module/expcore/datastore.lua +884 -0
- package/module/expcore/external.lua +146 -0
- package/module/expcore/permission_groups.lua +355 -0
- package/module/expcore/player_data.lua +152 -0
- package/module/locale/en/addons.cfg +31 -0
- package/module/locale/en/data.cfg +114 -0
- package/module/locale/en/expcore.cfg +16 -0
- package/module/locale/en/gui.cfg +114 -0
- package/module/locale/zh-CN/addons.cfg +31 -0
- package/module/locale/zh-CN/data.cfg +114 -0
- package/module/locale/zh-CN/expcore.cfg +16 -0
- package/module/locale/zh-CN/gui.cfg +122 -0
- package/module/locale/zh-TW/addons.cfg +31 -0
- package/module/locale/zh-TW/data.cfg +114 -0
- package/module/locale/zh-TW/expcore.cfg +16 -0
- package/module/locale/zh-TW/gui.cfg +122 -0
- package/module/module.json +14 -0
- package/module/module_exports.lua +3 -0
- package/module/modules/control/jail.lua +119 -0
- package/module/modules/control/protection.lua +204 -0
- package/module/modules/control/reports.lua +225 -0
- package/module/modules/control/spectate.lua +173 -0
- package/module/modules/control/vlayer.lua +807 -0
- package/module/modules/control/warnings.lua +331 -0
- package/module/modules/control/warps.lua +488 -0
- package/module/modules/data/alt-view.lua +26 -0
- package/module/modules/data/greetings.lua +45 -0
- package/module/modules/data/language.lua +21 -0
- package/module/modules/data/player-colours.lua +63 -0
- package/module/modules/data/quickbar.lua +72 -0
- package/module/modules/data/statistics.lua +181 -0
- package/module/modules/data/tag.lua +82 -0
- package/module/modules/data/toolbar.lua +31 -0
- package/module/modules/graftorio/forcestats.lua +196 -0
- package/module/modules/graftorio/general.lua +63 -0
- package/module/modules/graftorio/require.lua +28 -0
- package/module/modules/graftorio/statics.lua +36 -0
- package/module/modules/gui/vlayer.lua +547 -0
- package/module/modules/gui/warp-list.lua +909 -0
- package/module/utils/event.lua +86 -0
- package/package.json +38 -0
- package/tsconfig.browser.json +4 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +5 -0
- package/web/index.tsx +0 -0
- package/webpack.config.js +29 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
--[[-- Commands Module - Quickbar
|
|
2
|
+
- Adds a command that allows players to load Quickbar presets
|
|
3
|
+
@data Quickbar
|
|
4
|
+
]]
|
|
5
|
+
|
|
6
|
+
local Commands = require("modules/exp_commands")
|
|
7
|
+
local config = require("modules.exp_legacy.config.preset_player_quickbar") --- @dep config.preset_player_quickbar
|
|
8
|
+
|
|
9
|
+
--- Stores the quickbar filters for a player
|
|
10
|
+
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
|
11
|
+
local PlayerFilters = PlayerData.Settings:combine("QuickbarFilters")
|
|
12
|
+
PlayerFilters:set_metadata{
|
|
13
|
+
permission = "exp_scenario.command.save_quickbar",
|
|
14
|
+
stringify = function(value)
|
|
15
|
+
if not value then return "No filters set" end
|
|
16
|
+
local count = 0
|
|
17
|
+
for _ in pairs(value) do count = count + 1 end
|
|
18
|
+
|
|
19
|
+
return count .. " filters set"
|
|
20
|
+
end,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
--- Loads your quickbar preset
|
|
24
|
+
PlayerFilters:on_load(function(player_name, filters)
|
|
25
|
+
if not filters then filters = config[player_name] end
|
|
26
|
+
if not filters then return end
|
|
27
|
+
local player = game.players[player_name]
|
|
28
|
+
for i, item_name in pairs(filters) do
|
|
29
|
+
if item_name ~= nil and item_name ~= "" then
|
|
30
|
+
player.set_quick_bar_slot(i, item_name)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end)
|
|
34
|
+
|
|
35
|
+
local ignored_items = {
|
|
36
|
+
["blueprint"] = true,
|
|
37
|
+
["blueprint-book"] = true,
|
|
38
|
+
["deconstruction-planner"] = true,
|
|
39
|
+
["spidertron-remote"] = true,
|
|
40
|
+
["upgrade-planner"] = true,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
--- Saves your quickbar preset to the script-output folder
|
|
44
|
+
Commands.new("save-quickbar", "Saves your Quickbar preset items to file")
|
|
45
|
+
:add_aliases{ "save-toolbar" }
|
|
46
|
+
:add_flags{ "disabled" }
|
|
47
|
+
:register(function(player)
|
|
48
|
+
local filters = {}
|
|
49
|
+
|
|
50
|
+
error("2.1 changes to get_quick_bar_slot beak compatibility with 2.0; waiting for upstream")
|
|
51
|
+
-- Upstream may add method to compat, or change inventory sync to have a quickbar only mode
|
|
52
|
+
for i = 1, 100 do
|
|
53
|
+
--[[
|
|
54
|
+
local slot = player.get_quick_bar_slot(i)
|
|
55
|
+
-- Need to filter out blueprint and blueprint books because the slot is a LuaItemPrototype and does not contain a way to export blueprint data
|
|
56
|
+
if slot ~= nil then
|
|
57
|
+
local ignored = ignored_items[slot.name]
|
|
58
|
+
if ignored ~= true then
|
|
59
|
+
filters[i] = slot.name
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
]]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if next(filters) then
|
|
66
|
+
PlayerFilters:set(player, filters)
|
|
67
|
+
else
|
|
68
|
+
PlayerFilters:remove(player)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
return Commands.status.success{ "quickbar.saved" }
|
|
72
|
+
end)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
local ExpUtil = require("modules/exp_util")
|
|
2
|
+
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
|
|
3
|
+
local Storage = require("modules/exp_util/storage") --- @dep utils.global
|
|
4
|
+
local config = require("modules.exp_legacy.config.statistics") --- @dep config.statistics
|
|
5
|
+
local floor = math.floor
|
|
6
|
+
local afk_required = 5 * 3600 -- 5 minutes
|
|
7
|
+
|
|
8
|
+
--- Stores players who have been created, required to avoid loss of data
|
|
9
|
+
local new_players = {}
|
|
10
|
+
Storage.register(new_players, function(tbl)
|
|
11
|
+
new_players = tbl
|
|
12
|
+
end)
|
|
13
|
+
|
|
14
|
+
--- Stores the statistics on a player
|
|
15
|
+
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
|
16
|
+
local AllPlayerData = PlayerData.All
|
|
17
|
+
local Statistics = PlayerData.Statistics
|
|
18
|
+
Statistics:set_metadata{
|
|
19
|
+
display_order = config.display_order,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
--- Update your statistics with any which happened before the data was valid
|
|
23
|
+
Statistics:on_load(function(player_name, player_statistics)
|
|
24
|
+
local existing_data = AllPlayerData:get(player_name)
|
|
25
|
+
if existing_data and existing_data.valid then return end
|
|
26
|
+
local counters = config.counters
|
|
27
|
+
|
|
28
|
+
-- Merge all data from before you data loaded
|
|
29
|
+
for key, value in pairs(Statistics:get(player_name, {})) do
|
|
30
|
+
if config[key] or counters[key] then
|
|
31
|
+
if not player_statistics[key] then
|
|
32
|
+
player_statistics[key] = value
|
|
33
|
+
else
|
|
34
|
+
player_statistics[key] = player_statistics[key] + value
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
-- Increment your maps played if this is your first time on this map
|
|
40
|
+
if new_players[player_name] then
|
|
41
|
+
new_players[player_name] = nil
|
|
42
|
+
local ctn = player_statistics.MapsPlayed
|
|
43
|
+
player_statistics["MapsPlayed"] = ctn and ctn + 1 or 1
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
return player_statistics
|
|
47
|
+
end)
|
|
48
|
+
|
|
49
|
+
local long_time_format = ExpUtil.format_time_factory_locale{ format = "long", coefficient = 3600, hours = true, minutes = true }
|
|
50
|
+
local short_time_format = ExpUtil.format_time_factory_locale{ format = "short", coefficient = 3600, hours = true, minutes = true }
|
|
51
|
+
|
|
52
|
+
--- Add MapsPlayed if it is enabled
|
|
53
|
+
if config.MapsPlayed then
|
|
54
|
+
Statistics:combine("MapsPlayed")
|
|
55
|
+
Event.add(defines.events.on_player_created, function(event)
|
|
56
|
+
local player = game.players[event.player_index]
|
|
57
|
+
new_players[player.name] = true
|
|
58
|
+
end)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
--- Add Playtime and AfkTime if it is enabled
|
|
62
|
+
if config.Playtime or config.AfkTime then
|
|
63
|
+
local playtime, afk_time
|
|
64
|
+
if config.Playtime then
|
|
65
|
+
playtime = Statistics:combine("Playtime")
|
|
66
|
+
playtime:set_metadata{ stringify = long_time_format, stringify_short = short_time_format }
|
|
67
|
+
end
|
|
68
|
+
if config.AfkTime then
|
|
69
|
+
afk_time = Statistics:combine("AfkTime")
|
|
70
|
+
afk_time:set_metadata{ stringify = long_time_format, stringify_short = short_time_format }
|
|
71
|
+
end
|
|
72
|
+
Event.on_nth_tick(3600, function()
|
|
73
|
+
if game.tick == 0 then return end
|
|
74
|
+
for _, player in pairs(game.connected_players) do
|
|
75
|
+
if playtime then playtime:increment(player) end
|
|
76
|
+
if afk_time and player.afk_time > afk_required then afk_time:increment(player) end
|
|
77
|
+
end
|
|
78
|
+
end)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
--- Add DistanceTravelled if it is enabled
|
|
82
|
+
if config.DistanceTravelled then
|
|
83
|
+
local stat = Statistics:combine("DistanceTravelled")
|
|
84
|
+
stat:set_metadata{ unit = " tiles" }
|
|
85
|
+
Event.add(defines.events.on_player_changed_position, function(event)
|
|
86
|
+
local player = game.players[event.player_index]
|
|
87
|
+
if not player.valid or not player.connected or player.afk_time > afk_required then return end
|
|
88
|
+
stat:increment(player)
|
|
89
|
+
end)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
--- Add MachinesRemoved and TreesDestroyed and config.OreMined if it is enabled
|
|
93
|
+
if config.MachinesRemoved or config.TreesDestroyed or config.OreMined then
|
|
94
|
+
local machines, trees, ore
|
|
95
|
+
if config.MachinesRemoved then machines = Statistics:combine("MachinesRemoved") end
|
|
96
|
+
if config.TreesDestroyed then trees = Statistics:combine("TreesDestroyed") end
|
|
97
|
+
if config.OreMined then ore = Statistics:combine("OreMined") end
|
|
98
|
+
local function on_event(event)
|
|
99
|
+
if not event.player_index then return end -- Check player is valid
|
|
100
|
+
local player = game.players[event.player_index]
|
|
101
|
+
if not player.valid or not player.connected then return end
|
|
102
|
+
local entity = event.entity -- Check entity is valid
|
|
103
|
+
if not entity.valid then return end
|
|
104
|
+
if entity.type == "resource" then
|
|
105
|
+
ore:increment(player)
|
|
106
|
+
elseif entity.type == "tree" then
|
|
107
|
+
trees:increment(player)
|
|
108
|
+
elseif entity.force == player.force then
|
|
109
|
+
machines:increment(player)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
Event.add(defines.events.on_marked_for_deconstruction, on_event)
|
|
113
|
+
Event.add(defines.events.on_player_mined_entity, on_event)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
--- Add DamageDealt if it is enabled
|
|
117
|
+
if config.DamageDealt then
|
|
118
|
+
local stat = Statistics:combine("DamageDealt")
|
|
119
|
+
Event.add(defines.events.on_entity_damaged, function(event)
|
|
120
|
+
local character = event.cause -- Check character is valid
|
|
121
|
+
if not character or not character.valid or character.type ~= "character" then return end
|
|
122
|
+
local player = character.player -- Check player is valid
|
|
123
|
+
if not player.valid or not player.connected then return end
|
|
124
|
+
local entity = event.entity -- Check entity is valid
|
|
125
|
+
if not entity.valid or entity.force == player.force or entity.force.name == "neutral" then return end
|
|
126
|
+
stat:increment(player, floor(event.final_damage_amount))
|
|
127
|
+
end)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
--- Add Kills if it is enabled
|
|
131
|
+
if config.Kills then
|
|
132
|
+
local stat = Statistics:combine("Kills")
|
|
133
|
+
Event.add(defines.events.on_entity_died, function(event)
|
|
134
|
+
local character = event.cause -- Check character is valid
|
|
135
|
+
if not character or not character.valid or character.type ~= "character" then return end
|
|
136
|
+
local player = character.player -- Check player is valid
|
|
137
|
+
if not player or not player.valid or not player.connected then return end
|
|
138
|
+
local entity = event.entity -- Check entity is valid
|
|
139
|
+
if not entity.valid or entity.force == player.force or entity.force.name == "neutral" then return end
|
|
140
|
+
stat:increment(player)
|
|
141
|
+
end)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
--- Add RocketsLaunched if it is enabled
|
|
145
|
+
if config.RocketsLaunched then
|
|
146
|
+
local stat = Statistics:combine("RocketsLaunched")
|
|
147
|
+
Event.add(defines.events.on_rocket_launched, function(event)
|
|
148
|
+
local silo = event.rocket_silo -- Check silo is valid
|
|
149
|
+
if not silo or not silo.valid then return end
|
|
150
|
+
local force = silo.force -- Check force is valid
|
|
151
|
+
if not force or not force.valid then return end
|
|
152
|
+
for _, player in pairs(force.connected_players) do
|
|
153
|
+
stat:increment(player)
|
|
154
|
+
end
|
|
155
|
+
end)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
--- Add RocketsLaunched if it is enabled
|
|
159
|
+
if config.ResearchCompleted then
|
|
160
|
+
local stat = Statistics:combine("ResearchCompleted")
|
|
161
|
+
Event.add(defines.events.on_research_finished, function(event)
|
|
162
|
+
local research = event.research -- Check research is valid
|
|
163
|
+
if event.by_script or not research or not research.valid then return end
|
|
164
|
+
local force = research.force -- Check force is valid
|
|
165
|
+
if not force or not force.valid then return end
|
|
166
|
+
for _, player in pairs(force.connected_players) do
|
|
167
|
+
stat:increment(player)
|
|
168
|
+
end
|
|
169
|
+
end)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
--- Add all the remaining statistics from the config
|
|
173
|
+
for statistic, event_name in pairs(config.counters) do
|
|
174
|
+
local stat = Statistics:combine(statistic)
|
|
175
|
+
Event.add(event_name, function(event)
|
|
176
|
+
if not event.player_index then return end
|
|
177
|
+
local player = game.players[event.player_index]
|
|
178
|
+
if not player.valid or not player.connected then return end
|
|
179
|
+
stat:increment(player)
|
|
180
|
+
end)
|
|
181
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
--[[-- Commands Module - Tag
|
|
2
|
+
- Adds a command that allows players to have a custom tag after their name
|
|
3
|
+
@data Tag
|
|
4
|
+
]]
|
|
5
|
+
|
|
6
|
+
local Commands = require("modules/exp_commands")
|
|
7
|
+
local Roles = require("modules/exp_roles")
|
|
8
|
+
|
|
9
|
+
--- Stores the tag for a player
|
|
10
|
+
local PlayerData = require("modules.exp_legacy.expcore.player_data") --- @dep expcore.player_data
|
|
11
|
+
local PlayerTags = PlayerData.Settings:combine("Tag")
|
|
12
|
+
local PlayerTagColors = PlayerData.Settings:combine("TagColor")
|
|
13
|
+
PlayerTags:set_metadata{
|
|
14
|
+
permission = "exp_scenario.command.tag",
|
|
15
|
+
}
|
|
16
|
+
PlayerTagColors:set_metadata{
|
|
17
|
+
permission = "exp_scenario.command.tag_color",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
local set_tag = function(player, tag, color)
|
|
21
|
+
if tag == nil or tag == "" then
|
|
22
|
+
player.tag = ""
|
|
23
|
+
elseif color then
|
|
24
|
+
player.tag = "- [color=" .. color .. "]" .. tag .. "[/color]"
|
|
25
|
+
else
|
|
26
|
+
player.tag = "- " .. tag
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
--- When your tag is updated then apply the changes
|
|
31
|
+
PlayerTags:on_update(function(player_name, player_tag)
|
|
32
|
+
local player = game.players[player_name]
|
|
33
|
+
local player_tag_color = PlayerTagColors:get(player)
|
|
34
|
+
|
|
35
|
+
set_tag(player, player_tag, player_tag_color)
|
|
36
|
+
end)
|
|
37
|
+
|
|
38
|
+
--- When your tag color is updated then apply the changes
|
|
39
|
+
PlayerTagColors:on_update(function(player_name, player_tag_color)
|
|
40
|
+
local player = game.players[player_name]
|
|
41
|
+
local player_tag = PlayerTags:get(player)
|
|
42
|
+
|
|
43
|
+
set_tag(player, player_tag, player_tag_color)
|
|
44
|
+
end)
|
|
45
|
+
|
|
46
|
+
--- Sets your player tag.
|
|
47
|
+
Commands.new("tag", "Sets your player tag.")
|
|
48
|
+
:argument("tag", "", Commands.types.string_max_length(20))
|
|
49
|
+
:enable_auto_concatenation()
|
|
50
|
+
:register(function(player, tag)
|
|
51
|
+
--- @cast tag string
|
|
52
|
+
PlayerTags:set(player, tag)
|
|
53
|
+
end)
|
|
54
|
+
|
|
55
|
+
--- Sets your player tag color.
|
|
56
|
+
Commands.new("tag-color", "Sets your player tag color.")
|
|
57
|
+
:argument("color", "", Commands.types.color)
|
|
58
|
+
:enable_auto_concatenation()
|
|
59
|
+
:register(function(player, color)
|
|
60
|
+
--- @cast color Color
|
|
61
|
+
PlayerTagColors:set(player, color)
|
|
62
|
+
end)
|
|
63
|
+
|
|
64
|
+
--- Clears your tag. Or another player if you are admin.
|
|
65
|
+
Commands.new("tag-clear", "Clears your tag. Or another player if you are admin.")
|
|
66
|
+
:optional("player", "", Commands.types.lower_role_player)
|
|
67
|
+
:defaults{
|
|
68
|
+
player = function(player) return player end
|
|
69
|
+
}
|
|
70
|
+
:register(function(player, other_player)
|
|
71
|
+
--- @cast other_player LuaPlayer
|
|
72
|
+
if other_player == player then
|
|
73
|
+
-- No player given so removes your tag
|
|
74
|
+
PlayerTags:remove(other_player)
|
|
75
|
+
elseif Roles.player_has_permission(player, "exp_scenario.command.tag_clear.always") then
|
|
76
|
+
-- Player given and user is admin so clears that player's tag
|
|
77
|
+
PlayerTags:remove(other_player)
|
|
78
|
+
else
|
|
79
|
+
-- User is not admin and tried to clear another users tag
|
|
80
|
+
return Commands.status.unauthorised()
|
|
81
|
+
end
|
|
82
|
+
end)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
local Gui = require("modules/exp_gui")
|
|
2
|
+
local PlayerData = require("modules.exp_legacy.expcore.player_data")
|
|
3
|
+
|
|
4
|
+
-- Used to store the state of the toolbar when a player leaves
|
|
5
|
+
local ToolbarState = PlayerData.Settings:combine("ToolbarState")
|
|
6
|
+
ToolbarState:set_metadata{
|
|
7
|
+
stringify = function()
|
|
8
|
+
return "Toolbar is saved on exit"
|
|
9
|
+
end,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
--- Uncompress the data to be more useable
|
|
13
|
+
ToolbarState:on_load(function(player_name, value)
|
|
14
|
+
-- If there is no value, do nothing
|
|
15
|
+
if value == nil then return end
|
|
16
|
+
-- Old format, we discard it [ string[], string[], string[], boolean ]
|
|
17
|
+
if type(value) ~= "string" then return end
|
|
18
|
+
|
|
19
|
+
local decompressed = helpers.json_to_table(assert(helpers.decode_string(value), "Failed String Decode"))
|
|
20
|
+
local player = assert(game.get_player(player_name))
|
|
21
|
+
Gui.toolbar.set_state(player, decompressed --[[@as Gui.ToolbarState]])
|
|
22
|
+
|
|
23
|
+
return nil -- We don't save the state, use Gui.toolbar.get_state
|
|
24
|
+
end)
|
|
25
|
+
|
|
26
|
+
--- Save the current state of the players toolbar menu
|
|
27
|
+
ToolbarState:on_save(function(player_name, _)
|
|
28
|
+
local player = assert(game.get_player(player_name))
|
|
29
|
+
local value = Gui.toolbar.get_state(player)
|
|
30
|
+
return helpers.encode_string(helpers.table_to_json(value))
|
|
31
|
+
end)
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
local Event = require("modules/exp_legacy/utils/event")
|
|
2
|
+
local general = require("modules.exp_legacy.modules.graftorio.general")
|
|
3
|
+
local config = require("modules.exp_legacy.config.graftorio")
|
|
4
|
+
|
|
5
|
+
local lib = {}
|
|
6
|
+
|
|
7
|
+
lib.collect_production = function()
|
|
8
|
+
for _, force in pairs(game.forces) do
|
|
9
|
+
general.data.output[force.name].production = {}
|
|
10
|
+
for _, surface in pairs(game.surfaces) do
|
|
11
|
+
--- @class ItemStats
|
|
12
|
+
--- @field count number
|
|
13
|
+
|
|
14
|
+
--- @class ProductionStatistics
|
|
15
|
+
--- @field item_input table<string, ItemStats>
|
|
16
|
+
--- @field item_output table<string, ItemStats>
|
|
17
|
+
--- @field fluid_input table<string, ItemStats>
|
|
18
|
+
--- @field fluid_output table<string, ItemStats>
|
|
19
|
+
--- @field kill_input table<string, ItemStats>
|
|
20
|
+
--- @field kill_output table<string, ItemStats>
|
|
21
|
+
--- @field build_input table<string, ItemStats>
|
|
22
|
+
--- @field build_output table<string, ItemStats>
|
|
23
|
+
local stats = {
|
|
24
|
+
item_input = {},
|
|
25
|
+
item_output = {},
|
|
26
|
+
fluid_input = {},
|
|
27
|
+
fluid_output = {},
|
|
28
|
+
kill_input = {},
|
|
29
|
+
kill_output = {},
|
|
30
|
+
build_input = {},
|
|
31
|
+
build_output = {},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for name, count in pairs(force.get_item_production_statistics(surface).input_counts) do
|
|
35
|
+
local itemstats = stats.item_input[name] or {}
|
|
36
|
+
itemstats.count = count
|
|
37
|
+
stats.item_input[name] = itemstats
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
for name, count in pairs(force.get_item_production_statistics(surface).output_counts) do
|
|
41
|
+
local itemstats = stats.item_output[name] or {}
|
|
42
|
+
itemstats.count = count
|
|
43
|
+
stats.item_output[name] = itemstats
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
for name, count in pairs(force.get_fluid_production_statistics(surface).input_counts) do
|
|
47
|
+
local fluidstats = stats.fluid_input[name] or {}
|
|
48
|
+
fluidstats.count = count
|
|
49
|
+
stats.fluid_input[name] = fluidstats
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
for name, count in pairs(force.get_fluid_production_statistics(surface).output_counts) do
|
|
53
|
+
local fluidstats = stats.fluid_output[name] or {}
|
|
54
|
+
fluidstats.count = count
|
|
55
|
+
stats.fluid_output[name] = fluidstats
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
for name, count in pairs(force.get_kill_count_statistics(surface).input_counts) do
|
|
59
|
+
local killstats = stats.kill_input[name] or {}
|
|
60
|
+
killstats.count = count
|
|
61
|
+
stats.kill_input[name] = killstats
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
for name, count in pairs(force.get_kill_count_statistics(surface).output_counts) do
|
|
65
|
+
local killstats = stats.kill_output[name] or {}
|
|
66
|
+
killstats.count = count
|
|
67
|
+
stats.kill_output[name] = killstats
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
for name, count in pairs(force.get_entity_build_count_statistics(surface).input_counts) do
|
|
71
|
+
local buildstats = stats.build_input[name] or {}
|
|
72
|
+
buildstats.count = count
|
|
73
|
+
stats.build_input[name] = buildstats
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
for name, count in pairs(force.get_entity_build_count_statistics(surface).output_counts) do
|
|
77
|
+
local buildstats = stats.build_output[name] or {}
|
|
78
|
+
buildstats.count = count
|
|
79
|
+
stats.build_output[name] = buildstats
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
general.data.output[force.name].production[surface.name] = stats
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
lib.collect_loginet = function()
|
|
88
|
+
for _, force in pairs(game.forces) do
|
|
89
|
+
--- @class RobotStatistics
|
|
90
|
+
--- @field all_construction_robots uint
|
|
91
|
+
--- @field available_construction_robot uint
|
|
92
|
+
--- @field all_logistic_robots uint
|
|
93
|
+
--- @field available_logistic_robots uint
|
|
94
|
+
--- @field charging_robot_count uint
|
|
95
|
+
--- @field to_charge_robot_count uint
|
|
96
|
+
--- @field items table<string, uint>
|
|
97
|
+
--- @field pickups table<string, uint>
|
|
98
|
+
--- @field deliveries table<string, uint>
|
|
99
|
+
local stats = {
|
|
100
|
+
all_construction_robots = 0,
|
|
101
|
+
available_construction_robots = 0,
|
|
102
|
+
|
|
103
|
+
all_logistic_robots = 0,
|
|
104
|
+
available_logistic_robots = 0,
|
|
105
|
+
|
|
106
|
+
charging_robot_count = 0,
|
|
107
|
+
to_charge_robot_count = 0,
|
|
108
|
+
|
|
109
|
+
items = {},
|
|
110
|
+
pickups = {},
|
|
111
|
+
deliveries = {},
|
|
112
|
+
}
|
|
113
|
+
for _, networks in pairs(force.logistic_networks) do
|
|
114
|
+
for _, network in pairs(networks) do
|
|
115
|
+
stats.available_construction_robots = network.available_construction_robots
|
|
116
|
+
stats.all_construction_robots = network.all_construction_robots
|
|
117
|
+
|
|
118
|
+
stats.available_logistic_robots = network.available_logistic_robots
|
|
119
|
+
stats.all_logistic_robots = network.all_logistic_robots
|
|
120
|
+
|
|
121
|
+
stats.charging_robot_count = 0
|
|
122
|
+
stats.to_charge_robot_count = 0
|
|
123
|
+
for _, cell in pairs(network.cells) do
|
|
124
|
+
stats.charging_robot_count = (stats.charging_robot_count) + cell.charging_robot_count
|
|
125
|
+
stats.to_charge_robot_count = (stats.to_charge_robot_count) + cell.to_charge_robot_count
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
if config.modules.logistorage then
|
|
129
|
+
for _, item in pairs(network.get_contents()) do
|
|
130
|
+
stats.items[item.name] = (stats.items[item.name] or 0) + item.count
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
-- pickups and deliveries of items
|
|
134
|
+
for _, point_list in pairs{ network.provider_points, network.requester_points, network.storage_points } do
|
|
135
|
+
for _, point in pairs(point_list) do
|
|
136
|
+
for _, item in pairs(point.targeted_items_pickup) do
|
|
137
|
+
stats.pickups[item.name] = (stats.pickups[item.name] or 0) + item.count
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
for _, item in pairs(point.targeted_items_deliver) do
|
|
141
|
+
stats.deliveries[item.name] = (stats.deliveries[item.name] or 0) + item.count
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
general.data.output[force.name].robots = stats
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
--- @class Research
|
|
154
|
+
--- @field name string
|
|
155
|
+
--- @field level uint
|
|
156
|
+
--- @field progress double
|
|
157
|
+
|
|
158
|
+
Event.add(defines.events.on_research_finished, function(evt)
|
|
159
|
+
local research = evt.research
|
|
160
|
+
if not general.data.output[research.force.name] then general.data.output[research.force.name] = {} end
|
|
161
|
+
if not general.data.output[research.force.name].research then general.data.output[research.force.name].research = {} end
|
|
162
|
+
|
|
163
|
+
local force_research = general.data.output[research.force.name].research or {}
|
|
164
|
+
table.remove(force_research, 1)
|
|
165
|
+
general.data.output[research.force.name].research = force_research
|
|
166
|
+
end)
|
|
167
|
+
|
|
168
|
+
Event.add(defines.events.on_research_started, function(evt)
|
|
169
|
+
-- move queue up
|
|
170
|
+
local research = evt.research
|
|
171
|
+
if not general.data.output[research.force.name].research then general.data.output[research.force.name].research = {} end
|
|
172
|
+
|
|
173
|
+
local force_research = general.data.output[research.force.name].research or {}
|
|
174
|
+
table.remove(force_research, 1)
|
|
175
|
+
general.data.output[research.force.name].research = force_research
|
|
176
|
+
end)
|
|
177
|
+
|
|
178
|
+
Event.on_nth_tick(60, function()
|
|
179
|
+
for _, force in pairs(game.forces) do
|
|
180
|
+
if not general.data.output[force.name].research then general.data.output[force.name].research = {} end
|
|
181
|
+
|
|
182
|
+
local force_research = {}
|
|
183
|
+
-- this works even if the queue is disabled, but it will always be just 1 long in that case
|
|
184
|
+
for _, research in pairs(force.research_queue) do
|
|
185
|
+
table.insert(force_research, {
|
|
186
|
+
name = research.name,
|
|
187
|
+
level = research.level,
|
|
188
|
+
progress = force.technologies[research.name].saved_progress
|
|
189
|
+
})
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
general.data.output[force.name].research = force_research
|
|
193
|
+
end
|
|
194
|
+
end)
|
|
195
|
+
|
|
196
|
+
return lib
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
local Event = require("modules/exp_legacy/utils/event")
|
|
2
|
+
local Storage = require("modules/exp_util/storage")
|
|
3
|
+
|
|
4
|
+
local lib = {}
|
|
5
|
+
|
|
6
|
+
lib.data = {
|
|
7
|
+
output = {},
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Storage.register(lib.data, function(tbl)
|
|
11
|
+
lib.data = tbl
|
|
12
|
+
end)
|
|
13
|
+
|
|
14
|
+
--- @class Statistics
|
|
15
|
+
--- @field production ProductionStatistics?
|
|
16
|
+
--- @field robots RobotStatistics?
|
|
17
|
+
--- @field other OtherStatistics?
|
|
18
|
+
--- @field research Research[]?
|
|
19
|
+
|
|
20
|
+
Event.on_init(function()
|
|
21
|
+
--- @type table<string, Statistics>
|
|
22
|
+
lib.data.output = {}
|
|
23
|
+
for _, force in pairs(game.forces) do
|
|
24
|
+
lib.data.output[force.name] = {}
|
|
25
|
+
end
|
|
26
|
+
end)
|
|
27
|
+
|
|
28
|
+
--- @class OtherStatistics
|
|
29
|
+
--- @field tick uint
|
|
30
|
+
--- @field evolution EvolutionStatistics
|
|
31
|
+
|
|
32
|
+
--- @class EvolutionStatistics
|
|
33
|
+
--- @field evolution_factor double
|
|
34
|
+
--- @field evolution_factor_by_pollution double
|
|
35
|
+
--- @field evolution_factor_by_time double
|
|
36
|
+
--- @field evolution_factor_by_killing_spawners double
|
|
37
|
+
|
|
38
|
+
lib.collect_other = function()
|
|
39
|
+
for _, force in pairs(game.forces) do
|
|
40
|
+
--- @type OtherStatistics
|
|
41
|
+
local other = lib.data.output[force.name].other or {}
|
|
42
|
+
|
|
43
|
+
other.evolution = {
|
|
44
|
+
evolution_factor = force.get_evolution_factor(game.surfaces[1]),
|
|
45
|
+
evolution_factor_by_pollution = force.get_evolution_factor_by_pollution(game.surfaces[1]),
|
|
46
|
+
evolution_factor_by_time = force.get_evolution_factor_by_time(game.surfaces[1]),
|
|
47
|
+
evolution_factor_by_killing_spawners = force.get_evolution_factor_by_killing_spawners(game.surfaces[1]),
|
|
48
|
+
}
|
|
49
|
+
for k, v in pairs(other) do
|
|
50
|
+
lib.data.output[force.name].other[k] = v
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
Event.add(defines.events.on_force_created, function(evt)
|
|
56
|
+
lib.data.output[evt.force.name] = {}
|
|
57
|
+
end)
|
|
58
|
+
|
|
59
|
+
Event.add(defines.events.on_forces_merged, function(evt)
|
|
60
|
+
lib.data.output[evt.source_name] = nil
|
|
61
|
+
end)
|
|
62
|
+
|
|
63
|
+
return lib
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
local Commands = require("modules/exp_commands")
|
|
2
|
+
local config = require("modules.exp_legacy.config.graftorio")
|
|
3
|
+
local statics = require("modules.exp_legacy.modules.graftorio.statics")
|
|
4
|
+
local general = require("modules.exp_legacy.modules.graftorio.general")
|
|
5
|
+
local forcestats = nil
|
|
6
|
+
|
|
7
|
+
local table_to_json = helpers.table_to_json
|
|
8
|
+
|
|
9
|
+
if config.modules.forcestats then
|
|
10
|
+
forcestats = require("modules.exp_legacy.modules.graftorio.forcestats")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
Commands.new("collectdata", "Collect data for RCON usage")
|
|
14
|
+
:optional("location", "", Commands.types.string) -- Not sure what this is for, i didn't write this
|
|
15
|
+
:register(function()
|
|
16
|
+
-- this must be first as it overwrites the stats
|
|
17
|
+
-- also makes the .other table for all forces
|
|
18
|
+
statics.collect_statics()
|
|
19
|
+
if config.modules.other then
|
|
20
|
+
general.collect_other()
|
|
21
|
+
end
|
|
22
|
+
if config.modules.forcestats then
|
|
23
|
+
--- @cast forcestats -nil
|
|
24
|
+
forcestats.collect_production()
|
|
25
|
+
forcestats.collect_loginet()
|
|
26
|
+
end
|
|
27
|
+
return Commands.status.success(table_to_json(general.data.output))
|
|
28
|
+
end)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
local general = require("modules.exp_legacy.modules.graftorio.general")
|
|
2
|
+
|
|
3
|
+
local lib = {}
|
|
4
|
+
|
|
5
|
+
--- @class StaticStatistics
|
|
6
|
+
--- @field tick uint
|
|
7
|
+
--- @field online_players string[]
|
|
8
|
+
--- @field mods table<string, string>
|
|
9
|
+
--- @field seed table<string, uint>
|
|
10
|
+
|
|
11
|
+
lib.collect_statics = function()
|
|
12
|
+
local stats = {}
|
|
13
|
+
stats.tick = game.tick
|
|
14
|
+
|
|
15
|
+
stats.online_players = {}
|
|
16
|
+
for _, player in pairs(game.connected_players) do
|
|
17
|
+
table.insert(stats.online_players, player.name)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
stats.mods = {}
|
|
21
|
+
for name, version in pairs(script.active_mods) do
|
|
22
|
+
stats.mods[name] = version
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
-- reason behind this is that the map gen settings can be changed during runtime so just get them fresh
|
|
26
|
+
stats.seed = {}
|
|
27
|
+
for _, surface in pairs(game.surfaces) do
|
|
28
|
+
stats.seed[surface.name] = surface.map_gen_settings.seed
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
for _, force in pairs(game.forces) do
|
|
32
|
+
general.data.output[force.name].other = stats
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
return lib
|