diff options
author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2021-03-09 10:02:20 +0100 |
---|---|---|
committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2021-03-09 10:02:20 +0100 |
commit | f7ec8186ffad5e2fa4f2cacf456f08ee07bb1061 (patch) | |
tree | 86e63ba5bf47a6f1fb5be169450d8b9116b1c2ee /src | |
parent | cefacd63bf8598414b73f4de491de3e8d4976b93 (diff) | |
download | minetest-f7ec8186ffad5e2fa4f2cacf456f08ee07bb1061.tar.xz |
Implement InventoryOptimisationOption as enum
Diffstat (limited to 'src')
-rw-r--r-- | src/inventory.cpp | 28 | ||||
-rw-r--r-- | src/inventory.h | 9 | ||||
-rw-r--r-- | src/inventoryoptimisation.h | 28 | ||||
-rw-r--r-- | src/itemstackmetadata.cpp | 5 | ||||
-rw-r--r-- | src/itemstackmetadata.h | 3 | ||||
-rw-r--r-- | src/mapblock.cpp | 4 | ||||
-rw-r--r-- | src/mapblock.h | 3 | ||||
-rw-r--r-- | src/nodemetadata.cpp | 8 | ||||
-rw-r--r-- | src/nodemetadata.h | 5 | ||||
-rw-r--r-- | src/script/lua_api/l_item.cpp | 2 | ||||
-rw-r--r-- | src/server.cpp | 43 | ||||
-rw-r--r-- | src/server.h | 1 | ||||
-rw-r--r-- | src/unittest/test_inventory.cpp | 4 |
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); |