aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/inventory.cpp28
-rw-r--r--src/inventory.h9
-rw-r--r--src/inventoryoptimisation.h28
-rw-r--r--src/itemstackmetadata.cpp5
-rw-r--r--src/itemstackmetadata.h3
-rw-r--r--src/mapblock.cpp4
-rw-r--r--src/mapblock.h3
-rw-r--r--src/nodemetadata.cpp8
-rw-r--r--src/nodemetadata.h5
-rw-r--r--src/script/lua_api/l_item.cpp2
-rw-r--r--src/server.cpp43
-rw-r--r--src/server.h1
-rw-r--r--src/unittest/test_inventory.cpp4
13 files changed, 96 insertions, 47 deletions
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 147fbd30e..28245f6ea 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -56,7 +56,7 @@ ItemStack::ItemStack(const std::string &name_, u16 count_,
count = 1;
}
-void ItemStack::serialize(std::ostream &os, bool serialize_meta, bool disk) const
+void ItemStack::serialize(std::ostream &os, InventoryOptimizationOption opt) const
{
if (empty())
return;
@@ -77,10 +77,10 @@ void ItemStack::serialize(std::ostream &os, bool serialize_meta, bool disk) cons
os << " " << wear;
if (parts >= 4) {
os << " ";
- if (serialize_meta)
- metadata.serialize(os, disk);
- else
+ if (opt & INV_OO_NO_META)
os << "<metadata size=" << metadata.size() << ">";
+ else
+ metadata.serialize(os, opt);
}
}
@@ -243,10 +243,10 @@ void ItemStack::deSerialize(const std::string &str, IItemDefManager *itemdef)
deSerialize(is, itemdef);
}
-std::string ItemStack::getItemString(bool include_meta, bool disk) const
+std::string ItemStack::getItemString(InventoryOptimizationOption opt) const
{
std::ostringstream os(std::ios::binary);
- serialize(os, include_meta, disk);
+ serialize(os, opt);
return os.str();
}
@@ -425,7 +425,7 @@ void InventoryList::setName(const std::string &name)
setModified();
}
-void InventoryList::serialize(std::ostream &os, bool incremental, bool disk) const
+void InventoryList::serialize(std::ostream &os, InventoryOptimizationOption opt) const
{
//os.imbue(std::locale("C"));
@@ -436,10 +436,10 @@ void InventoryList::serialize(std::ostream &os, bool incremental, bool disk) con
os<<"Empty";
} else {
os<<"Item ";
- item.serialize(os, true, disk);
+ item.serialize(os, opt);
}
// TODO: Implement this:
- // if (!incremental || item.checkModified())
+ // if (opt & INV_OO_INCREMENTAL && !item.checkModified())
// os << "Keep";
os<<"\n";
}
@@ -847,15 +847,15 @@ bool Inventory::operator == (const Inventory &other) const
return true;
}
-void Inventory::serialize(std::ostream &os, bool incremental, bool disk) const
+void Inventory::serialize(std::ostream &os, InventoryOptimizationOption opt) const
{
//std::cout << "Serialize " << (int)incremental << ", n=" << m_lists.size() << std::endl;
for (const InventoryList *list : m_lists) {
- if (!incremental || list->checkModified()) {
- os << "List " << list->getName() << " " << list->getSize() << "\n";
- list->serialize(os, incremental, disk);
- } else {
+ if (opt & INV_OO_INCREMENTAL && !list->checkModified()) {
os << "KeepList " << list->getName() << "\n";
+ } else {
+ os << "List " << list->getName() << " " << list->getSize() << "\n";
+ list->serialize(os, opt);
}
}
diff --git a/src/inventory.h b/src/inventory.h
index e6a7bf880..2237b7a7c 100644
--- a/src/inventory.h
+++ b/src/inventory.h
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
+#include "inventoryoptimisation.h"
#include "itemdef.h"
#include "irrlichttypes.h"
#include "itemstackmetadata.h"
@@ -40,13 +41,13 @@ struct ItemStack
~ItemStack() = default;
// Serialization
- void serialize(std::ostream &os, bool serialize_meta = true, bool disk = true) const;
+ void serialize(std::ostream &os, InventoryOptimizationOption opt = INV_OO_NONE) const;
// Deserialization. Pass itemdef unless you don't want aliases resolved.
void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL);
void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL);
// Returns the string used for inventory
- std::string getItemString(bool include_meta = true, bool disk = true) const;
+ std::string getItemString(InventoryOptimizationOption opt = INV_OO_NONE) const;
// Returns the tooltip
std::string getDescription(IItemDefManager *itemdef) const;
std::string getShortDescription(IItemDefManager *itemdef) const;
@@ -195,7 +196,7 @@ public:
void setSize(u32 newsize);
void setWidth(u32 newWidth);
void setName(const std::string &name);
- void serialize(std::ostream &os, bool incremental, bool disk = true) const;
+ void serialize(std::ostream &os, InventoryOptimizationOption opt = INV_OO_NONE) const;
void deSerialize(std::istream &is);
InventoryList(const InventoryList &other);
@@ -295,7 +296,7 @@ public:
}
// Never ever serialize to disk using "incremental"!
- void serialize(std::ostream &os, bool incremental = false, bool disk = true) const;
+ void serialize(std::ostream &os, InventoryOptimizationOption opt = INV_OO_NONE) const;
void deSerialize(std::istream &is);
InventoryList * addList(const std::string &name, u32 size);
diff --git a/src/inventoryoptimisation.h b/src/inventoryoptimisation.h
new file mode 100644
index 000000000..0ceb9c673
--- /dev/null
+++ b/src/inventoryoptimisation.h
@@ -0,0 +1,28 @@
+/*
+Minetest
+Copyright (C) 2021 Elias Fleckenstein <eliasfleckenstein@web.de>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+
+enum InventoryOptimizationOption {
+ INV_OO_NONE = 0,
+ INV_OO_INCREMENTAL = 0x0001,
+ INV_OO_META_SPARSE = 0x0002,
+ INV_OO_INCREMENTAL_META_SPARSE = 0x0003,
+ INV_OO_NO_META = 0x0004,
+};
diff --git a/src/itemstackmetadata.cpp b/src/itemstackmetadata.cpp
index b437a05f5..97d639f65 100644
--- a/src/itemstackmetadata.cpp
+++ b/src/itemstackmetadata.cpp
@@ -59,13 +59,14 @@ bool ItemStackMetadata::setString(const std::string &name, const std::string &va
return result;
}
-void ItemStackMetadata::serialize(std::ostream &os, bool disk) const
+void ItemStackMetadata::serialize(std::ostream &os, InventoryOptimizationOption opt) const
{
std::ostringstream os2;
os2 << DESERIALIZE_START;
std::string unsent_fields;
+ bool sparse_meta = opt & INV_OO_META_SPARSE;
for (const auto &stringvar : m_stringvars) {
- if (! disk
+ if (sparse_meta
&& stringvar.first != TOOLCAP_KEY
&& stringvar.first != "description"
&& stringvar.first != "color"
diff --git a/src/itemstackmetadata.h b/src/itemstackmetadata.h
index 7d81bf6dd..80787284c 100644
--- a/src/itemstackmetadata.h
+++ b/src/itemstackmetadata.h
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
+#include "inventoryoptimisation.h"
#include "metadata.h"
#include "tool.h"
@@ -34,7 +35,7 @@ public:
void clear() override;
bool setString(const std::string &name, const std::string &var) override;
- void serialize(std::ostream &os, bool disk = true) const;
+ void serialize(std::ostream &os, InventoryOptimizationOption opt = INV_OO_NONE) const;
void deSerialize(std::istream &is);
const ToolCapabilities &getToolCapabilities(
diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index 03633cf8e..eb878059e 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -355,7 +355,7 @@ static void correctBlockNodeIds(const NameIdMapping *nimap, MapNode *nodes,
}
}
-void MapBlock::serialize(std::ostream &os, u8 version, bool disk, int compression_level, bool disk_inv)
+void MapBlock::serialize(std::ostream &os, u8 version, bool disk, int compression_level, InventoryOptimizationOption opt)
{
if(!ser_ver_supported(version))
throw VersionMismatchException("ERROR: MapBlock format not supported");
@@ -411,7 +411,7 @@ void MapBlock::serialize(std::ostream &os, u8 version, bool disk, int compressio
Node metadata
*/
std::ostringstream oss(std::ios_base::binary);
- m_node_metadata.serialize(oss, version, disk, false, disk_inv);
+ m_node_metadata.serialize(oss, version, disk, false, opt);
compressZlib(oss.str(), os, compression_level);
/*
diff --git a/src/mapblock.h b/src/mapblock.h
index 1548afc30..3f5dd49f3 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <set>
#include "irr_v3d.h"
+#include "inventoryoptimisation.h"
#include "mapnode.h"
#include "exceptions.h"
#include "constants.h"
@@ -473,7 +474,7 @@ public:
// These don't write or read version by itself
// Set disk to true for on-disk format, false for over-the-network format
// Precondition: version >= SER_FMT_VER_LOWEST_WRITE
- void serialize(std::ostream &os, u8 version, bool disk, int compression_level, bool disk_inv = true);
+ void serialize(std::ostream &os, u8 version, bool disk, int compression_level, InventoryOptimizationOption opt = INV_OO_NONE);
// If disk == true: In addition to doing other things, will add
// unknown blocks from id-name mapping to wndef
void deSerialize(std::istream &is, u8 version, bool disk);
diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp
index b4ece067f..8c6f1c4de 100644
--- a/src/nodemetadata.cpp
+++ b/src/nodemetadata.cpp
@@ -40,7 +40,7 @@ NodeMetadata::~NodeMetadata()
delete m_inventory;
}
-void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk, bool disk_inv) const
+void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk, InventoryOptimizationOption opt) const
{
int num_vars = disk ? m_stringvars.size() : countNonPrivate();
writeU32(os, num_vars);
@@ -55,7 +55,7 @@ void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk, bool disk_
writeU8(os, (priv) ? 1 : 0);
}
- m_inventory->serialize(os, false, disk || disk_inv);
+ m_inventory->serialize(os, opt);
}
void NodeMetadata::deSerialize(std::istream &is, u8 version)
@@ -113,7 +113,7 @@ int NodeMetadata::countNonPrivate() const
*/
void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk,
- bool absolute_pos, bool disk_inv) const
+ bool absolute_pos, InventoryOptimizationOption opt) const
{
/*
Version 0 is a placeholder for "nothing to see here; go away."
@@ -146,7 +146,7 @@ void NodeMetadataList::serialize(std::ostream &os, u8 blockver, bool disk,
u16 p16 = (p.Z * MAP_BLOCKSIZE + p.Y) * MAP_BLOCKSIZE + p.X;
writeU16(os, p16);
}
- data->serialize(os, version, disk, disk_inv);
+ data->serialize(os, version, disk, opt);
}
}
diff --git a/src/nodemetadata.h b/src/nodemetadata.h
index 63b722c67..a7bc6191a 100644
--- a/src/nodemetadata.h
+++ b/src/nodemetadata.h
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
#include <unordered_set>
+#include "inventoryoptimisation.h"
#include "metadata.h"
/*
@@ -40,7 +41,7 @@ public:
NodeMetadata(IItemDefManager *item_def_mgr);
~NodeMetadata();
- void serialize(std::ostream &os, u8 version, bool disk = true, bool disk_inv = true) const;
+ void serialize(std::ostream &os, u8 version, bool disk = true, InventoryOptimizationOption opt = INV_OO_NONE) const;
void deSerialize(std::istream &is, u8 version);
void clear();
@@ -82,7 +83,7 @@ public:
~NodeMetadataList();
void serialize(std::ostream &os, u8 blockver, bool disk = true,
- bool absolute_pos = false, bool disk_inv = true) const;
+ bool absolute_pos = false, InventoryOptimizationOption opt = INV_OO_NONE) const;
void deSerialize(std::istream &is, IItemDefManager *item_def_mgr,
bool absolute_pos = false);
diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp
index 9e0da4034..7faf12340 100644
--- a/src/script/lua_api/l_item.cpp
+++ b/src/script/lua_api/l_item.cpp
@@ -41,7 +41,7 @@ int LuaItemStack::gc_object(lua_State *L)
int LuaItemStack::mt_tostring(lua_State *L)
{
LuaItemStack *o = checkobject(L, 1);
- std::string itemstring = o->m_stack.getItemString(false);
+ std::string itemstring = o->m_stack.getItemString(INV_OO_NO_META);
lua_pushfstring(L, "ItemStack(\"%s\")", itemstring.c_str());
return 1;
}
diff --git a/src/server.cpp b/src/server.cpp
index ac3802438..0c2510627 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1459,22 +1459,18 @@ void Server::SendInventory(PlayerSAO *sao, bool incremental)
{
RemotePlayer *player = sao->getPlayer();
- thread_local bool send_all = g_settings->getBool("send_all_item_metadata");
-
- // Do not send new format to old clients
- incremental &= player->protocol_version >= 38;
-
UpdateCrafting(player);
/*
Serialize it
*/
- NetworkPacket pkt(TOCLIENT_INVENTORY, 0, sao->getPeerID());
+ session_t peer_id = sao->getPeerID();
+
+ NetworkPacket pkt(TOCLIENT_INVENTORY, 0, peer_id);
std::ostringstream os(std::ios::binary);
- RemoteClient *client = getClientNoEx(sao->getPeerID(), CS_InitDone);
- sao->getInventory()->serialize(os, incremental, send_all || (client && client->mapsaving_enabled));
+ sao->getInventory()->serialize(os, getOptimisationOption(peer_id, incremental));
sao->getInventory()->setModified(false);
player->setModified(true);
@@ -2316,7 +2312,7 @@ void Server::sendMetadataChanged(const std::list<v3s16> &meta_updates, float far
// Send the meta changes
std::ostringstream os(std::ios::binary);
- meta_updates_list.serialize(os, client->net_proto_version, false, true, false);
+ meta_updates_list.serialize(os, client->net_proto_version, false, true, getOptimisationOption(i));
std::ostringstream oss(std::ios::binary);
compressZlib(os.str(), oss);
@@ -2337,9 +2333,8 @@ void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,
Create a packet with the block in the right format
*/
thread_local const int net_compression_level = rangelim(g_settings->getS16("map_compression_level_net"), -1, 9);
- thread_local bool send_all = g_settings->getBool("send_all_item_metadata");
std::ostringstream os(std::ios_base::binary);
- block->serialize(os, ver, false, net_compression_level, send_all || getClient(peer_id)->mapsaving_enabled);
+ block->serialize(os, ver, false, net_compression_level, getOptimisationOption(peer_id));
block->serializeNetworkSpecific(os);
std::string s = os.str();
@@ -2694,11 +2689,9 @@ void Server::sendDetachedInventory(Inventory *inventory, const std::string &name
} else {
pkt << true; // Update inventory
- thread_local bool send_all = g_settings->getBool("send_all_item_metadata");
-
// Serialization & NetworkPacket isn't a love story
std::ostringstream os(std::ios_base::binary);
- inventory->serialize(os, false, send_all);
+ inventory->serialize(os, getOptimisationOption(peer_id, false));
inventory->setModified(false);
const std::string &os_str = os.str();
@@ -3922,3 +3915,25 @@ Translations *Server::getTranslationLanguage(const std::string &lang_code)
return translations;
}
+
+InventoryOptimizationOption Server::getOptimisationOption(session_t peer_id, bool incremental)
+{
+ thread_local bool send_all = g_settings->getBool("send_all_item_metadata");
+ RemoteClient *client = nullptr;
+
+ if (peer_id != PEER_ID_INEXISTENT)
+ client = getClient(peer_id, CS_Created);
+
+ InventoryOptimizationOption opt = INV_OO_META_SPARSE;
+
+ if (send_all || (client && client->mapsaving_enabled))
+ opt = INV_OO_NONE;
+
+ // Do not send new format to old clients
+ incremental &= (client && client->net_proto_version >= 38);
+
+ if (incremental)
+ opt = (InventoryOptimizationOption) (opt | INV_OO_INCREMENTAL);
+
+ return opt;
+}
diff --git a/src/server.h b/src/server.h
index 9857215d0..d2435698f 100644
--- a/src/server.h
+++ b/src/server.h
@@ -491,6 +491,7 @@ private:
void DeleteClient(session_t peer_id, ClientDeletionReason reason);
void UpdateCrafting(RemotePlayer *player);
bool checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what);
+ InventoryOptimizationOption getOptimisationOption(session_t peer_id, bool incremental = false);
void handleChatInterfaceEvent(ChatEvent *evt);
diff --git a/src/unittest/test_inventory.cpp b/src/unittest/test_inventory.cpp
index 5f71636c4..72ae371c1 100644
--- a/src/unittest/test_inventory.cpp
+++ b/src/unittest/test_inventory.cpp
@@ -63,13 +63,13 @@ void TestInventory::testSerializeDeserialize(IItemDefManager *idef)
inv.getList("main")->setWidth(5);
std::ostringstream inv_os(std::ios::binary);
- inv.serialize(inv_os, false);
+ inv.serialize(inv_os, INV_OO_NONE);
UASSERTEQ(std::string, inv_os.str(), serialized_inventory_out);
inv.setModified(false);
inv_os.str("");
inv_os.clear();
- inv.serialize(inv_os, true);
+ inv.serialize(inv_os, INV_OO_INCREMENTAL);
UASSERTEQ(std::string, inv_os.str(), serialized_inventory_inc);
ItemStack leftover = inv.getList("main")->takeItem(7, 99 - 12);