From c38985825f299999135cc01aaf0052ec9138135a Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 26 Nov 2016 17:35:25 +0100 Subject: [PATCH] Allow restricting detached inventories to one player This combats the problem of sending the hundreds of "creative" / "armor" or whatever detached invs that exist on popular servers to each and every player on join or on change of said invs. --- builtin/game/detached_inventory.lua | 4 ++-- doc/lua_api.txt | 5 ++++- src/script/lua_api/l_inventory.cpp | 7 ++++--- src/server.cpp | 18 ++++++++++++------ src/server.h | 4 +++- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/builtin/game/detached_inventory.lua b/builtin/game/detached_inventory.lua index b5d106b04..420e89ff2 100644 --- a/builtin/game/detached_inventory.lua +++ b/builtin/game/detached_inventory.lua @@ -2,7 +2,7 @@ core.detached_inventories = {} -function core.create_detached_inventory(name, callbacks) +function core.create_detached_inventory(name, callbacks, player_name) local stuff = {} stuff.name = name if callbacks then @@ -15,6 +15,6 @@ function core.create_detached_inventory(name, callbacks) end stuff.mod_origin = core.get_current_modname() or "??" core.detached_inventories[name] = stuff - return core.create_detached_inventory_raw(name) + return core.create_detached_inventory_raw(name, player_name) end diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 9da0fb4f9..eb47270f4 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2310,8 +2310,11 @@ and `minetest.auth_reload` call the authetification handler. * `{type="player", name="celeron55"}` * `{type="node", pos={x=, y=, z=}}` * `{type="detached", name="creative"}` -* `minetest.create_detached_inventory(name, callbacks)`: returns an `InvRef` +* `minetest.create_detached_inventory(name, callbacks, [player_name])`: returns an `InvRef` * callbacks: See "Detached inventory callbacks" + * player_name: Make detached inventory available to one player exclusively, + by default they will be sent to every player (even if not used). + Note that this parameter is mostly just a workaround and will be removed in future releases. * Creates a detached inventory. If it already exists, it is cleared. * `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`: returns left over ItemStack diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp index 110e68d23..38eade609 100644 --- a/src/script/lua_api/l_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -520,16 +520,17 @@ int ModApiInventory::l_get_inventory(lua_State *L) } } -// create_detached_inventory_raw(name) +// create_detached_inventory_raw(name, [player_name]) int ModApiInventory::l_create_detached_inventory_raw(lua_State *L) { NO_MAP_LOCK_REQUIRED; const char *name = luaL_checkstring(L, 1); - if(getServer(L)->createDetachedInventory(name) != NULL){ + const char *player = lua_isstring(L, 2) ? lua_tostring(L, 2) : ""; + if (getServer(L)->createDetachedInventory(name, player) != NULL) { InventoryLocation loc; loc.setDetached(name); InvRef::create(L, loc); - }else{ + } else { lua_pushnil(L); } return 1; diff --git a/src/server.cpp b/src/server.cpp index fae375425..fe67ac96e 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2487,11 +2487,16 @@ void Server::sendDetachedInventory(const std::string &name, u16 peer_id) NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id); pkt.putRawString(s.c_str(), s.size()); - if (peer_id != PEER_ID_INEXISTENT) { - Send(&pkt); - } - else { - m_clients.sendToAll(0, &pkt, true); + const std::string &check = m_detached_inventories_player[name]; + if (peer_id == PEER_ID_INEXISTENT) { + if (check == "") + return m_clients.sendToAll(0, &pkt, true); + RemotePlayer *p = m_env->getPlayer(check.c_str()); + if (p) + m_clients.send(p->peer_id, 0, &pkt, true); + } else { + if (check == "" || getPlayerName(peer_id) == check) + Send(&pkt); } } @@ -3224,7 +3229,7 @@ void Server::deleteParticleSpawner(const std::string &playername, u32 id) SendDeleteParticleSpawner(peer_id, id); } -Inventory* Server::createDetachedInventory(const std::string &name) +Inventory* Server::createDetachedInventory(const std::string &name, const std::string &player) { if(m_detached_inventories.count(name) > 0){ infostream<<"Server clearing detached inventory \""< m_detached_inventories; + // value = "" (visible to all players) or player name + std::map m_detached_inventories_player; DISABLE_CLASS_COPY(Server); };