forked from Mirrorlandia_minetest/minetest
Add core.remove_detached_inventory (#7684)
Breaks backwards compatibility for good Bump protocol version
This commit is contained in:
parent
d6f2a1c4b8
commit
0a5e77132a
@ -18,3 +18,7 @@ function core.create_detached_inventory(name, callbacks, player_name)
|
|||||||
return core.create_detached_inventory_raw(name, player_name)
|
return core.create_detached_inventory_raw(name, player_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function core.remove_detached_inventory(name)
|
||||||
|
core.detached_inventories[name] = nil
|
||||||
|
return core.remove_detached_inventory_raw(name)
|
||||||
|
end
|
||||||
|
@ -4141,6 +4141,8 @@ Inventory
|
|||||||
Note that this parameter is mostly just a workaround and will be removed
|
Note that this parameter is mostly just a workaround and will be removed
|
||||||
in future releases.
|
in future releases.
|
||||||
* Creates a detached inventory. If it already exists, it is cleared.
|
* Creates a detached inventory. If it already exists, it is cleared.
|
||||||
|
* `minetest.remove_detached_inventory(name)`
|
||||||
|
* Returns a `boolean` indicating whether the removal succeeded.
|
||||||
* `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`:
|
* `minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing)`:
|
||||||
returns left over ItemStack.
|
returns left over ItemStack.
|
||||||
* See `minetest.item_eat` and `minetest.register_on_item_eat`
|
* See `minetest.item_eat` and `minetest.register_on_item_eat`
|
||||||
|
@ -843,21 +843,32 @@ void Client::handleCommand_InventoryFormSpec(NetworkPacket* pkt)
|
|||||||
|
|
||||||
void Client::handleCommand_DetachedInventory(NetworkPacket* pkt)
|
void Client::handleCommand_DetachedInventory(NetworkPacket* pkt)
|
||||||
{
|
{
|
||||||
std::string datastring(pkt->getString(0), pkt->getSize());
|
std::string name;
|
||||||
std::istringstream is(datastring, std::ios_base::binary);
|
bool keep_inv = true;
|
||||||
|
*pkt >> name >> keep_inv;
|
||||||
std::string name = deSerializeString(is);
|
|
||||||
|
|
||||||
infostream << "Client: Detached inventory update: \"" << name
|
infostream << "Client: Detached inventory update: \"" << name
|
||||||
<< "\"" << std::endl;
|
<< "\", mode=" << (keep_inv ? "update" : "remove") << std::endl;
|
||||||
|
|
||||||
Inventory *inv = NULL;
|
const auto &inv_it = m_detached_inventories.find(name);
|
||||||
if (m_detached_inventories.count(name) > 0)
|
if (!keep_inv) {
|
||||||
inv = m_detached_inventories[name];
|
if (inv_it != m_detached_inventories.end()) {
|
||||||
else {
|
delete inv_it->second;
|
||||||
|
m_detached_inventories.erase(inv_it);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Inventory *inv = nullptr;
|
||||||
|
if (inv_it == m_detached_inventories.end()) {
|
||||||
inv = new Inventory(m_itemdef);
|
inv = new Inventory(m_itemdef);
|
||||||
m_detached_inventories[name] = inv;
|
m_detached_inventories[name] = inv;
|
||||||
|
} else {
|
||||||
|
inv = inv_it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string contents;
|
||||||
|
*pkt >> contents;
|
||||||
|
std::istringstream is(contents, std::ios::binary);
|
||||||
inv->deSerialize(is);
|
inv->deSerialize(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,19 +188,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
Nodebox version 5
|
Nodebox version 5
|
||||||
Add disconnected nodeboxes
|
Add disconnected nodeboxes
|
||||||
Add TOCLIENT_FORMSPEC_PREPEND
|
Add TOCLIENT_FORMSPEC_PREPEND
|
||||||
|
PROTOCOL VERSION 37:
|
||||||
|
Redo detached inventory sending
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LATEST_PROTOCOL_VERSION 36
|
#define LATEST_PROTOCOL_VERSION 37
|
||||||
#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
|
#define LATEST_PROTOCOL_VERSION_STRING TOSTRING(LATEST_PROTOCOL_VERSION)
|
||||||
|
|
||||||
// Server's supported network protocol range
|
// Server's supported network protocol range
|
||||||
#define SERVER_PROTOCOL_VERSION_MIN 36
|
#define SERVER_PROTOCOL_VERSION_MIN 37
|
||||||
#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
|
#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
|
||||||
|
|
||||||
// Client's supported network protocol range
|
// Client's supported network protocol range
|
||||||
// The minimal version depends on whether
|
// The minimal version depends on whether
|
||||||
// send_pre_v25_init is enabled or not
|
// send_pre_v25_init is enabled or not
|
||||||
#define CLIENT_PROTOCOL_VERSION_MIN 36
|
#define CLIENT_PROTOCOL_VERSION_MIN 37
|
||||||
#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
|
#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
|
||||||
|
|
||||||
// Constant that differentiates the protocol from random data and other protocols
|
// Constant that differentiates the protocol from random data and other protocols
|
||||||
|
@ -536,8 +536,18 @@ int ModApiInventory::l_create_detached_inventory_raw(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove_detached_inventory_raw(name)
|
||||||
|
int ModApiInventory::l_remove_detached_inventory_raw(lua_State *L)
|
||||||
|
{
|
||||||
|
NO_MAP_LOCK_REQUIRED;
|
||||||
|
const std::string &name = luaL_checkstring(L, 1);
|
||||||
|
lua_pushboolean(L, getServer(L)->removeDetachedInventory(name));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
void ModApiInventory::Initialize(lua_State *L, int top)
|
void ModApiInventory::Initialize(lua_State *L, int top)
|
||||||
{
|
{
|
||||||
API_FCT(create_detached_inventory_raw);
|
API_FCT(create_detached_inventory_raw);
|
||||||
|
API_FCT(remove_detached_inventory_raw);
|
||||||
API_FCT(get_inventory);
|
API_FCT(get_inventory);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +120,8 @@ class ModApiInventory : public ModApiBase {
|
|||||||
private:
|
private:
|
||||||
static int l_create_detached_inventory_raw(lua_State *L);
|
static int l_create_detached_inventory_raw(lua_State *L);
|
||||||
|
|
||||||
|
static int l_remove_detached_inventory_raw(lua_State *L);
|
||||||
|
|
||||||
static int l_get_inventory(lua_State *L);
|
static int l_get_inventory(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -2478,33 +2478,41 @@ void Server::sendRequestedMedia(session_t peer_id,
|
|||||||
|
|
||||||
void Server::sendDetachedInventory(const std::string &name, session_t peer_id)
|
void Server::sendDetachedInventory(const std::string &name, session_t peer_id)
|
||||||
{
|
{
|
||||||
if(m_detached_inventories.count(name) == 0) {
|
const auto &inv_it = m_detached_inventories.find(name);
|
||||||
errorstream<<FUNCTION_NAME<<": \""<<name<<"\" not found"<<std::endl;
|
const auto &player_it = m_detached_inventories_player.find(name);
|
||||||
return;
|
|
||||||
|
if (player_it == m_detached_inventories_player.end() ||
|
||||||
|
player_it->second.empty()) {
|
||||||
|
// OK. Send to everyone
|
||||||
|
} else {
|
||||||
|
RemotePlayer *p = m_env->getPlayer(player_it->second.c_str());
|
||||||
|
if (!p)
|
||||||
|
return; // Player is offline
|
||||||
|
|
||||||
|
if (peer_id != PEER_ID_INEXISTENT && peer_id != p->getPeerId())
|
||||||
|
return; // Caller requested send to a different player, so don't send.
|
||||||
|
|
||||||
|
peer_id = p->getPeerId();
|
||||||
}
|
}
|
||||||
Inventory *inv = m_detached_inventories[name];
|
|
||||||
std::ostringstream os(std::ios_base::binary);
|
|
||||||
|
|
||||||
os << serializeString(name);
|
|
||||||
inv->serialize(os);
|
|
||||||
|
|
||||||
// Make data buffer
|
|
||||||
std::string s = os.str();
|
|
||||||
|
|
||||||
NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id);
|
NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id);
|
||||||
pkt.putRawString(s.c_str(), s.size());
|
pkt << name;
|
||||||
|
|
||||||
const std::string &check = m_detached_inventories_player[name];
|
if (inv_it == m_detached_inventories.end()) {
|
||||||
if (peer_id == PEER_ID_INEXISTENT) {
|
pkt << false; // Remove inventory
|
||||||
if (check.empty())
|
|
||||||
return m_clients.sendToAll(&pkt);
|
|
||||||
RemotePlayer *p = m_env->getPlayer(check.c_str());
|
|
||||||
if (p)
|
|
||||||
m_clients.send(p->getPeerId(), 0, &pkt, true);
|
|
||||||
} else {
|
} else {
|
||||||
if (check.empty() || getPlayerName(peer_id) == check)
|
pkt << true; // Update inventory
|
||||||
Send(&pkt);
|
|
||||||
|
// Serialization & NetworkPacket isn't a love story
|
||||||
|
std::ostringstream os(std::ios_base::binary);
|
||||||
|
inv_it->second->serialize(os);
|
||||||
|
pkt << os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (peer_id == PEER_ID_INEXISTENT)
|
||||||
|
m_clients.sendToAll(&pkt);
|
||||||
|
else
|
||||||
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendDetachedInventories(session_t peer_id)
|
void Server::sendDetachedInventories(session_t peer_id)
|
||||||
@ -2665,9 +2673,10 @@ void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason)
|
|||||||
playersao->clearParentAttachment();
|
playersao->clearParentAttachment();
|
||||||
|
|
||||||
// inform connected clients
|
// inform connected clients
|
||||||
|
const std::string &player_name = player->getName();
|
||||||
NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
|
NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT);
|
||||||
// (u16) 1 + std::string represents a vector serialization representation
|
// (u16) 1 + std::string represents a vector serialization representation
|
||||||
notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << std::string(playersao->getPlayer()->getName());
|
notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << player_name;
|
||||||
m_clients.sendToAll(¬ice);
|
m_clients.sendToAll(¬ice);
|
||||||
// run scripts
|
// run scripts
|
||||||
m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT);
|
m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT);
|
||||||
@ -3265,6 +3274,30 @@ Inventory* Server::createDetachedInventory(const std::string &name, const std::s
|
|||||||
return inv;
|
return inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::removeDetachedInventory(const std::string &name)
|
||||||
|
{
|
||||||
|
const auto &inv_it = m_detached_inventories.find(name);
|
||||||
|
if (inv_it == m_detached_inventories.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
delete inv_it->second;
|
||||||
|
m_detached_inventories.erase(inv_it);
|
||||||
|
|
||||||
|
const auto &player_it = m_detached_inventories_player.find(name);
|
||||||
|
if (player_it != m_detached_inventories_player.end()) {
|
||||||
|
RemotePlayer *player = m_env->getPlayer(player_it->second.c_str());
|
||||||
|
|
||||||
|
if (player && player->getPeerId() != PEER_ID_INEXISTENT)
|
||||||
|
sendDetachedInventory(name, player->getPeerId());
|
||||||
|
|
||||||
|
m_detached_inventories_player.erase(player_it);
|
||||||
|
} else {
|
||||||
|
// Notify all players about the change
|
||||||
|
sendDetachedInventory(name, PEER_ID_INEXISTENT);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// actions: time-reversed list
|
// actions: time-reversed list
|
||||||
// Return value: success/failure
|
// Return value: success/failure
|
||||||
bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
|
bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions,
|
||||||
|
@ -248,7 +248,9 @@ public:
|
|||||||
void deleteParticleSpawner(const std::string &playername, u32 id);
|
void deleteParticleSpawner(const std::string &playername, u32 id);
|
||||||
|
|
||||||
// Creates or resets inventory
|
// Creates or resets inventory
|
||||||
Inventory* createDetachedInventory(const std::string &name, const std::string &player="");
|
Inventory *createDetachedInventory(const std::string &name,
|
||||||
|
const std::string &player = "");
|
||||||
|
bool removeDetachedInventory(const std::string &name);
|
||||||
|
|
||||||
// Envlock and conlock should be locked when using scriptapi
|
// Envlock and conlock should be locked when using scriptapi
|
||||||
ServerScripting *getScriptIface(){ return m_script; }
|
ServerScripting *getScriptIface(){ return m_script; }
|
||||||
|
Loading…
Reference in New Issue
Block a user