add game&rawdata
This commit is contained in:
parent
0133cd976c
commit
49b34b5546
45731 changed files with 709831 additions and 0 deletions
218
gamedata/scripts/alife_storage_manager.script
Normal file
218
gamedata/scripts/alife_storage_manager.script
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
--[[
|
||||
This script handles the serialization of data using the marshal library and the saving of this data to disk depending
|
||||
on save game name. What this means is that you can save entire tables to disk instead of saving to object packet.
|
||||
This script was created to alleviate issues with using packets to save dynamic data (pstor) which lead to save corruption.
|
||||
Also it removes some restrictions on what you can save.
|
||||
|
||||
*only store valid lua types such as numbers, strings, boolean, functions or tables that contain these valid types. Userdata needs to have a special
|
||||
__persist function defined in it's metatable. See how it is done for CTime in _G.script
|
||||
|
||||
*Supposedly you can save userdata if you write a proper __persist method for the metatable but I have failed to achieve proper results with serializing CTime.
|
||||
|
||||
*You must register for 'save_state' and 'load_state' and add your own table to m_data for it to be encoded then stored in *.scoc
|
||||
*Although marshal is pretty fast, keep in mind that encoding/decoding a ton of data, saves will start to noticeablely take longer to save/load.
|
||||
*For testing/debugging you can uncomment the print_table calls in save_state and load_state. It will save the before and after tables to print_table.txt in your main directory.
|
||||
|
||||
|
||||
by: Alundaio
|
||||
--]]
|
||||
local m_data = {}
|
||||
|
||||
-- store stuff that you want to persist even offline
|
||||
m_data.se_object = {}
|
||||
|
||||
-- store stuff only for online objects. When object goes offline this table is purged.
|
||||
m_data.game_object = {}
|
||||
|
||||
-- PDA known contacts
|
||||
-- m_data.actor_contacts = {}
|
||||
|
||||
saved_game_extension_ex = save_extension() .. "_data"
|
||||
|
||||
local function on_pstor_load_all(obj,packet)
|
||||
local id = obj:id()
|
||||
local state = get_game_object_state(obj,false)
|
||||
if (state and db.storage[id]) then
|
||||
if (state.pstor_all) then
|
||||
db.storage[id].pstor = state.pstor_all
|
||||
state.pstor_all = nil
|
||||
end
|
||||
|
||||
if (state.pstor_ctime) then
|
||||
db.storage[id].pstor_ctime = state.pstor_ctime
|
||||
state.pstor_ctime = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function on_game_start()
|
||||
if not isMarshal then
|
||||
return
|
||||
end
|
||||
--RegisterScriptCallback("on_pstor_load_all",on_pstor_load_all)
|
||||
end
|
||||
|
||||
-- called from engine!
|
||||
function CALifeStorageManager_before_save(fname)
|
||||
if not isMarshal then
|
||||
return
|
||||
end
|
||||
|
||||
--printf("CALifeStorageManager_before_save BEFORE callback")
|
||||
|
||||
m_data.GAME_VERSION = GAME_VERSION
|
||||
|
||||
SendScriptCallback("save_state",m_data)
|
||||
|
||||
--printf("CALifeStorageManager_before_save AFTER callback")
|
||||
|
||||
-- save pstor
|
||||
for id,t in pairs(db.storage) do
|
||||
if (m_data.game_object[id]) then
|
||||
if (t.pstor and not is_empty(t.pstor)) then
|
||||
m_data.game_object[id].pstor_all = t.pstor
|
||||
end
|
||||
|
||||
-- serialization with game.CTime.__persist
|
||||
if (t.pstor_ctime and not is_empty(t.pstor_ctime)) then
|
||||
m_data.game_object[id].pstor_ctime = t.pstor_ctime
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--ProcessEventQueueState(m_data,true)
|
||||
|
||||
-- clean out game_object table of empty sub tables
|
||||
for id,tbl in pairs(m_data.game_object) do
|
||||
for k,v in pairs(tbl) do
|
||||
if (type(v) == "table" and is_empty(v)) then
|
||||
m_data.game_object[id][k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local data = marshal.encode(m_data)
|
||||
if not (data) then
|
||||
return
|
||||
end
|
||||
|
||||
local path = getFS():update_path('$game_saves$', '')
|
||||
|
||||
lfs.mkdir(path) -- incase savegame folder doesn't exist yet
|
||||
path = path .. fname:sub(0,-6):lower() .. saved_game_extension_ex
|
||||
|
||||
local savegame = io.open(path,"wb")
|
||||
if not (io.type(savegame) == "file") then
|
||||
printf("Error: Unable to write to %s",path)
|
||||
return
|
||||
end
|
||||
|
||||
--printf("axr_main: saving custom data %s",path)
|
||||
savegame:write(data)
|
||||
savegame:close()
|
||||
|
||||
--printf("CALifeStorageManager_before_save FINISHED")
|
||||
end
|
||||
|
||||
-- called from engine!
|
||||
function CALifeStorageManager_after_save(fname)
|
||||
if ffx_path_utils then
|
||||
fname = ffx_path_utils.get_file_name(fname, false)
|
||||
end
|
||||
|
||||
local _path = getFS():update_path('$game_saves$', '')
|
||||
|
||||
SendScriptCallback("save_file_created", _path, fname)
|
||||
end
|
||||
|
||||
-- called from engine!
|
||||
function CALifeStorageManager_new_game(fname)
|
||||
if ffx_path_utils then
|
||||
fname = ffx_path_utils.get_file_name(fname, false)
|
||||
end
|
||||
|
||||
local _path = getFS():update_path('$game_saves$', '')
|
||||
|
||||
SendScriptCallback("new_game_created", _path, fname)
|
||||
end
|
||||
|
||||
-- called from engine!
|
||||
function CALifeStorageManager_save(fname)
|
||||
--printf("CALifeStorageManager_save START FINISHED")
|
||||
end
|
||||
|
||||
-- called from engine
|
||||
function CALifeStorageManager_load(fname)
|
||||
if not isMarshal then
|
||||
return
|
||||
end
|
||||
|
||||
local path = fname:sub(0,-6) .. saved_game_extension_ex
|
||||
|
||||
--alun_utils.debug_write(strformat("CALifeStorageManager_load %s",path))
|
||||
|
||||
local savegame = io.open(path,"rb")
|
||||
if not (io.type(savegame) == "file") then
|
||||
return
|
||||
end
|
||||
|
||||
local data = savegame:read("*all")
|
||||
savegame:close()
|
||||
|
||||
if not (data and data ~= "") then
|
||||
printf("Error: Failed to read %s",path)
|
||||
return
|
||||
end
|
||||
|
||||
m_data = marshal.decode(data)
|
||||
|
||||
--ProcessEventQueueState(m_data,false)
|
||||
|
||||
-- For debugging save state
|
||||
--alun_utils.print_table(m_data,"m_data_on_load ("..path..")")
|
||||
|
||||
SendScriptCallback("load_state",m_data)
|
||||
|
||||
if ffx_path_utils then
|
||||
fname = ffx_path_utils.get_file_name(fname, false)
|
||||
end
|
||||
local _path = getFS():update_path('$game_saves$', '')
|
||||
SendScriptCallback("save_file_loaded", _path, fname)
|
||||
|
||||
--alun_utils.debug_write(strformat("CALifeStorageManager_load END"))
|
||||
end
|
||||
|
||||
function get_state()
|
||||
return m_data
|
||||
end
|
||||
|
||||
function decode(t)
|
||||
return marshal.decode(t)
|
||||
end
|
||||
|
||||
-- storage based on ID but verified by object name
|
||||
function get_game_object_state(obj,create_if_dont_exist)
|
||||
local id = obj:id()
|
||||
local name = obj:name()
|
||||
if not (m_data.game_object[id]) then
|
||||
if not (create_if_dont_exist) then
|
||||
return
|
||||
end
|
||||
m_data.game_object[id] = {}
|
||||
m_data.game_object[id].name = name
|
||||
end
|
||||
return m_data.game_object[id]
|
||||
end
|
||||
|
||||
function get_se_obj_state(se_obj,create_if_dont_exist)
|
||||
local id = se_obj.id
|
||||
local name = se_obj:name()
|
||||
if not (m_data.se_object[id]) then
|
||||
if not (create_if_dont_exist) then
|
||||
return
|
||||
end
|
||||
m_data.se_object[id] = {}
|
||||
m_data.se_object[id].name = name
|
||||
end
|
||||
return m_data.se_object[id]
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue