Skip to content

Commit 0a5e771

Browse files
authoredOct 10, 2018
Add core.remove_detached_inventory (#7684)
Breaks backwards compatibility for good Bump protocol version
1 parent d6f2a1c commit 0a5e771

File tree

8 files changed

+100
-34
lines changed

8 files changed

+100
-34
lines changed
 

Diff for: ‎builtin/game/detached_inventory.lua

+4
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ function core.create_detached_inventory(name, callbacks, player_name)
1818
return core.create_detached_inventory_raw(name, player_name)
1919
end
2020

21+
function core.remove_detached_inventory(name)
22+
core.detached_inventories[name] = nil
23+
return core.remove_detached_inventory_raw(name)
24+
end

Diff for: ‎doc/lua_api.txt

+2
Original file line numberDiff line numberDiff line change
@@ -4141,6 +4141,8 @@ Inventory
41414141
Note that this parameter is mostly just a workaround and will be removed
41424142
in future releases.
41434143
* Creates a detached inventory. If it already exists, it is cleared.
4144+
* `minetest.remove_detached_inventory(name)`
4145+
* Returns a `boolean` indicating whether the removal succeeded.
41444146
* `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`:
41454147
returns left over ItemStack.
41464148
* See `minetest.item_eat` and `minetest.register_on_item_eat`

Diff for: ‎src/network/clientpackethandler.cpp

+20-9
Original file line numberDiff line numberDiff line change
@@ -843,21 +843,32 @@ void Client::handleCommand_InventoryFormSpec(NetworkPacket* pkt)
843843

844844
void Client::handleCommand_DetachedInventory(NetworkPacket* pkt)
845845
{
846-
std::string datastring(pkt->getString(0), pkt->getSize());
847-
std::istringstream is(datastring, std::ios_base::binary);
848-
849-
std::string name = deSerializeString(is);
846+
std::string name;
847+
bool keep_inv = true;
848+
*pkt >> name >> keep_inv;
850849

851850
infostream << "Client: Detached inventory update: \"" << name
852-
<< "\"" << std::endl;
851+
<< "\", mode=" << (keep_inv ? "update" : "remove") << std::endl;
853852

854-
Inventory *inv = NULL;
855-
if (m_detached_inventories.count(name) > 0)
856-
inv = m_detached_inventories[name];
857-
else {
853+
const auto &inv_it = m_detached_inventories.find(name);
854+
if (!keep_inv) {
855+
if (inv_it != m_detached_inventories.end()) {
856+
delete inv_it->second;
857+
m_detached_inventories.erase(inv_it);
858+
}
859+
return;
860+
}
861+
Inventory *inv = nullptr;
862+
if (inv_it == m_detached_inventories.end()) {
858863
inv = new Inventory(m_itemdef);
859864
m_detached_inventories[name] = inv;
865+
} else {
866+
inv = inv_it->second;
860867
}
868+
869+
std::string contents;
870+
*pkt >> contents;
871+
std::istringstream is(contents, std::ios::binary);
861872
inv->deSerialize(is);
862873
}
863874

Diff for: ‎src/network/networkprotocol.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -188,19 +188,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
188188
Nodebox version 5
189189
Add disconnected nodeboxes
190190
Add TOCLIENT_FORMSPEC_PREPEND
191+
PROTOCOL VERSION 37:
192+
Redo detached inventory sending
191193
*/
192194

193-
#define LATEST_PROTOCOL_VERSION 36
195+
#define LATEST_PROTOCOL_VERSION 37
194196
#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
195197

196198
// Server's supported network protocol range
197-
#define SERVER_PROTOCOL_VERSION_MIN 36
199+
#define SERVER_PROTOCOL_VERSION_MIN 37
198200
#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
199201

200202
// Client's supported network protocol range
201203
// The minimal version depends on whether
202204
// send_pre_v25_init is enabled or not
203-
#define CLIENT_PROTOCOL_VERSION_MIN 36
205+
#define CLIENT_PROTOCOL_VERSION_MIN 37
204206
#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
205207

206208
// Constant that differentiates the protocol from random data and other protocols

Diff for: ‎src/script/lua_api/l_inventory.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -536,8 +536,18 @@ int ModApiInventory::l_create_detached_inventory_raw(lua_State *L)
536536
return 1;
537537
}
538538

539+
// remove_detached_inventory_raw(name)
540+
int ModApiInventory::l_remove_detached_inventory_raw(lua_State *L)
541+
{
542+
NO_MAP_LOCK_REQUIRED;
543+
const std::string &name = luaL_checkstring(L, 1);
544+
lua_pushboolean(L, getServer(L)->removeDetachedInventory(name));
545+
return 1;
546+
}
547+
539548
void ModApiInventory::Initialize(lua_State *L, int top)
540549
{
541550
API_FCT(create_detached_inventory_raw);
551+
API_FCT(remove_detached_inventory_raw);
542552
API_FCT(get_inventory);
543553
}

Diff for: ‎src/script/lua_api/l_inventory.h

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ class ModApiInventory : public ModApiBase {
120120
private:
121121
static int l_create_detached_inventory_raw(lua_State *L);
122122

123+
static int l_remove_detached_inventory_raw(lua_State *L);
124+
123125
static int l_get_inventory(lua_State *L);
124126

125127
public:

Diff for: ‎src/server.cpp

+54-21
Original file line numberDiff line numberDiff line change
@@ -2478,33 +2478,41 @@ void Server::sendRequestedMedia(session_t peer_id,
24782478

24792479
void Server::sendDetachedInventory(const std::string &name, session_t peer_id)
24802480
{
2481-
if(m_detached_inventories.count(name) == 0) {
2482-
errorstream<<FUNCTION_NAME<<": \""<<name<<"\" not found"<<std::endl;
2483-
return;
2484-
}
2485-
Inventory *inv = m_detached_inventories[name];
2486-
std::ostringstream os(std::ios_base::binary);
2481+
const auto &inv_it = m_detached_inventories.find(name);
2482+
const auto &player_it = m_detached_inventories_player.find(name);
24872483

2488-
os << serializeString(name);
2489-
inv->serialize(os);
2484+
if (player_it == m_detached_inventories_player.end() ||
2485+
player_it->second.empty()) {
2486+
// OK. Send to everyone
2487+
} else {
2488+
RemotePlayer *p = m_env->getPlayer(player_it->second.c_str());
2489+
if (!p)
2490+
return; // Player is offline
24902491

2491-
// Make data buffer
2492-
std::string s = os.str();
2492+
if (peer_id != PEER_ID_INEXISTENT && peer_id != p->getPeerId())
2493+
return; // Caller requested send to a different player, so don't send.
2494+
2495+
peer_id = p->getPeerId();
2496+
}
24932497

24942498
NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id);
2495-
pkt.putRawString(s.c_str(), s.size());
2499+
pkt << name;
24962500

2497-
const std::string &check = m_detached_inventories_player[name];
2498-
if (peer_id == PEER_ID_INEXISTENT) {
2499-
if (check.empty())
2500-
return m_clients.sendToAll(&pkt);
2501-
RemotePlayer *p = m_env->getPlayer(check.c_str());
2502-
if (p)
2503-
m_clients.send(p->getPeerId(), 0, &pkt, true);
2501+
if (inv_it == m_detached_inventories.end()) {
2502+
pkt << false; // Remove inventory
25042503
} else {
2505-
if (check.empty() || getPlayerName(peer_id) == check)
2506-
Send(&pkt);
2504+
pkt << true; // Update inventory
2505+
2506+
// Serialization & NetworkPacket isn't a love story
2507+
std::ostringstream os(std::ios_base::binary);
2508+
inv_it->second->serialize(os);
2509+
pkt << os.str();
25072510
}
2511+
2512+
if (peer_id == PEER_ID_INEXISTENT)
2513+
m_clients.sendToAll(&pkt);
2514+
else
2515+
Send(&pkt);
25082516
}
25092517

25102518
void Server::sendDetachedInventories(session_t peer_id)
@@ -2665,9 +2673,10 @@ void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason)
26652673
playersao->clearParentAttachment();
26662674

26672675
// inform connected clients
2676+
const std::string &player_name = player->getName();
26682677
NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
26692678
// (u16) 1 + std::string represents a vector serialization representation
2670-
notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << std::string(playersao->getPlayer()->getName());
2679+
notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << player_name;
26712680
m_clients.sendToAll(&notice);
26722681
// run scripts
26732682
m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT);
@@ -3265,6 +3274,30 @@ Inventory* Server::createDetachedInventory(const std::string &name, const std::s
32653274
return inv;
32663275
}
32673276

3277+
bool Server::removeDetachedInventory(const std::string &name)
3278+
{
3279+
const auto &inv_it = m_detached_inventories.find(name);
3280+
if (inv_it == m_detached_inventories.end())
3281+
return false;
3282+
3283+
delete inv_it->second;
3284+
m_detached_inventories.erase(inv_it);
3285+
3286+
const auto &player_it = m_detached_inventories_player.find(name);
3287+
if (player_it != m_detached_inventories_player.end()) {
3288+
RemotePlayer *player = m_env->getPlayer(player_it->second.c_str());
3289+
3290+
if (player && player->getPeerId() != PEER_ID_INEXISTENT)
3291+
sendDetachedInventory(name, player->getPeerId());
3292+
3293+
m_detached_inventories_player.erase(player_it);
3294+
} else {
3295+
// Notify all players about the change
3296+
sendDetachedInventory(name, PEER_ID_INEXISTENT);
3297+
}
3298+
return true;
3299+
}
3300+
32683301
// actions: time-reversed list
32693302
// Return value: success/failure
32703303
bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,

Diff for: ‎src/server.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ class Server : public con::PeerHandler, public MapEventReceiver,
248248
void deleteParticleSpawner(const std::string &playername, u32 id);
249249

250250
// Creates or resets inventory
251-
Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
251+
Inventory *createDetachedInventory(const std::string &name,
252+
const std::string &player = "");
253+
bool removeDetachedInventory(const std::string &name);
252254

253255
// Envlock and conlock should be locked when using scriptapi
254256
ServerScripting *getScriptIface(){ return m_script; }

0 commit comments

Comments
 (0)
Please sign in to comment.