aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsfan5 <sfan5@live.de>2016-11-26 17:35:25 +0100
committersfan5 <sfan5@live.de>2016-11-28 13:41:19 +0100
commitc38985825f299999135cc01aaf0052ec9138135a (patch)
treec54db1b2f7e8a27dd5c1d693c6e0ee92386271b9
parent2fe3bf5a18eb9aa9f38654b3c0a0729c42408cd6 (diff)
downloadminetest-c38985825f299999135cc01aaf0052ec9138135a.tar.gz
minetest-c38985825f299999135cc01aaf0052ec9138135a.tar.bz2
minetest-c38985825f299999135cc01aaf0052ec9138135a.zip
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.
-rw-r--r--builtin/game/detached_inventory.lua4
-rw-r--r--doc/lua_api.txt5
-rw-r--r--src/script/lua_api/l_inventory.cpp7
-rw-r--r--src/server.cpp18
-rw-r--r--src/server.h4
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 \""<<name<<"\""<<std::endl;
@@ -3235,6 +3240,7 @@ Inventory* Server::createDetachedInventory(const std::string &name)
Inventory *inv = new Inventory(m_itemdef);
sanity_check(inv);
m_detached_inventories[name] = inv;
+ m_detached_inventories_player[name] = player;
//TODO find a better way to do this
sendDetachedInventory(name,PEER_ID_INEXISTENT);
return inv;
diff --git a/src/server.h b/src/server.h
index 9e844e36c..cc2bcef25 100644
--- a/src/server.h
+++ b/src/server.h
@@ -270,7 +270,7 @@ public:
void deleteParticleSpawner(const std::string &playername, u32 id);
// Creates or resets inventory
- Inventory* createDetachedInventory(const std::string &name);
+ Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
// Envlock and conlock should be locked when using scriptapi
GameScripting *getScriptIface(){ return m_script; }
@@ -647,6 +647,8 @@ private:
*/
// key = name
std::map<std::string, Inventory*> m_detached_inventories;
+ // value = "" (visible to all players) or player name
+ std::map<std::string, std::string> m_detached_inventories_player;
DISABLE_CLASS_COPY(Server);
};