mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 15:14:52 +09:00
Expand compat to 0.17 (#711)
This commit is contained in:
1 parent
87746edbf5
commit
ff9ba0271f
8 files changed
+138
-89
No files matched your search
@@ -12,9 +12,8 @@ local MyModule = {
|
||||
-- If you use any of these events and access globalData then make sure to call this function first
|
||||
local script_data = {}
|
||||
local function setup_script_data()
|
||||
local _script_data = compat.script_data()
|
||||
if _script_data["__plugin_name__"] == nil then
|
||||
_script_data["__plugin_name__"] = {
|
||||
if compat.script_data["__plugin_name__"] == nil then
|
||||
compat.script_data["__plugin_name__"] = {
|
||||
-- starting values go here
|
||||
}
|
||||
end
|
||||
@@ -24,8 +23,7 @@ end
|
||||
--- The on_load function is called independently for each client when they first load the map
|
||||
-- It should be used to restore global aliases and metatables not registered with script.register_metatable
|
||||
function MyModule.on_load()
|
||||
local _script_data = compat.script_data()
|
||||
script_data = _script_data["__plugin_name__"]
|
||||
script_data = compat.script_data["__plugin_name__"]
|
||||
end
|
||||
|
||||
--- Public methods should be available though your top level module table
|
||||
|
||||
@@ -10,11 +10,11 @@ api.events = {
|
||||
}
|
||||
|
||||
function api.get_instance_name()
|
||||
return compat.script_data().clusterio.instance_name
|
||||
return compat.script_data.clusterio.instance_name
|
||||
end
|
||||
|
||||
function api.get_instance_id()
|
||||
return compat.script_data().clusterio.instance_id
|
||||
return compat.script_data.clusterio.instance_id
|
||||
end
|
||||
|
||||
function api.send_json(channel, data)
|
||||
@@ -33,7 +33,7 @@ function api.send_json(channel, data)
|
||||
if #data < 4000 then
|
||||
print("\f$ipc:" .. channel .. "?j" .. data)
|
||||
else
|
||||
local script_data = compat.script_data()
|
||||
local script_data = compat.script_data
|
||||
script_data.clusterio_file_no = (script_data.clusterio_file_no or 0) + 1
|
||||
local file_name = "clst_" .. script_data.clusterio_file_no .. ".json"
|
||||
compat.write_file(file_name, data, false, 0)
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
--[[
|
||||
Adds various functions used to ensure compatibly between version including some polyfills
|
||||
Adds various functions used to ensure compatibly between version including some polyfills.
|
||||
|
||||
Implementation Guidelines
|
||||
- If a function is only available at runtime in one version, then all versions must be made to error.
|
||||
- Where possible, directly assign the function / table to the member of compat.
|
||||
- When not possible, then it should replace itself with a direct assignment asap.
|
||||
- Versions are handled in ascending order covering all supported versions and ending with an error.
|
||||
]]
|
||||
|
||||
local json = require("json")
|
||||
local lib_json = require("json")
|
||||
|
||||
--- @diagnostic disable: deprecated
|
||||
|
||||
--- @class LibCompat
|
||||
--- @field script_data table
|
||||
--- @field prototypes LuaPrototypes
|
||||
--- @field active_mods table<string, string>
|
||||
--- @field write_file fun(filename: string, data: LocalisedString, append: boolean?, for_player: uint?)
|
||||
--- @field table_to_json fun(data: table): string
|
||||
--- @field json_to_table fun(json: string): AnyBasic?
|
||||
local compat = {}
|
||||
|
||||
--- @class LibCompatMt
|
||||
--- @package
|
||||
local compat_mt = {}
|
||||
|
||||
--- @alias VersionTable { [1]: number, [2]: number, [3]: number }
|
||||
|
||||
--- Concert a version string into a version table
|
||||
@@ -37,12 +53,6 @@ do
|
||||
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
|
||||
@@ -86,85 +96,127 @@ function compat.version_le(version)
|
||||
return true
|
||||
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")
|
||||
--- The versions of factorio we support
|
||||
local v2_0 = compat.version_ge("2.0")
|
||||
local v1_1 = not v2_0 and compat.version_ge("1.1")
|
||||
local v1_0 = not v1_1 and compat.version_ge("1.0")
|
||||
local v0_18 = not v1_0 and compat.version_ge("0.18")
|
||||
local v0_17 = not v0_18 and compat.version_ge("0.17")
|
||||
|
||||
--- Returns the table reference used to store script data
|
||||
--- @return table script_data
|
||||
function compat.script_data()
|
||||
if major_v1_1 then
|
||||
--- @diagnostic disable-next-line
|
||||
return global
|
||||
elseif major_v2 then
|
||||
return storage
|
||||
end
|
||||
return unsupported_version()
|
||||
local v2 = compat.version_ge("2.0")
|
||||
local v1 = not v2 and compat.version_ge("1.0")
|
||||
local v0 = not v1 and compat.version_ge("0.17")
|
||||
|
||||
--- Raise an error because the current version is unsupported
|
||||
local function unsupported_version()
|
||||
error("Unsupported version: " .. current_version_str, 3)
|
||||
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()
|
||||
--- Raise an error because the function is only available at runtime
|
||||
local function runtime_only()
|
||||
error("To maintain compatibly, this value can only be used during runtime.", 3)
|
||||
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
|
||||
--- Keys of this table will raise an unsupported error when accessed
|
||||
local unsupported_properties = {}
|
||||
|
||||
--- Keys of this table can only be accessed at runtime
|
||||
--- The value is a function which returns the real value
|
||||
local runtime_properties = {}
|
||||
|
||||
--- Handles the indexing of the tables above
|
||||
function compat_mt:__index(key)
|
||||
if unsupported_properties[key] then
|
||||
return unsupported_version()
|
||||
elseif runtime_properties[key] then
|
||||
if game == nil then
|
||||
return runtime_only()
|
||||
end
|
||||
local value = runtime_properties[key]()
|
||||
if value == nil then
|
||||
return unsupported_version()
|
||||
end
|
||||
rawset(self, key, value)
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
--- Prototype data contains all the definitions for the game, it is only available during runtime
|
||||
function runtime_properties.prototypes()
|
||||
if v0 or v1 then
|
||||
--- Lazy loading of prototype data
|
||||
return setmetatable({}, {
|
||||
-- Prevent iteration due to lazy loading, its a really rare use case
|
||||
__pairs = function() error("Pairs not supported in " .. current_version_str, 2) end,
|
||||
__ipairs = function() error("IPairs not supported in " .. current_version_str, 2) end,
|
||||
__index = function(self, key)
|
||||
local value = game[key .. "_prototypes"]
|
||||
rawset(self, key, value)
|
||||
return value
|
||||
end
|
||||
})
|
||||
elseif v2 then
|
||||
return prototypes
|
||||
end
|
||||
end
|
||||
|
||||
--- List of all active mods
|
||||
function runtime_properties.active_mods()
|
||||
if v0_17 then
|
||||
return game.active_mods
|
||||
elseif v0 or v1 or v2 then
|
||||
return script.active_mods
|
||||
end
|
||||
return unsupported_version()
|
||||
end
|
||||
|
||||
--- @param tbl table
|
||||
--- @return string
|
||||
function compat.table_to_json(tbl)
|
||||
return unsupported_version()
|
||||
--- Writes a string to file
|
||||
function runtime_properties.write_file()
|
||||
if v0 or v1 then
|
||||
return game.write_file
|
||||
elseif v2 then
|
||||
return helpers.write_file
|
||||
end
|
||||
end
|
||||
|
||||
--- @param json string
|
||||
--- @return table
|
||||
function compat.json_to_table(json)
|
||||
return unsupported_version()
|
||||
end
|
||||
|
||||
--- @param filename string
|
||||
--- @param data LocalisedString
|
||||
--- @param append boolean?
|
||||
--- @param for_player uint?
|
||||
function compat.write_file(filename, data, append, for_player)
|
||||
unsupported_version()
|
||||
end
|
||||
|
||||
--- Select the appropriate polyfill implementation
|
||||
if major_v1_1 then
|
||||
--- Convert tables to and from json, we have backported this to work before runtime
|
||||
if v0 or v1 then
|
||||
compat.table_to_json = function(tbl)
|
||||
if game then
|
||||
compat.table_to_json = game.table_to_json
|
||||
return game.table_to_json(tbl)
|
||||
end
|
||||
return json.encode(tbl)
|
||||
return lib_json.encode(tbl)
|
||||
end
|
||||
compat.json_to_table = function(json)
|
||||
if game then
|
||||
compat.json_to_table = game.json_to_table
|
||||
return game.json_to_table(json)
|
||||
end
|
||||
return json.decode(json)
|
||||
return lib_json.decode(json)
|
||||
end
|
||||
compat.write_file = function(filename, data, append, for_player) return game.write_file(filename, data, append, for_player) end
|
||||
elseif major_v2 then
|
||||
elseif v2 then
|
||||
compat.table_to_json = helpers.table_to_json
|
||||
compat.json_to_table = helpers.json_to_table
|
||||
compat.write_file = helpers.write_file
|
||||
else
|
||||
unsupported_properties.table_to_json = true
|
||||
unsupported_properties.json_to_table = true
|
||||
end
|
||||
|
||||
return compat
|
||||
--- Script data refers to lua data which is persisted between loads
|
||||
--- This is called immediately, during init and during load
|
||||
local function set_script_data()
|
||||
if v0 or v1 then
|
||||
--- @diagnostic disable-next-line
|
||||
compat.script_data = global
|
||||
elseif v2 then
|
||||
compat.script_data = storage
|
||||
else
|
||||
unsupported_properties.script_data = true
|
||||
end
|
||||
end
|
||||
|
||||
set_script_data()
|
||||
compat.on_init = set_script_data --- @package
|
||||
compat.on_load = set_script_data --- @package
|
||||
|
||||
return setmetatable(compat, compat_mt)
|
||||
@@ -4,9 +4,8 @@ local compat = require("modules/clusterio/compat")
|
||||
--- @class (exact) EventData.on_server_startup:EventData
|
||||
|
||||
local function check_patch()
|
||||
local script_data = compat.script_data()
|
||||
if script_data.clusterio_patch_number ~= clusterio_patch_number then
|
||||
script_data.clusterio_patch_number = clusterio_patch_number
|
||||
if compat.script_data.clusterio_patch_number ~= clusterio_patch_number then
|
||||
compat.script_data.clusterio_patch_number = clusterio_patch_number
|
||||
script.raise_event(api.events.on_server_startup, {
|
||||
name = api.events.on_server_startup, tick = game.tick
|
||||
})
|
||||
@@ -19,9 +18,8 @@ impl.events = {}
|
||||
impl.events[defines.events.on_tick] = check_patch
|
||||
|
||||
impl.events[api.events.on_server_startup] = function()
|
||||
local script_data = compat.script_data()
|
||||
if not script_data.clusterio then
|
||||
script_data.clusterio = {
|
||||
if not compat.script_data.clusterio then
|
||||
compat.script_data.clusterio = {
|
||||
instance_id = nil,
|
||||
instance_name = nil,
|
||||
}
|
||||
@@ -55,8 +53,8 @@ end
|
||||
-- Internal API
|
||||
clusterio_private = {}
|
||||
function clusterio_private.update_instance(new_id, new_name)
|
||||
local script_data = compat.script_data()
|
||||
check_patch()
|
||||
local script_data = compat.script_data
|
||||
script_data.clusterio.instance_id = new_id
|
||||
script_data.clusterio.instance_name = new_name
|
||||
script.raise_event(api.events.on_instance_updated, {
|
||||
@@ -78,15 +76,15 @@ remote.add_interface('clusterio_api', {
|
||||
end,
|
||||
|
||||
get_instance_id = function()
|
||||
return compat.script_data().clusterio.instance_id
|
||||
return compat.script_data.clusterio.instance_id
|
||||
end,
|
||||
|
||||
get_instance_name = function()
|
||||
return compat.script_data().clusterio.instance_name
|
||||
return compat.script_data.clusterio.instance_name
|
||||
end,
|
||||
|
||||
get_file_no = function()
|
||||
local script_data = compat.script_data()
|
||||
local script_data = compat.script_data
|
||||
script_data.clusterio_file_no = (script_data.clusterio_file_no or 0) + 1
|
||||
return script_data.clusterio_file_no
|
||||
end,
|
||||
|
||||
@@ -2,5 +2,8 @@
|
||||
"name": "clusterio",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {},
|
||||
"load": ["impl.lua"]
|
||||
"load": [
|
||||
"impl.lua",
|
||||
"compat.lua"
|
||||
]
|
||||
}
|
||||
@@ -2,8 +2,7 @@ local compat = require("modules/clusterio/compat")
|
||||
|
||||
--- @param no_early_return boolean? True to always setup data
|
||||
return function(no_early_return)
|
||||
local script_data = compat.script_data()
|
||||
local inventory_sync = script_data.inventory_sync
|
||||
local inventory_sync = compat.script_data.inventory_sync
|
||||
if inventory_sync and not no_early_return then
|
||||
return inventory_sync
|
||||
end
|
||||
@@ -17,6 +16,6 @@ return function(no_early_return)
|
||||
inventory_sync.finished_downloads = inventory_sync.finished_downloads or {}
|
||||
inventory_sync.active_uploads = inventory_sync.active_uploads or {}
|
||||
|
||||
script_data.inventory_sync = inventory_sync
|
||||
compat.script_data.inventory_sync = inventory_sync
|
||||
return inventory_sync
|
||||
end
|
||||
@@ -360,7 +360,7 @@ end
|
||||
-- Upload inventory when a player leaves the game. Triggers on restart after crash if player was online during crash.
|
||||
inventory_sync.events[defines.events.on_pre_player_left_game] = function(event)
|
||||
-- for some reason, on_pre_player_left_game gets called before on_server_startup so script_data isn't ready yet
|
||||
if not compat.script_data().inventory_sync then
|
||||
if not compat.script_data.inventory_sync then
|
||||
log("ERROR: script data for inventory sync is not defined")
|
||||
return
|
||||
end
|
||||
|
||||
@@ -33,8 +33,7 @@ end
|
||||
--- @param no_early_return boolean?
|
||||
--- @return table
|
||||
local function get_script_data(no_early_return)
|
||||
local script_data = compat.script_data()
|
||||
local research_sync = script_data.research_sync
|
||||
local research_sync = compat.script_data.research_sync
|
||||
if research_sync and not no_early_return then
|
||||
return research_sync
|
||||
end
|
||||
@@ -56,7 +55,7 @@ local function get_script_data(no_early_return)
|
||||
}
|
||||
end
|
||||
|
||||
script_data.research_sync = research_sync
|
||||
compat.script_data.research_sync = research_sync
|
||||
return research_sync
|
||||
end
|
||||
|
||||
|
||||
Reference in new issue
Block a user