diff --git a/docs/contributing.md b/docs/contributing.md index 21d91386..df8bfb8b 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -224,9 +224,9 @@ JavaScript template literals may also be used where appropriate. ### Indenting -JavaScript code should be indented with tabs. +JavaScript and Lua code should be indented with tabs. -Lua code should be indented with 4 spaces. +Other files types should prefer tabs for indents where reasonable with the exception of Markdown. ### Line Length diff --git a/docs/jsdoc.json b/docs/jsdoc.json index 8752694b..4a90978a 100644 --- a/docs/jsdoc.json +++ b/docs/jsdoc.json @@ -1,23 +1,23 @@ { - "plugins": [ - "plugins/markdown" - ], - "tags": { - "allowUnknownTags": false - }, - "opts": { - "destination": "docs/api", - "recurse": true - }, - "source": { - "include": [ - "packages/master/src/", - "packages/master/master.js", - "packages/slave/slave.js", - "packages/ctl/ctl.js", - "packages/lib/", - "plugins/" - ], - "excludePattern": "node_modules" - } + "plugins": [ + "plugins/markdown" + ], + "tags": { + "allowUnknownTags": false + }, + "opts": { + "destination": "docs/api", + "recurse": true + }, + "source": { + "include": [ + "packages/master/src/", + "packages/master/master.js", + "packages/slave/slave.js", + "packages/ctl/ctl.js", + "packages/lib/", + "plugins/" + ], + "excludePattern": "node_modules" + } } diff --git a/packages/master/web/index.html b/packages/master/web/index.html index 77dedfc5..ba9bbf02 100644 --- a/packages/master/web/index.html +++ b/packages/master/web/index.html @@ -1,17 +1,17 @@ - - - - - Clusterio - - - - -
- - + + + + + Clusterio + + + + +
+ + diff --git a/packages/slave/lua/clusterio_lib/api.lua b/packages/slave/lua/clusterio_lib/api.lua index c800b035..90b121e3 100644 --- a/packages/slave/lua/clusterio_lib/api.lua +++ b/packages/slave/lua/clusterio_lib/api.lua @@ -4,63 +4,63 @@ local api = {} local initialized = false function api.init() - if initialized then - return - end - initialized = true + if initialized then + return + end + initialized = true - if remote.interfaces.clusterio_api then - api.events = remote.call("clusterio_api", "get_events") - else - local null_event = script.generate_event_name() - api.events = { - on_instance_updated = null_event, - on_server_startup = null_event, - } - end + if remote.interfaces.clusterio_api then + api.events = remote.call("clusterio_api", "get_events") + else + local null_event = script.generate_event_name() + api.events = { + on_instance_updated = null_event, + on_server_startup = null_event, + } + end end local function call_api(fn, ...) - if remote.interfaces.clusterio_api and remote.interfaces.clusterio_api[fn] then - return remote.call("clusterio_api", fn, ...) - else - return nil - end + if remote.interfaces.clusterio_api and remote.interfaces.clusterio_api[fn] then + return remote.call("clusterio_api", fn, ...) + else + return nil + end end function api.get_instance_name() - return call_api("get_instance_name") + return call_api("get_instance_name") end function api.get_instance_id() - return call_api("get_instance_id") + return call_api("get_instance_id") end function api.send_json(channel, data) - if not remote.interfaces.clusterio_api then - return - end + if not remote.interfaces.clusterio_api then + return + end - -- Escape bad characters. The question mark is used for separating the - -- channel name from the payload. - channel = channel:gsub("([\x00-\x1f?\\])", function(match) - return "\\x" .. string.format("%02x", match:byte()) - end) + -- Escape bad characters. The question mark is used for separating the + -- channel name from the payload. + channel = channel:gsub("([\x00-\x1f?\\])", function(match) + return "\\x" .. string.format("%02x", match:byte()) + end) - data = game.table_to_json(data) + data = game.table_to_json(data) - -- If there's more than about 4kB of data users running with the Windows - -- console open will start to experience stuttering, otherwise we could - -- output about 1 MB of data at a time through stdout. - if #data < 4000 then - print("\f$ipc:" .. channel .. "?j" .. data) - else - local file_no = remote.call("clusterio_api", "get_file_no") - local file_name = "clst_" .. file_no .. ".json" - game.write_file(file_name, data, false, 0) - print("\f$ipc:" .. channel .. "?f" .. file_name) - end + -- If there's more than about 4kB of data users running with the Windows + -- console open will start to experience stuttering, otherwise we could + -- output about 1 MB of data at a time through stdout. + if #data < 4000 then + print("\f$ipc:" .. channel .. "?j" .. data) + else + local file_no = remote.call("clusterio_api", "get_file_no") + local file_name = "clst_" .. file_no .. ".json" + game.write_file(file_name, data, false, 0) + print("\f$ipc:" .. channel .. "?f" .. file_name) + end end diff --git a/packages/slave/lua/clusterio_lib/info.json b/packages/slave/lua/clusterio_lib/info.json index 1f387fa0..5afc7b4f 100644 --- a/packages/slave/lua/clusterio_lib/info.json +++ b/packages/slave/lua/clusterio_lib/info.json @@ -1,24 +1,24 @@ { - "name": "clusterio_lib", - "variants": [ - { - "version": "0.1.0", - "factorio_version": "0.17" - }, - { - "version": "0.1.1", - "factorio_version": "0.18" - }, - { - "version": "0.1.2", - "factorio_version": "1.1" - } - ], - "title": "Clusterio Library (Alpha)", - "author": "Clusterio Team", - "homepage": "https://github.com/clusterio/clusterio", - "description": "Library for interfacing with Clusterio. Warning: work in progress alpha.", - "additional_files": { - "serialize.lua": ["..", "..", "modules", "clusterio", "serialize.lua"] - } + "name": "clusterio_lib", + "variants": [ + { + "version": "0.1.0", + "factorio_version": "0.17" + }, + { + "version": "0.1.1", + "factorio_version": "0.18" + }, + { + "version": "0.1.2", + "factorio_version": "1.1" + } + ], + "title": "Clusterio Library (Alpha)", + "author": "Clusterio Team", + "homepage": "https://github.com/clusterio/clusterio", + "description": "Library for interfacing with Clusterio. Warning: work in progress alpha.", + "additional_files": { + "serialize.lua": ["..", "..", "modules", "clusterio", "serialize.lua"] + } } diff --git a/packages/slave/lua/export/control.lua b/packages/slave/lua/export/control.lua index 5c70f36e..4d27f895 100644 --- a/packages/slave/lua/export/control.lua +++ b/packages/slave/lua/export/control.lua @@ -1,8 +1,8 @@ local function send_json(channel, data) - data = game.table_to_json(data) - print("\f$ipc:" .. channel .. "?j" .. data) + data = game.table_to_json(data) + print("\f$ipc:" .. channel .. "?j" .. data) end script.on_init(function() - send_json("mod_list", game.active_mods) + send_json("mod_list", game.active_mods) end) diff --git a/packages/slave/lua/export/data-final-fixes.lua b/packages/slave/lua/export/data-final-fixes.lua index 335ac5c1..991bb831 100644 --- a/packages/slave/lua/export/data-final-fixes.lua +++ b/packages/slave/lua/export/data-final-fixes.lua @@ -1,104 +1,104 @@ local item_types = { - -- Item categories - "item", - "ammo", - "capsule", - "gun", - "item-with-entity-data", - "item-with-label", - "item-with-inventory", - "blueprint-book", - "item-with-tags", - "selection-tool", - "blueprint", - "deconstruction-item", - "copy-paste-tool", - "upgrade-item", - "module", - "rail-planner", - "tool", - "armor", - "mining-tool", - "repair-tool", + -- Item categories + "item", + "ammo", + "capsule", + "gun", + "item-with-entity-data", + "item-with-label", + "item-with-inventory", + "blueprint-book", + "item-with-tags", + "selection-tool", + "blueprint", + "deconstruction-item", + "copy-paste-tool", + "upgrade-item", + "module", + "rail-planner", + "tool", + "armor", + "mining-tool", + "repair-tool", - -- Fluids - "fluid", + -- Fluids + "fluid", } local function is_array(t) - local count = 0 - for k in pairs(t) do - if type(k) ~= "number" then - return false - end - count = count + 1 - end + local count = 0 + for k in pairs(t) do + if type(k) ~= "number" then + return false + end + count = count + 1 + end - for i = 1, count do - if not t[i] then - return false - end - end + for i = 1, count do + if not t[i] then + return false + end + end - return count ~= 0 + return count ~= 0 end -- no game.table_to_json here :( local function table_to_json(data) - if type(data) == "number" then + if type(data) == "number" then if data == math.huge then return "1e500" end -- Inf is not representable in JSON, but 1e500 will overflow to it. if data == -math.huge then return "-1e500" end if data ~= data then return "0" end -- NaN is not representable in JSON, treat as 0 instead. - return string.format("%.17g", data) + return string.format("%.17g", data) - elseif type(data) == "string" then - data = data:gsub('([\x00-\x1f\\"])', function(match) - return "\\u00" .. string.format("%02x", match:byte()) - end) - return '"' .. data .. '"' + elseif type(data) == "string" then + data = data:gsub('([\x00-\x1f\\"])', function(match) + return "\\u00" .. string.format("%02x", match:byte()) + end) + return '"' .. data .. '"' - elseif data == nil then - return "null" + elseif data == nil then + return "null" - elseif data == true then - return "true" - elseif data == false then - return "false" + elseif data == true then + return "true" + elseif data == false then + return "false" - elseif type(data) == "table" then - local r - if is_array(data) then - r = {"["} - for i=1, #data do - r[#r+1] = table_to_json(data[i]) - r[#r+1] = "," - end + elseif type(data) == "table" then + local r + if is_array(data) then + r = {"["} + for i=1, #data do + r[#r+1] = table_to_json(data[i]) + r[#r+1] = "," + end - -- overwrite last comma, empty table is an object - r[#r] = "]" + -- overwrite last comma, empty table is an object + r[#r] = "]" - else - r = {"{"} - for k, v in pairs(data) do - r[#r+1] = table_to_json(tostring(k)) - r[#r+1] = ":" - r[#r+1] = table_to_json(v) - r[#r+1] = "," - end - r[#r + (r[#r] == "," and 0 or 1)] = "}" - end + else + r = {"{"} + for k, v in pairs(data) do + r[#r+1] = table_to_json(tostring(k)) + r[#r+1] = ":" + r[#r+1] = table_to_json(v) + r[#r+1] = "," + end + r[#r + (r[#r] == "," and 0 or 1)] = "}" + end - return table.concat(r) - end + return table.concat(r) + end end local function send_json(channel, data) - data = table_to_json(data) - print("\f$ipc:" .. channel .. "?j" .. data) + data = table_to_json(data) + print("\f$ipc:" .. channel .. "?j" .. data) end for _, group in ipairs(item_types) do - for _, item in pairs(data.raw[group]) do - send_json("item_export", item) - end + for _, item in pairs(data.raw[group]) do + send_json("item_export", item) + end end diff --git a/packages/slave/lua/export/info.json b/packages/slave/lua/export/info.json index cb87c168..ed4b7195 100644 --- a/packages/slave/lua/export/info.json +++ b/packages/slave/lua/export/info.json @@ -1,8 +1,8 @@ { - "name": "export", - "version": "0.0.0", - "title": "Icon exporter", - "author": "Clusterio Team", - "homepage": "https://github.com/clusterio/clusterio", - "description": "Exports item prototypes on stdout during the data stage." + "name": "export", + "version": "0.0.0", + "title": "Icon exporter", + "author": "Clusterio Team", + "homepage": "https://github.com/clusterio/clusterio", + "description": "Exports item prototypes on stdout during the data stage." } diff --git a/packages/slave/modules/clusterio/api.lua b/packages/slave/modules/clusterio/api.lua index f0e932dd..08e7fbf1 100644 --- a/packages/slave/modules/clusterio/api.lua +++ b/packages/slave/modules/clusterio/api.lua @@ -3,39 +3,39 @@ local api = {} api.events = { - on_instance_updated = script.generate_event_name(), - on_server_startup = script.generate_event_name(), + on_instance_updated = script.generate_event_name(), + on_server_startup = script.generate_event_name(), } function api.get_instance_name() - return global.clusterio.instance_name + return global.clusterio.instance_name end function api.get_instance_id() - return global.clusterio.instance_id + return global.clusterio.instance_id end function api.send_json(channel, data) - -- Escape bad characters. The question mark is used for separating the - -- channel name from the payload. - channel = channel:gsub("([\x00-\x1f?\\])", function(match) - return "\\x" .. string.format("%02x", match:byte()) - end) + -- Escape bad characters. The question mark is used for separating the + -- channel name from the payload. + channel = channel:gsub("([\x00-\x1f?\\])", function(match) + return "\\x" .. string.format("%02x", match:byte()) + end) - data = game.table_to_json(data) + data = game.table_to_json(data) - -- If there's more than about 4kB of data users running with the Windows - -- console open will start to experience stuttering, otherwise we could - -- output about 1 MB of data at a time through stdout. - if #data < 4000 then - print("\f$ipc:" .. channel .. "?j" .. data) - else - global.clusterio_file_no = (global.clusterio_file_no or 0) + 1 - local file_name = "clst_" .. global.clusterio_file_no .. ".json" - game.write_file(file_name, data, false, 0) - print("\f$ipc:" .. channel .. "?f" .. file_name) - end + -- If there's more than about 4kB of data users running with the Windows + -- console open will start to experience stuttering, otherwise we could + -- output about 1 MB of data at a time through stdout. + if #data < 4000 then + print("\f$ipc:" .. channel .. "?j" .. data) + else + global.clusterio_file_no = (global.clusterio_file_no or 0) + 1 + local file_name = "clst_" .. global.clusterio_file_no .. ".json" + game.write_file(file_name, data, false, 0) + print("\f$ipc:" .. channel .. "?f" .. file_name) + end end diff --git a/packages/slave/modules/clusterio/impl.lua b/packages/slave/modules/clusterio/impl.lua index 96164e22..ee936ab2 100644 --- a/packages/slave/modules/clusterio/impl.lua +++ b/packages/slave/modules/clusterio/impl.lua @@ -5,69 +5,69 @@ local impl = {} impl.events = {} impl.events[defines.events.on_tick] = function() - if global.clusterio_patch_number ~= clusterio_patch_number then - global.clusterio_patch_number = clusterio_patch_number - script.raise_event(api.events.on_server_startup, {}) - end + if global.clusterio_patch_number ~= clusterio_patch_number then + global.clusterio_patch_number = clusterio_patch_number + script.raise_event(api.events.on_server_startup, {}) + end end impl.events[api.events.on_server_startup] = function() - if not global.clusterio then - global.clusterio = { - instance_id = nil, - instance_name = nil, - } - end + if not global.clusterio then + global.clusterio = { + instance_id = nil, + instance_name = nil, + } + end - -- Replay will just desync after the save is patched - game.disable_replay() + -- Replay will just desync after the save is patched + game.disable_replay() end impl.events[defines.events.on_player_joined_game] = function(event) - local player = game.players[event.player_index] - api.send_json("player_event", { type = "join", name = player.name }) + local player = game.players[event.player_index] + api.send_json("player_event", { type = "join", name = player.name }) end impl.events[defines.events.on_player_left_game] = function(event) - local player = game.players[event.player_index] - api.send_json("player_event", { type = "leave", name = player.name }) + local player = game.players[event.player_index] + api.send_json("player_event", { type = "leave", name = player.name }) end -- Internal API clusterio_private = {} function clusterio_private.update_instance(new_id, new_name) - global.clusterio.instance_id = new_id - global.clusterio.instance_name = new_name - script.raise_event(api.events.on_instance_updated, { - instance_id = new_id, - instance_name = new_name, - }) + global.clusterio.instance_id = new_id + global.clusterio.instance_name = new_name + script.raise_event(api.events.on_instance_updated, { + instance_id = new_id, + instance_name = new_name, + }) end -- This is not part of the add_remote_interface callback to ensure it is --- available when the clusterio_lib mod is loaded. The reason this is +-- available when the clusterio_lib mod is loaded. The reason this is -- neccessary is that on_init for newly added mods happen before on_load -- for existing mods, and the add_remote_interface callback is done in -- on_load. See https://forums.factorio.com/viewtopic.php?f=25&t=81552 for -- more details. remote.add_interface('clusterio_api', { - get_events = function() - return api.events - end, + get_events = function() + return api.events + end, - get_instance_id = function() - return global.clusterio.instance_id - end, + get_instance_id = function() + return global.clusterio.instance_id + end, - get_instance_name = function() - return global.clusterio.instance_name - end, + get_instance_name = function() + return global.clusterio.instance_name + end, - get_file_no = function() - global.clusterio_file_no = (global.clusterio_file_no or 0) + 1 - return global.clusterio_file_no - end, + get_file_no = function() + global.clusterio_file_no = (global.clusterio_file_no or 0) + 1 + return global.clusterio_file_no + end, }) diff --git a/packages/slave/modules/clusterio/module.json b/packages/slave/modules/clusterio/module.json index 5ba34a15..81dd7b1f 100644 --- a/packages/slave/modules/clusterio/module.json +++ b/packages/slave/modules/clusterio/module.json @@ -1,6 +1,6 @@ { - "name": "clusterio", - "version": "0.0.0", - "dependencies": {}, - "load": ["impl.lua"] + "name": "clusterio", + "version": "0.0.0", + "dependencies": {}, + "load": ["impl.lua"] } diff --git a/packages/slave/modules/clusterio/serialize.lua b/packages/slave/modules/clusterio/serialize.lua index 434a7fd2..ce937eb4 100644 --- a/packages/slave/modules/clusterio/serialize.lua +++ b/packages/slave/modules/clusterio/serialize.lua @@ -3,38 +3,38 @@ local serialize = {} local function version_to_table(version) - local t = {} - for p in string.gmatch(version, "%d+") do - t[#t + 1] = tonumber(p) - end - return t + local t = {} + for p in string.gmatch(version, "%d+") do + t[#t + 1] = tonumber(p) + end + return t end -- 0.17 compatibility local supports_bar, get_bar, has_bar, version if (pcall(function() local mods = script.active_mods end)) then - supports_bar = "supports_bar" - get_bar = "get_bar" - set_bar = "set_bar" - version = version_to_table(script.active_mods.base) + supports_bar = "supports_bar" + get_bar = "get_bar" + set_bar = "set_bar" + version = version_to_table(script.active_mods.base) else - supports_bar = "hasbar" - get_bar = "getbar" - set_bar = "setbar" - version = version_to_table("0.17.69") + supports_bar = "hasbar" + get_bar = "getbar" + set_bar = "setbar" + version = version_to_table("0.17.69") end -- returns true if the game version is greater than or equal to the given version local function version_ge(comp) - comp = version_to_table(comp) - for i=1, 3 do - if comp[i] > version[i] then - return false - elseif comp[i] < version[i] then - return true - end - end - return true + comp = version_to_table(comp) + for i=1, 3 do + if comp[i] > version[i] then + return false + elseif comp[i] < version[i] then + return true + end + end + return true end local has_create_grid = version_ge("1.1.7") @@ -42,265 +42,265 @@ local has_create_grid = version_ge("1.1.7") -- Equipment Grids are serialized into an array of equipment entries -- where ench entry is a table with the following fields: --- n: name --- p: position (array of 2 numbers corresponding to x and y) --- s: shield (optional) --- e: energy (optional) +-- n: name +-- p: position (array of 2 numbers corresponding to x and y) +-- s: shield (optional) +-- e: energy (optional) -- If the equipment is a burner the following is also present: --- i: burner inventory --- r: result inventory --- b: curently burning (optional) --- f: remaining_burning_fuel (optional) +-- i: burner inventory +-- r: result inventory +-- b: curently burning (optional) +-- f: remaining_burning_fuel (optional) function serialize.serialize_equipment_grid(grid) - local serialized = {} - local processed = {} - for y = 0, grid.height - 1 do - for x = 0, grid.width - 1 do - local equipment = grid.get({x, y}) - if equipment ~= nil then - local pos = equipment.position - local combined_pos = pos.x + pos.y * grid.width + 1 - if not processed[combined_pos] then - processed[combined_pos] = true - local entry = { - n = equipment.name, - p = {pos.x, pos.y}, - } - if equipment.shield > 0 then entry.s = equipment.shield end - if equipment.energy > 0 then entry.e = equipment.energy end - -- TODO: Test with Industrial Revolution - if equipment.burner then - local burner = equipment.burner - entry.i = serialize.serialize_inventory(burner.inventory) - entry.r = serialize.serialize_inventory(burner.burnt_result_inventory) - if burner.curently_burning then - entry.b = {} - serialize.serialize_item_stack(burner.curently_burning, entry.b) - entry.f = burner.remaining_burning_fuel - end - end - table.insert(serialized, entry) - end - end - end - end - return serialized + local serialized = {} + local processed = {} + for y = 0, grid.height - 1 do + for x = 0, grid.width - 1 do + local equipment = grid.get({x, y}) + if equipment ~= nil then + local pos = equipment.position + local combined_pos = pos.x + pos.y * grid.width + 1 + if not processed[combined_pos] then + processed[combined_pos] = true + local entry = { + n = equipment.name, + p = {pos.x, pos.y}, + } + if equipment.shield > 0 then entry.s = equipment.shield end + if equipment.energy > 0 then entry.e = equipment.energy end + -- TODO: Test with Industrial Revolution + if equipment.burner then + local burner = equipment.burner + entry.i = serialize.serialize_inventory(burner.inventory) + entry.r = serialize.serialize_inventory(burner.burnt_result_inventory) + if burner.curently_burning then + entry.b = {} + serialize.serialize_item_stack(burner.curently_burning, entry.b) + entry.f = burner.remaining_burning_fuel + end + end + table.insert(serialized, entry) + end + end + end + end + return serialized end function serialize.deserialize_equipment_grid(grid, serialized) - grid.clear() - for _, entry in ipairs(serialized) do - local equipment = grid.put({ - name = entry.n, - position = entry.p, - }) - if equipment then - if entry.s then equipment.shield = entry.s end - if entry.e then equipment.energy = entry.e end - if entry.i then - if entry.b then serialize.deserialize_item_stack(burner.currently_burning, entry.b) end - if entry.f then burner.remaining_burning_fuel = entry.f end - serialize.deserialize_inventory(burner.burnt_result_inventory, entry.r) - serialize.deserialize_inventory(burner.inventory, entry.i) - end - end - end + grid.clear() + for _, entry in ipairs(serialized) do + local equipment = grid.put({ + name = entry.n, + position = entry.p, + }) + if equipment then + if entry.s then equipment.shield = entry.s end + if entry.e then equipment.energy = entry.e end + if entry.i then + if entry.b then serialize.deserialize_item_stack(burner.currently_burning, entry.b) end + if entry.f then burner.remaining_burning_fuel = entry.f end + serialize.deserialize_inventory(burner.burnt_result_inventory, entry.r) + serialize.deserialize_inventory(burner.inventory, entry.i) + end + end + end end -- Item stacks are serialized into a table with the following fields: --- n: name --- c: count --- h: health (optional) --- d: durability (optional) --- a: ammo count (optional) --- l: label (optional) --- g: equipment grid (optional) --- i: item inventory (optional) +-- n: name +-- c: count +-- h: health (optional) +-- d: durability (optional) +-- a: ammo count (optional) +-- l: label (optional) +-- g: equipment grid (optional) +-- i: item inventory (optional) -- If the item stack is exportable it has the following property instead --- e: export string +-- e: export string -- Label is a table with the following fields: --- t: label text (optional) --- c: color (optional) --- a: allow manual label change +-- t: label text (optional) +-- c: color (optional) +-- a: allow manual label change function serialize.serialize_item_stack(slot, entry) - if - slot.is_blueprint - or slot.is_blueprint_book - or slot.is_upgrade_item - or slot.is_deconstruction_item - or slot.is_item_with_tags - then - local call_success, call_return = pcall(slot.export_stack) - if not call_success then - print("Error: '" .. call_return .. "' thrown exporting '" .. slot.name .. "'") - else - entry.e = call_return - end + if + slot.is_blueprint + or slot.is_blueprint_book + or slot.is_upgrade_item + or slot.is_deconstruction_item + or slot.is_item_with_tags + then + local call_success, call_return = pcall(slot.export_stack) + if not call_success then + print("Error: '" .. call_return .. "' thrown exporting '" .. slot.name .. "'") + else + entry.e = call_return + end - return - end + return + end - entry.n = slot.name - entry.c = slot.count - if slot.health < 1 then entry.h = slot.health end - if slot.durability then entry.d = slot.durability end - if slot.type == "ammo" then entry.a = slot.ammo end - if slot.is_item_with_label then - local label = {} - if slot.label then label.t = slot.label end - if slot.label_color then label.c = slot.label_color end - label.a = slot.allow_manual_label_change - entry.l = label - end + entry.n = slot.name + entry.c = slot.count + if slot.health < 1 then entry.h = slot.health end + if slot.durability then entry.d = slot.durability end + if slot.type == "ammo" then entry.a = slot.ammo end + if slot.is_item_with_label then + local label = {} + if slot.label then label.t = slot.label end + if slot.label_color then label.c = slot.label_color end + label.a = slot.allow_manual_label_change + entry.l = label + end - if slot.grid then - entry.g = serialize.serialize_equipment_grid(slot.grid) - end + if slot.grid then + entry.g = serialize.serialize_equipment_grid(slot.grid) + end - if slot.is_item_with_inventory then - local sub_inventory = slot.get_inventory(defines.inventory.item_main) - entry.i = serialize.serialize_inventory(sub_inventory) - end + if slot.is_item_with_inventory then + local sub_inventory = slot.get_inventory(defines.inventory.item_main) + entry.i = serialize.serialize_inventory(sub_inventory) + end end function serialize.deserialize_item_stack(slot, entry) - if entry.e then - local success = slot.import_stack(entry.e) - if success == 1 then - print("Error: import of '" .. entry.e .. "' succeeded with errors") - elseif success == -1 then - print("Error: import of '" .. entry.e .. "' failed") - end + if entry.e then + local success = slot.import_stack(entry.e) + if success == 1 then + print("Error: import of '" .. entry.e .. "' succeeded with errors") + elseif success == -1 then + print("Error: import of '" .. entry.e .. "' failed") + end - return - end + return + end - local item_stack = { - name = entry.n, - count = entry.c, - } - if entry.h then item_stack.health = entry.h end - if entry.d then item_stack.durability = entry.d end - if entry.a then item_stack.ammo = entry.a end + local item_stack = { + name = entry.n, + count = entry.c, + } + if entry.h then item_stack.health = entry.h end + if entry.d then item_stack.durability = entry.d end + if entry.a then item_stack.ammo = entry.a end - local call_success, call_return = pcall(slot.set_stack, item_stack) - if not call_success then - print("Error: '" .. call_return .. "' thrown setting stack ".. serpent.line(entry)) + local call_success, call_return = pcall(slot.set_stack, item_stack) + if not call_success then + print("Error: '" .. call_return .. "' thrown setting stack ".. serpent.line(entry)) - elseif not call_return then - print("Error: Failed to set stack " .. serpent.line(entry)) + elseif not call_return then + print("Error: Failed to set stack " .. serpent.line(entry)) - else - if entry.l then - -- TODO test this with AAI's unit-remote-control - local label = entry.l - if label.t then slot.label = label.t end - if label.c then slot.label_color = label.c end - slot.allow_manual_label_change = label.a - end - if entry.g then - if slot.grid then - serialize.deserialize_equipment_grid(slot.grid, entry.g) - elseif slot.type == "item-with-entity-data" and has_create_grid then - slot.create_grid() - serialize.deserialize_equipment_grid(slot.grid, entry.g) - else - print("Error: Attempt to deserialize equipment grid on an unsupported entity") - end - end - if entry.i then - local sub_inventory = slot.get_inventory(defines.inventory.item_main) - serialize.deserialize_inventory(sub_inventory, entry.i) - end - end + else + if entry.l then + -- TODO test this with AAI's unit-remote-control + local label = entry.l + if label.t then slot.label = label.t end + if label.c then slot.label_color = label.c end + slot.allow_manual_label_change = label.a + end + if entry.g then + if slot.grid then + serialize.deserialize_equipment_grid(slot.grid, entry.g) + elseif slot.type == "item-with-entity-data" and has_create_grid then + slot.create_grid() + serialize.deserialize_equipment_grid(slot.grid, entry.g) + else + print("Error: Attempt to deserialize equipment grid on an unsupported entity") + end + end + if entry.i then + local sub_inventory = slot.get_inventory(defines.inventory.item_main) + serialize.deserialize_inventory(sub_inventory, entry.i) + end + end end -- Inventories are serialized into a table with the following fields: --- i: array of item stack or exportable item entries --- b: bar position (optional) +-- i: array of item stack or exportable item entries +-- b: bar position (optional) -- Each item entry has the following fields --- s: index (optional, equals to previous plus one if not present) --- r: repeat count (optional) --- f: slot filter (optional) +-- s: index (optional, equals to previous plus one if not present) +-- r: repeat count (optional) +-- f: slot filter (optional) -- Pluss all the fields for item stacks (see deserialize_item_stack) -- It's also possible that the slot is empty but has a slot filter. function serialize.serialize_inventory(inventory) - local serialized = {} - if inventory[supports_bar]() and inventory[get_bar]() <= #inventory then - serialized.b = inventory[get_bar]() - end + local serialized = {} + if inventory[supports_bar]() and inventory[get_bar]() <= #inventory then + serialized.b = inventory[get_bar]() + end - serialized.i = {} - local previous_index = 0 - local previous_serialized = nil - for i = 1, #inventory do - local item = {} - local slot = inventory[i] - if inventory.supports_filters() then - item.f = inventory.get_filter(i) - end + serialized.i = {} + local previous_index = 0 + local previous_serialized = nil + for i = 1, #inventory do + local item = {} + local slot = inventory[i] + if inventory.supports_filters() then + item.f = inventory.get_filter(i) + end - if slot.valid_for_read then - serialize.serialize_item_stack(slot, item) - end + if slot.valid_for_read then + serialize.serialize_item_stack(slot, item) + end - if item.n or item.f or item.e then - local item_serialized = game.table_to_json(item) - if item_serialized == previous_serialized then - local previous_item = serialized.i[#serialized.i] - previous_item.r = (previous_item.r or 0) + 1 - previous_index = i + if item.n or item.f or item.e then + local item_serialized = game.table_to_json(item) + if item_serialized == previous_serialized then + local previous_item = serialized.i[#serialized.i] + previous_item.r = (previous_item.r or 0) + 1 + previous_index = i - else - if i ~= previous_index + 1 then - item.s = i - end + else + if i ~= previous_index + 1 then + item.s = i + end - previous_index = i - previous_serialized = item_serialized - table.insert(serialized.i, item) - end + previous_index = i + previous_serialized = item_serialized + table.insert(serialized.i, item) + end - else - -- Either an empty slot or serilization failed - previous_index = 0 - previous_serialized = nil - end - end + else + -- Either an empty slot or serilization failed + previous_index = 0 + previous_serialized = nil + end + end - return serialized + return serialized end function serialize.deserialize_inventory(inventory, serialized) - if serialized.b and inventory[supports_bar]() then - inventory[set_bar](serialized.b) - end + if serialized.b and inventory[supports_bar]() then + inventory[set_bar](serialized.b) + end - local last_slot_index = 0 - for _, entry in ipairs(serialized.i) do - local base_index = entry.s or last_slot_index + 1 + local last_slot_index = 0 + for _, entry in ipairs(serialized.i) do + local base_index = entry.s or last_slot_index + 1 - local repeat_count = entry.r or 0 - for offset = 0, repeat_count do - -- XXX what if the inventory is smaller on this instance? - local index = base_index + offset - local slot = inventory[index] - if entry.f then - local call_success, call_return = pcall(inventory.set_filter, index, entry.f) - if not call_success then - print("Error: '" .. call_return .. "' thrown setting filter " .. entry.f) + local repeat_count = entry.r or 0 + for offset = 0, repeat_count do + -- XXX what if the inventory is smaller on this instance? + local index = base_index + offset + local slot = inventory[index] + if entry.f then + local call_success, call_return = pcall(inventory.set_filter, index, entry.f) + if not call_success then + print("Error: '" .. call_return .. "' thrown setting filter " .. entry.f) - elseif not call_return then - print("Error: Failed to set filter " .. entry.f) - end - end + elseif not call_return then + print("Error: Failed to set filter " .. entry.f) + end + end - if entry.n or entry.e then - serialize.deserialize_item_stack(slot, entry) - end - end - last_slot_index = base_index + repeat_count - end + if entry.n or entry.e then + serialize.deserialize_item_stack(slot, entry) + end + end + last_slot_index = base_index + repeat_count + end end diff --git a/plugins/player_auth/module/module.json b/plugins/player_auth/module/module.json index 782aad51..846ca4bb 100644 --- a/plugins/player_auth/module/module.json +++ b/plugins/player_auth/module/module.json @@ -1,4 +1,4 @@ { - "name": "player_auth", - "load": ["auth.lua"] + "name": "player_auth", + "load": ["auth.lua"] } diff --git a/plugins/research_sync/module/module.json b/plugins/research_sync/module/module.json index c2b055e9..192a686e 100644 --- a/plugins/research_sync/module/module.json +++ b/plugins/research_sync/module/module.json @@ -1,4 +1,4 @@ { - "name": "research_sync", - "load": ["sync.lua"] + "name": "research_sync", + "load": ["sync.lua"] } diff --git a/plugins/research_sync/module/sync.lua b/plugins/research_sync/module/sync.lua index e6074d97..5bd9b938 100644 --- a/plugins/research_sync/module/sync.lua +++ b/plugins/research_sync/module/sync.lua @@ -4,216 +4,216 @@ local sync = {} local function get_technology_progress(tech) - if tech == tech.force.current_research then - return tech.force.research_progress - else - return tech.force.get_saved_technology_progress(tech.name) - end + if tech == tech.force.current_research then + return tech.force.research_progress + else + return tech.force.get_saved_technology_progress(tech.name) + end end local function set_technology_progress(tech, progress) - if tech == tech.force.current_research then - tech.force.research_progress = progress - else - tech.force.set_saved_technology_progress(tech.name, progress) - end + if tech == tech.force.current_research then + tech.force.research_progress = progress + else + tech.force.set_saved_technology_progress(tech.name, progress) + end end sync.events = {} sync.events[clusterio_api.events.on_server_startup] = function(event) - if not global.research_sync then - global.research_sync = { - technologies = {}, - } - end + if not global.research_sync then + global.research_sync = { + technologies = {}, + } + end - -- Used when syncing completed technologies from the master - global.research_sync.ignore_research_finished = false + -- Used when syncing completed technologies from the master + global.research_sync.ignore_research_finished = false - local force = game.forces["player"] - for _, tech in pairs(force.technologies) do - if tech.enabled then - local progress = get_technology_progress(tech) - global.research_sync.technologies[tech.name] = { - level = tech.level, - researched = tech.researched, - progress = progress, - } - end - end + local force = game.forces["player"] + for _, tech in pairs(force.technologies) do + if tech.enabled then + local progress = get_technology_progress(tech) + global.research_sync.technologies[tech.name] = { + level = tech.level, + researched = tech.researched, + progress = progress, + } + end + end end local function get_contribution(tech) - local progress = get_technology_progress(tech) - if not progress then - return 0, nil - end + local progress = get_technology_progress(tech) + if not progress then + return 0, nil + end - local prev_tech = global.research_sync.technologies[tech.name] - if prev_tech.progress and prev_tech.level == tech.level then - return progress - prev_tech.progress, progress - else - return progress, progress - end + local prev_tech = global.research_sync.technologies[tech.name] + if prev_tech.progress and prev_tech.level == tech.level then + return progress - prev_tech.progress, progress + else + return progress, progress + end end local function send_contribution(tech) - local contribution, progress = get_contribution(tech) - if contribution ~= 0 then - clusterio_api.send_json("research_sync:contribution", { - name = tech.name, - level = tech.level, - contribution = contribution, - }) - global.research_sync.technologies[tech.name].progress = progress - end + local contribution, progress = get_contribution(tech) + if contribution ~= 0 then + clusterio_api.send_json("research_sync:contribution", { + name = tech.name, + level = tech.level, + contribution = contribution, + }) + global.research_sync.technologies[tech.name].progress = progress + end end sync.events[defines.events.on_research_started] = function(event) - local tech = event.last_research - if tech then - send_contribution(tech) - end + local tech = event.last_research + if tech then + send_contribution(tech) + end end sync.events[defines.events.on_research_finished] = function(event) - if global.research_sync.ignore_research_finished then - return - end + if global.research_sync.ignore_research_finished then + return + end - local tech = event.research - global.research_sync.technologies[tech.name] = { - level = tech.level, - researched = tech.researched, - } + local tech = event.research + global.research_sync.technologies[tech.name] = { + level = tech.level, + researched = tech.researched, + } - local level = tech.level - if not tech.researched then - level = level - 1 - end + local level = tech.level + if not tech.researched then + level = level - 1 + end - clusterio_api.send_json("research_sync:finished", { - name = tech.name, - level = level, - }) + clusterio_api.send_json("research_sync:finished", { + name = tech.name, + level = level, + }) end sync.on_nth_tick = {} sync.on_nth_tick[79] = function(event) - local tech = game.forces["player"].current_research - if tech then - send_contribution(tech) - end + local tech = game.forces["player"].current_research + if tech then + send_contribution(tech) + end end research_sync = {} function research_sync.dump_technologies() - local force = game.forces["player"] + local force = game.forces["player"] - local techs = {} - for _, tech in pairs(force.technologies) do - if tech.enabled then - table.insert(techs, { - name = tech.name, - level = tech.level, - progress = get_technology_progress(tech), - researched = tech.researched, - }) - end - end + local techs = {} + for _, tech in pairs(force.technologies) do + if tech.enabled then + table.insert(techs, { + name = tech.name, + level = tech.level, + progress = get_technology_progress(tech), + researched = tech.researched, + }) + end + end - if #techs == 0 then - rcon.print("[]") - else - rcon.print(game.table_to_json(techs)) - end + if #techs == 0 then + rcon.print("[]") + else + rcon.print(game.table_to_json(techs)) + end end function research_sync.sync_technologies(data) - local force = game.forces["player"] + local force = game.forces["player"] - local nameIndex = 1 - local levelIndex = 2 - local progressIndex = 3 - local researchedIndex = 4 + local nameIndex = 1 + local levelIndex = 2 + local progressIndex = 3 + local researchedIndex = 4 - global.research_sync.ignore_research_finished = true - for _, tech_data in pairs(game.json_to_table(data)) do - local tech = force.technologies[tech_data[nameIndex]] - if tech and tech.enabled and tech.level <= tech_data[levelIndex] then - tech.level = math.min(tech_data[levelIndex], tech.prototype.max_level) + global.research_sync.ignore_research_finished = true + for _, tech_data in pairs(game.json_to_table(data)) do + local tech = force.technologies[tech_data[nameIndex]] + if tech and tech.enabled and tech.level <= tech_data[levelIndex] then + tech.level = math.min(tech_data[levelIndex], tech.prototype.max_level) - local progress - if tech_data[researchedIndex] then - tech.researched = true - progress = nil - elseif tech_data[progressIndex] then - send_contribution(tech) - progress = tech_data[progressIndex] - set_technology_progress(tech, progress) - else - progress = get_technology_progress(tech) - end + local progress + if tech_data[researchedIndex] then + tech.researched = true + progress = nil + elseif tech_data[progressIndex] then + send_contribution(tech) + progress = tech_data[progressIndex] + set_technology_progress(tech, progress) + else + progress = get_technology_progress(tech) + end - global.research_sync.technologies[tech.name] = { - level = tech.level, - researched = tech.researched, - progress = progress, - } - end - end - global.research_sync.ignore_research_finished = false + global.research_sync.technologies[tech.name] = { + level = tech.level, + researched = tech.researched, + progress = progress, + } + end + end + global.research_sync.ignore_research_finished = false end function research_sync.update_progress(data) - local techs = game.json_to_table(data) - local force = game.forces["player"] + local techs = game.json_to_table(data) + local force = game.forces["player"] - for _, masterTech in ipairs(techs) do - local tech = force.technologies[masterTech.name] - if tech and tech.enabled and tech.level == masterTech.level then - send_contribution(tech) - set_technology_progress(tech, masterTech.progress) - global.research_sync.technologies[tech.name] = { - level = tech.level, - progress = masterTech.progress - } - end - end + for _, masterTech in ipairs(techs) do + local tech = force.technologies[masterTech.name] + if tech and tech.enabled and tech.level == masterTech.level then + send_contribution(tech) + set_technology_progress(tech, masterTech.progress) + global.research_sync.technologies[tech.name] = { + level = tech.level, + progress = masterTech.progress + } + end + end end function research_sync.research_technology(name, level) - local force = game.forces["player"] - local tech = force.technologies[name] - if not tech or not tech.enabled or tech.level > level then - return - end + local force = game.forces["player"] + local tech = force.technologies[name] + if not tech or not tech.enabled or tech.level > level then + return + end - if level > tech.prototype.max_level then - level = tech.prototype.max_level - end + if level > tech.prototype.max_level then + level = tech.prototype.max_level + end - global.research_sync.ignore_research_finished = true - if tech == force.current_research and tech.level == level then - force.research_progress = 1 + global.research_sync.ignore_research_finished = true + if tech == force.current_research and tech.level == level then + force.research_progress = 1 - elseif tech.level < level or tech.level == level and not tech.researched then - tech.level = level - tech.researched = true + elseif tech.level < level or tech.level == level and not tech.researched then + tech.level = level + tech.researched = true - if tech.name:find("-%d+$") then - game.print {"", "Researched ", {"technology-name." .. tech.name:gsub("-%d+$", "")}, " ", level} - else - game.print {"", "Researched ", {"technology-name." .. tech.name}} - end - game.play_sound { path = "utility/research_completed" } - end - global.research_sync.ignore_research_finished = false + if tech.name:find("-%d+$") then + game.print {"", "Researched ", {"technology-name." .. tech.name:gsub("-%d+$", "")}, " ", level} + else + game.print {"", "Researched ", {"technology-name." .. tech.name}} + end + game.play_sound { path = "utility/research_completed" } + end + global.research_sync.ignore_research_finished = false - global.research_sync.technologies[tech.name] = { - level = tech.level, - researched = tech.researched, - } + global.research_sync.technologies[tech.name] = { + level = tech.level, + researched = tech.researched, + } end diff --git a/plugins/statistics_exporter/module/export.lua b/plugins/statistics_exporter/module/export.lua index fb7fc164..52955488 100644 --- a/plugins/statistics_exporter/module/export.lua +++ b/plugins/statistics_exporter/module/export.lua @@ -1,34 +1,34 @@ local statistics = { - "item_production_statistics", - "fluid_production_statistics", - "kill_count_statistics", - "entity_build_count_statistics", + "item_production_statistics", + "fluid_production_statistics", + "kill_count_statistics", + "entity_build_count_statistics", } statistics_exporter = {} function statistics_exporter.export() - local stats = { - game_tick = game.tick, - player_count = #game.connected_players, - game_flow_statistics = { - pollution_statistics = { - input = game.pollution_statistics.input_counts, - output = game.pollution_statistics.output_counts, - }, - }, - force_flow_statistics = {} - } - for _, force in pairs(game.forces) do - local flow_statistics = {} - for _, statName in pairs(statistics) do - flow_statistics[statName] = { - input = force[statName].input_counts, - output = force[statName].output_counts, - } - end - stats.force_flow_statistics[force.name] = flow_statistics - end + local stats = { + game_tick = game.tick, + player_count = #game.connected_players, + game_flow_statistics = { + pollution_statistics = { + input = game.pollution_statistics.input_counts, + output = game.pollution_statistics.output_counts, + }, + }, + force_flow_statistics = {} + } + for _, force in pairs(game.forces) do + local flow_statistics = {} + for _, statName in pairs(statistics) do + flow_statistics[statName] = { + input = force[statName].input_counts, + output = force[statName].output_counts, + } + end + stats.force_flow_statistics[force.name] = flow_statistics + end - rcon.print(game.table_to_json(stats)) + rcon.print(game.table_to_json(stats)) end diff --git a/plugins/statistics_exporter/module/module.json b/plugins/statistics_exporter/module/module.json index 7da2637e..abd3ba6a 100644 --- a/plugins/statistics_exporter/module/module.json +++ b/plugins/statistics_exporter/module/module.json @@ -1,4 +1,4 @@ { - "name": "statistics_exporter", - "require": ["export.lua"] + "name": "statistics_exporter", + "require": ["export.lua"] } diff --git a/plugins/subspace_storage/web/index.css b/plugins/subspace_storage/web/index.css index e0e730c8..d96377fc 100644 --- a/plugins/subspace_storage/web/index.css +++ b/plugins/subspace_storage/web/index.css @@ -1,5 +1,5 @@ .factorio-icon { - display: inline-block; - vertical-align: middle; - margin-right: 0.5em; + display: inline-block; + vertical-align: middle; + margin-right: 0.5em; }