]> git.lizzy.rs Git - minetest.git/commitdiff
Implement InventoryOptimisationOption as enum
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 9 Mar 2021 09:02:20 +0000 (10:02 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 9 Mar 2021 09:02:20 +0000 (10:02 +0100)
13 files changed:
src/inventory.cpp
src/inventory.h
src/inventoryoptimisation.h [new file with mode: 0644]
src/itemstackmetadata.cpp
src/itemstackmetadata.h
src/mapblock.cpp
src/mapblock.h
src/nodemetadata.cpp
src/nodemetadata.h
src/script/lua_api/l_item.cpp
src/server.cpp
src/server.h
src/unittest/test_inventory.cpp

index 147fbd30e9d7f9583bc1d7e50e502ae96d3cfcd9..28245f6ea2ed2c8267915f74036b49305348bbdf 100644 (file)
@@ -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);
                }
        }
 
index e6a7bf880fd92ae49e778abd448dfadc9ebcb0b1..2237b7a7cef1c19f06bc63310f907adcb6395694 100644 (file)
@@ -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 @@ class InventoryList
        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 @@ class Inventory
        }
 
        // 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 (file)
index 0000000..0ceb9c6
--- /dev/null
@@ -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,
+};
index b437a05f57ff41a25b9427341f8ca316f77a7cd4..97d639f6516b2583ec09d7652e5e3da614116cbf 100644 (file)
@@ -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"
index 7d81bf6ddfcebc92d3dc24e44fcd4b5434d2e6a8..80787284c8d687b7eeb4f2cce84bf830c2bb5d90 100644 (file)
@@ -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 @@ class ItemStackMetadata : public Metadata
        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(
index 03633cf8ef56418acbca8ee70aa36a5637c1bc14..eb878059e4640726ea43806eebbe003bf90b6bac 100644 (file)
@@ -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);
 
        /*
index 1548afc30cfe8d7b2a4979aee81f7b16841a37ba..3f5dd49f3dcdefce076db537a0f76131c29d8370 100644 (file)
@@ -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 @@ class MapBlock
        // 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);
index b4ece067f4509b198c88f3e1a44c988a54044f5e..8c6f1c4debc05b1891dbb542f87e8ca8b7dd7357 100644 (file)
@@ -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);
        }
 }
 
index 63b722c67031a0c844457b68d22de8a42c8740ca..a7bc6191a7c5a01116bafc30ed8bc01d2f90691a 100644 (file)
@@ -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 @@ class NodeMetadata : public Metadata
        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 @@ class NodeMetadataList
        ~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);
 
index 9e0da4034cb30322966f7febd77458152076cb32..7faf12340925616c1fd7247435fae95ae6131b84 100644 (file)
@@ -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;
 }
index ac38024387989128664a855948d6904c310f4998..0c2510627022cc2e4bee02568fd873b318c86571 100644 (file)
@@ -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;
+}
index 9857215d09e98664772058ecfd51596b42672f91..d2435698fb4ca2bdf0fe53f59869306bca55b314 100644 (file)
@@ -491,6 +491,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
        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);
 
index 5f71636c48abf548b659fb915fc3f4ad71de38a4..72ae371c1d14008cabeb2354f2638203ad9683ca 100644 (file)
@@ -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);