Skip to content

Commit eb88e5d

Browse files
authoredMar 16, 2017
Add ModStorageAPI to client side modding (#5396)
mod storage is located into user_path / client / mod_storage
1 parent 4627641 commit eb88e5d

File tree

8 files changed

+68
-11
lines changed

8 files changed

+68
-11
lines changed
 

‎clientmods/preview/init.lua

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
local modname = core.get_current_modname() or "??"
2+
local modstorage = core.get_mod_storage()
23

34
-- This is an example function to ensure it's working properly, should be removed before merge
45
core.register_on_shutdown(function()
@@ -49,6 +50,8 @@ core.register_chatcommand("test_node", {
4950

5051
core.after(2, function()
5152
print("[PREVIEW] loaded " .. modname .. " mod")
53+
modstorage:set_string("current_mod", modname)
54+
print(modstorage:get_string("current_mod"))
5255
end)
5356

5457
core.register_on_dignode(function(pos, node)

‎src/client.cpp

+42-1
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ Client::Client(
249249
m_removed_sounds_check_timer(0),
250250
m_state(LC_Created),
251251
m_localdb(NULL),
252-
m_script(NULL)
252+
m_script(NULL),
253+
m_mod_storage_save_timer(10.0f)
253254
{
254255
// Add local player
255256
m_env.setLocalPlayer(new LocalPlayer(this, playername));
@@ -730,6 +731,18 @@ void Client::step(float dtime)
730731
}
731732
}
732733

734+
m_mod_storage_save_timer -= dtime;
735+
if (m_mod_storage_save_timer <= 0.0f) {
736+
verbosestream << "Saving registered mod storages." << std::endl;
737+
m_mod_storage_save_timer = g_settings->getFloat("server_map_save_interval");
738+
for (UNORDERED_MAP<std::string, ModMetadata *>::const_iterator
739+
it = m_mod_storages.begin(); it != m_mod_storages.end(); ++it) {
740+
if (it->second->isModified()) {
741+
it->second->save(getModStoragePath());
742+
}
743+
}
744+
}
745+
733746
// Write server map
734747
if (m_localdb && m_localdb_save_interval.step(dtime,
735748
m_cache_save_interval)) {
@@ -1998,3 +2011,31 @@ scene::IAnimatedMesh* Client::getMesh(const std::string &filename)
19982011
smgr->getMeshCache()->removeMesh(mesh);
19992012
return mesh;
20002013
}
2014+
2015+
bool Client::registerModStorage(ModMetadata *storage)
2016+
{
2017+
if (m_mod_storages.find(storage->getModName()) != m_mod_storages.end()) {
2018+
errorstream << "Unable to register same mod storage twice. Storage name: "
2019+
<< storage->getModName() << std::endl;
2020+
return false;
2021+
}
2022+
2023+
m_mod_storages[storage->getModName()] = storage;
2024+
return true;
2025+
}
2026+
2027+
void Client::unregisterModStorage(const std::string &name)
2028+
{
2029+
UNORDERED_MAP<std::string, ModMetadata *>::const_iterator it = m_mod_storages.find(name);
2030+
if (it != m_mod_storages.end()) {
2031+
// Save unconditionaly on unregistration
2032+
it->second->save(getModStoragePath());
2033+
m_mod_storages.erase(name);
2034+
}
2035+
}
2036+
2037+
std::string Client::getModStoragePath() const
2038+
{
2039+
return porting::path_user + DIR_DELIM + "client" + DIR_DELIM + "mod_storage";
2040+
}
2041+

‎src/client.h

+6
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,10 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
554554
{ return checkPrivilege(priv); }
555555
virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
556556

557+
virtual std::string getModStoragePath() const;
558+
virtual bool registerModStorage(ModMetadata *meta);
559+
virtual void unregisterModStorage(const std::string &name);
560+
557561
// The following set of functions is used by ClientMediaDownloader
558562
// Insert a media file appropriately into the appropriate manager
559563
bool loadMedia(const std::string &data, const std::string &filename);
@@ -724,6 +728,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
724728

725729
ClientScripting *m_script;
726730
bool m_modding_enabled;
731+
UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
732+
float m_mod_storage_save_timer;
727733

728734
DISABLE_CLASS_COPY(Client);
729735
};

‎src/gamedef.h

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class MtEventManager;
3434
class IRollbackManager;
3535
class EmergeManager;
3636
class Camera;
37+
class ModMetadata;
3738

3839
namespace irr { namespace scene {
3940
class IAnimatedMesh;
@@ -75,6 +76,9 @@ class IGameDef
7576
virtual const std::vector<ModSpec> &getMods() const = 0;
7677
virtual const ModSpec* getModSpec(const std::string &modname) const = 0;
7778
virtual std::string getWorldPath() const { return ""; }
79+
virtual std::string getModStoragePath() const = 0;
80+
virtual bool registerModStorage(ModMetadata *storage) = 0;
81+
virtual void unregisterModStorage(const std::string &name) = 0;
7882
};
7983

8084
#endif

‎src/script/clientscripting.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ void ClientScripting::InitializeModApi(lua_State *L, int top)
5858
ModApiStorage::Initialize(L, top);
5959

6060
LuaItemStack::Register(L);
61+
StorageRef::Register(L);
6162
}

‎src/script/lua_api/l_storage.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ int ModApiStorage::l_get_mod_storage(lua_State *L)
3333
std::string mod_name = lua_tostring(L, -1);
3434

3535
ModMetadata *store = new ModMetadata(mod_name);
36-
// For server side
37-
if (Server *server = getServer(L)) {
38-
store->load(server->getModStoragePath());
39-
server->registerModStorage(store);
36+
if (IGameDef *gamedef = getGameDef(L)) {
37+
store->load(gamedef->getModStoragePath());
38+
gamedef->registerModStorage(store);
4039
} else {
4140
assert(false); // this should not happen
4241
}
@@ -70,8 +69,8 @@ int StorageRef::gc_object(lua_State *L)
7069
{
7170
StorageRef *o = *(StorageRef **)(lua_touserdata(L, 1));
7271
// Server side
73-
if (Server *server = getServer(L))
74-
server->unregisterModStorage(getobject(o)->getModName());
72+
if (IGameDef *gamedef = getGameDef(L))
73+
gamedef->unregisterModStorage(getobject(o)->getModName());
7574
delete o;
7675
return 0;
7776
}

‎src/server.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,8 @@ class Server : public con::PeerHandler, public MapEventReceiver,
299299
virtual const ModSpec* getModSpec(const std::string &modname) const;
300300
void getModNames(std::vector<std::string> &modlist);
301301
std::string getBuiltinLuaPath();
302-
std::string getWorldPath() const { return m_path_world; }
303-
std::string getModStoragePath() const;
302+
virtual std::string getWorldPath() const { return m_path_world; }
303+
virtual std::string getModStoragePath() const;
304304

305305
inline bool isSingleplayer()
306306
{ return m_simple_singleplayer_mode; }
@@ -361,8 +361,8 @@ class Server : public con::PeerHandler, public MapEventReceiver,
361361
void SendInventory(PlayerSAO* playerSAO);
362362
void SendMovePlayer(u16 peer_id);
363363

364-
bool registerModStorage(ModMetadata *storage);
365-
void unregisterModStorage(const std::string &name);
364+
virtual bool registerModStorage(ModMetadata *storage);
365+
virtual void unregisterModStorage(const std::string &name);
366366

367367
// Bind address
368368
Address m_bind_addr;

‎src/unittest/test.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class TestGameDef : public IGameDef {
6565
return testmodspec;
6666
}
6767
virtual const ModSpec* getModSpec(const std::string &modname) const { return NULL; }
68+
virtual std::string getModStoragePath() const { return "."; }
69+
virtual bool registerModStorage(ModMetadata *meta) { return true; }
70+
virtual void unregisterModStorage(const std::string &name) {}
6871

6972
private:
7073
IItemDefManager *m_itemdef;

0 commit comments

Comments
 (0)
Please sign in to comment.