Skip to content

Commit

Permalink
Allow restricting detached inventories to one player
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sfan5 committed Nov 28, 2016
1 parent 2fe3bf5 commit c389858
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 13 deletions.
4 changes: 2 additions & 2 deletions builtin/game/detached_inventory.lua
Expand Up @@ -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
Expand All @@ -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

5 changes: 4 additions & 1 deletion doc/lua_api.txt
Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions src/script/lua_api/l_inventory.cpp
Expand Up @@ -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;
Expand Down
18 changes: 12 additions & 6 deletions src/server.cpp
Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion src/server.h
Expand Up @@ -270,7 +270,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
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; }
Expand Down Expand Up @@ -647,6 +647,8 @@ class Server : public con::PeerHandler, public MapEventReceiver,
*/
// 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);
};
Expand Down

0 comments on commit c389858

Please sign in to comment.