forked from Mirrorlandia_minetest/minetest
Add ModStorageAPI to client side modding (#5396)
mod storage is located into user_path / client / mod_storage
This commit is contained in:
parent
46276414ed
commit
eb88e5dd4b
@ -1,4 +1,5 @@
|
|||||||
local modname = core.get_current_modname() or "??"
|
local modname = core.get_current_modname() or "??"
|
||||||
|
local modstorage = core.get_mod_storage()
|
||||||
|
|
||||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||||
core.register_on_shutdown(function()
|
core.register_on_shutdown(function()
|
||||||
@ -49,6 +50,8 @@ core.register_chatcommand("test_node", {
|
|||||||
|
|
||||||
core.after(2, function()
|
core.after(2, function()
|
||||||
print("[PREVIEW] loaded " .. modname .. " mod")
|
print("[PREVIEW] loaded " .. modname .. " mod")
|
||||||
|
modstorage:set_string("current_mod", modname)
|
||||||
|
print(modstorage:get_string("current_mod"))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
core.register_on_dignode(function(pos, node)
|
core.register_on_dignode(function(pos, node)
|
||||||
|
@ -249,7 +249,8 @@ Client::Client(
|
|||||||
m_removed_sounds_check_timer(0),
|
m_removed_sounds_check_timer(0),
|
||||||
m_state(LC_Created),
|
m_state(LC_Created),
|
||||||
m_localdb(NULL),
|
m_localdb(NULL),
|
||||||
m_script(NULL)
|
m_script(NULL),
|
||||||
|
m_mod_storage_save_timer(10.0f)
|
||||||
{
|
{
|
||||||
// Add local player
|
// Add local player
|
||||||
m_env.setLocalPlayer(new LocalPlayer(this, playername));
|
m_env.setLocalPlayer(new LocalPlayer(this, playername));
|
||||||
@ -730,6 +731,18 @@ void Client::step(float dtime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_mod_storage_save_timer -= dtime;
|
||||||
|
if (m_mod_storage_save_timer <= 0.0f) {
|
||||||
|
verbosestream << "Saving registered mod storages." << std::endl;
|
||||||
|
m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
|
||||||
|
for (UNORDERED_MAP<std::string, ModMetadata *>::const_iterator
|
||||||
|
it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
|
||||||
|
if (it->second->isModified()) {
|
||||||
|
it->second->save(getModStoragePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Write server map
|
// Write server map
|
||||||
if (m_localdb && m_localdb_save_interval.step(dtime,
|
if (m_localdb && m_localdb_save_interval.step(dtime,
|
||||||
m_cache_save_interval)) {
|
m_cache_save_interval)) {
|
||||||
@ -1998,3 +2011,31 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename)
|
|||||||
smgr->getMeshCache()->removeMesh(mesh);
|
smgr->getMeshCache()->removeMesh(mesh);
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::registerModStorage(ModMetadata *storage)
|
||||||
|
{
|
||||||
|
if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) {
|
||||||
|
errorstream << "Unable to register same mod storage twice. Storage name: "
|
||||||
|
<< storage->getModName() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mod_storages[storage->getModName()] = storage;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::unregisterModStorage(const std::string &name)
|
||||||
|
{
|
||||||
|
UNORDERED_MAP<std::string, ModMetadata *>::const_iterator it = m_mod_storages.find(name);
|
||||||
|
if (it != m_mod_storages.end()) {
|
||||||
|
// Save unconditionaly on unregistration
|
||||||
|
it->second->save(getModStoragePath());
|
||||||
|
m_mod_storages.erase(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Client::getModStoragePath() const
|
||||||
|
{
|
||||||
|
return porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "mod_storage";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -554,6 +554,10 @@ public:
|
|||||||
{ return checkPrivilege(priv); }
|
{ return checkPrivilege(priv); }
|
||||||
virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
|
virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
|
||||||
|
|
||||||
|
virtual std::string getModStoragePath() const;
|
||||||
|
virtual bool registerModStorage(ModMetadata *meta);
|
||||||
|
virtual void unregisterModStorage(const std::string &name);
|
||||||
|
|
||||||
// The following set of functions is used by ClientMediaDownloader
|
// The following set of functions is used by ClientMediaDownloader
|
||||||
// Insert a media file appropriately into the appropriate manager
|
// Insert a media file appropriately into the appropriate manager
|
||||||
bool loadMedia(const std::string &data, const std::string &filename);
|
bool loadMedia(const std::string &data, const std::string &filename);
|
||||||
@ -724,6 +728,8 @@ private:
|
|||||||
|
|
||||||
ClientScripting *m_script;
|
ClientScripting *m_script;
|
||||||
bool m_modding_enabled;
|
bool m_modding_enabled;
|
||||||
|
UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
|
||||||
|
float m_mod_storage_save_timer;
|
||||||
|
|
||||||
DISABLE_CLASS_COPY(Client);
|
DISABLE_CLASS_COPY(Client);
|
||||||
};
|
};
|
||||||
|
@ -34,6 +34,7 @@ class MtEventManager;
|
|||||||
class IRollbackManager;
|
class IRollbackManager;
|
||||||
class EmergeManager;
|
class EmergeManager;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
class ModMetadata;
|
||||||
|
|
||||||
namespace irr { namespace scene {
|
namespace irr { namespace scene {
|
||||||
class IAnimatedMesh;
|
class IAnimatedMesh;
|
||||||
@ -75,6 +76,9 @@ public:
|
|||||||
virtual const std::vector<ModSpec> &getMods() const = 0;
|
virtual const std::vector<ModSpec> &getMods() const = 0;
|
||||||
virtual const ModSpec* getModSpec(const std::string &modname) const = 0;
|
virtual const ModSpec* getModSpec(const std::string &modname) const = 0;
|
||||||
virtual std::string getWorldPath() const { return ""; }
|
virtual std::string getWorldPath() const { return ""; }
|
||||||
|
virtual std::string getModStoragePath() const = 0;
|
||||||
|
virtual bool registerModStorage(ModMetadata *storage) = 0;
|
||||||
|
virtual void unregisterModStorage(const std::string &name) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,4 +58,5 @@ void ClientScripting::InitializeModApi(lua_State *L, int top)
|
|||||||
ModApiStorage::Initialize(L, top);
|
ModApiStorage::Initialize(L, top);
|
||||||
|
|
||||||
LuaItemStack::Register(L);
|
LuaItemStack::Register(L);
|
||||||
|
StorageRef::Register(L);
|
||||||
}
|
}
|
||||||
|
@ -33,10 +33,9 @@ int ModApiStorage::l_get_mod_storage(lua_State *L)
|
|||||||
std::string mod_name = lua_tostring(L, -1);
|
std::string mod_name = lua_tostring(L, -1);
|
||||||
|
|
||||||
ModMetadata *store = new ModMetadata(mod_name);
|
ModMetadata *store = new ModMetadata(mod_name);
|
||||||
// For server side
|
if (IGameDef *gamedef = getGameDef(L)) {
|
||||||
if (Server *server = getServer(L)) {
|
store->load(gamedef->getModStoragePath());
|
||||||
store->load(server->getModStoragePath());
|
gamedef->registerModStorage(store);
|
||||||
server->registerModStorage(store);
|
|
||||||
} else {
|
} else {
|
||||||
assert(false); // this should not happen
|
assert(false); // this should not happen
|
||||||
}
|
}
|
||||||
@ -70,8 +69,8 @@ int StorageRef::gc_object(lua_State *L)
|
|||||||
{
|
{
|
||||||
StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
|
StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
|
||||||
// Server side
|
// Server side
|
||||||
if (Server *server = getServer(L))
|
if (IGameDef *gamedef = getGameDef(L))
|
||||||
server->unregisterModStorage(getobject(o)->getModName());
|
gamedef->unregisterModStorage(getobject(o)->getModName());
|
||||||
delete o;
|
delete o;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -299,8 +299,8 @@ public:
|
|||||||
virtual const ModSpec* getModSpec(const std::string &modname) const;
|
virtual const ModSpec* getModSpec(const std::string &modname) const;
|
||||||
void getModNames(std::vector<std::string> &modlist);
|
void getModNames(std::vector<std::string> &modlist);
|
||||||
std::string getBuiltinLuaPath();
|
std::string getBuiltinLuaPath();
|
||||||
std::string getWorldPath() const { return m_path_world; }
|
virtual std::string getWorldPath() const { return m_path_world; }
|
||||||
std::string getModStoragePath() const;
|
virtual std::string getModStoragePath() const;
|
||||||
|
|
||||||
inline bool isSingleplayer()
|
inline bool isSingleplayer()
|
||||||
{ return m_simple_singleplayer_mode; }
|
{ return m_simple_singleplayer_mode; }
|
||||||
@ -361,8 +361,8 @@ public:
|
|||||||
void SendInventory(PlayerSAO* playerSAO);
|
void SendInventory(PlayerSAO* playerSAO);
|
||||||
void SendMovePlayer(u16 peer_id);
|
void SendMovePlayer(u16 peer_id);
|
||||||
|
|
||||||
bool registerModStorage(ModMetadata *storage);
|
virtual bool registerModStorage(ModMetadata *storage);
|
||||||
void unregisterModStorage(const std::string &name);
|
virtual void unregisterModStorage(const std::string &name);
|
||||||
|
|
||||||
// Bind address
|
// Bind address
|
||||||
Address m_bind_addr;
|
Address m_bind_addr;
|
||||||
|
@ -65,6 +65,9 @@ public:
|
|||||||
return testmodspec;
|
return testmodspec;
|
||||||
}
|
}
|
||||||
virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; }
|
virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; }
|
||||||
|
virtual std::string getModStoragePath() const { return "."; }
|
||||||
|
virtual bool registerModStorage(ModMetadata *meta) { return true; }
|
||||||
|
virtual void unregisterModStorage(const std::string &name) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IItemDefManager *m_itemdef;
|
IItemDefManager *m_itemdef;
|
||||||
|
Loading…
Reference in New Issue
Block a user