diff --git a/packages/host/lua/clusterio_lib/info.json b/packages/host/lua/clusterio_lib/info.json index 5afc7b4f..7e720756 100644 --- a/packages/host/lua/clusterio_lib/info.json +++ b/packages/host/lua/clusterio_lib/info.json @@ -19,6 +19,7 @@ "homepage": "https://github.com/clusterio/clusterio", "description": "Library for interfacing with Clusterio. Warning: work in progress alpha.", "additional_files": { + "compat.lua": ["..", "..", "modules", "clusterio", "compat.lua"], "serialize.lua": ["..", "..", "modules", "clusterio", "serialize.lua"] } } diff --git a/packages/host/modules/clusterio/compat.lua b/packages/host/modules/clusterio/compat.lua new file mode 100644 index 00000000..1c95db24 --- /dev/null +++ b/packages/host/modules/clusterio/compat.lua @@ -0,0 +1,148 @@ +--[[ +Adds various functions used to ensure compatibly between version including some polyfills +]] + +--- @class LibCompat +local compat = {} + +--- @alias VersionTable { [1]: number, [2]: number, [3]: number } + +--- Concert a version string into a version table +--- @param version string +--- @return VersionTable +local function version_to_table(version) + local index = 0 + local rtn = { 0, 0, 0 } + for part in version:gmatch("%d+") do + index = index + 1 + rtn[index] = tonumber(part) + end + return rtn +end + +--- The current version of factorio, the earliest supported is 0.17.69 +local current_version_str = "0.17.69" +local current_version = version_to_table(current_version_str) +do + local success, base_version = pcall(function() + return script.active_mods.base + end) + if success then + current_version_str = base_version + current_version = version_to_table(current_version_str) + end +end + +--- Raise an error because the current version is unsupported +--- @return any +local function unsupported_version() + error("Unsupported version: " .. current_version_str, 3) +end + +--- Returns true if the current version is equal to the provided version +--- @param version string Version to compare against +--- @return boolean # True if versions are equal +function compat.version_eq(version) + local version_tbl = version_to_table(version) + for i = 1, 3 do + if version_tbl[i] ~= current_version[i] then + return false + end + end + return true +end + +--- Returns true if the current version is greater than or equal to the the provided version +--- @param version string Version to compare against +--- @return boolean # True if the version is greater or equal to provided +function compat.version_ge(version) + local version_tbl = version_to_table(version) + for i = 1, 3 do + if version_tbl[i] > current_version[i] then + return false + elseif version_tbl[i] < current_version[i] then + return true + end + end + return true +end + +--- Returns true if the current version is less than or equal to the the provided version +--- @param version string Version to compare against +--- @return boolean # True if the version is less or equal to provided +function compat.version_le(version) + return not compat.version_ge(version) +end + +--- The major versions of factorio we support +local major_v2 = compat.version_ge("2.0.0") +local major_v1_1 = not major_v2 and compat.version_ge("1.1.0") +-- local major_v1 = not major_v1_1 and compat.version_ge("1.0.0") + +--- Returns the table reference used to store script data +--- @return table script_data +function compat.script_data() + if major_v1_1 then + return global + elseif major_v2 then + return storage + end + return unsupported_version() +end + +--- Returns the table reference used to store prototypes +--- @param category string Category of prototype to access, eg "item", "fluid", "recipe" +--- @return table # Table of prototype data +function compat.prototype_data(category) + if major_v1_1 then + return game[category .. "_prototypes"] + elseif major_v2 then + return prototypes[category] + end + return unsupported_version() +end + +--- Returns the table reference used to list active mods +--- @return table # Table of active mods +function compat.active_mods() + if major_v1_1 or major_v2 then + return script.active_mods + end + return unsupported_version() +end + +--- Converts a table into a json string +--- @param tbl table Table to convert to json +--- @return string # Json string representing the table +function compat.table_to_json(tbl) + return unsupported_version() +end + +--- Converts a json string into a table +--- @param json string Json string representing a table +--- @return table # Table created from the string +function compat.json_to_table(tbl) + return unsupported_version() +end + +--- Write a file to script output directory +--- @param filename string The name of the file. +--- @param data LocalisedString The content to write to the file. +--- @param append boolean? True if the data will be appended, false will overwrite existing data +--- @param for_player uint? If given, file is only written for this player index, 0 represents the server +--- @return table # Table created from the string +function compat.write_file(filename, data, append, for_player) + return unsupported_version() +end + +if major_v1_1 then + -- Game is not always available so it needs to be called within another function + -- TODO maybe include a version that does not require game? + compat.table_to_json = function(...) return game.table_to_json(...) end + compat.json_to_table = function(...) return game.json_to_table(...) end + compat.write_file = function(...) return game.write_file(...) end +elseif major_v2 then + compat.table_to_json = helpers.table_to_json + compat.json_to_table = helpers.json_to_table + compat.write_file = helpers.write_file +end