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;
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);
}
}
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();
}
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"));
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";
}
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);
}
}
#pragma once
+#include "inventoryoptimisation.h"
#include "itemdef.h"
#include "irrlichttypes.h"
#include "itemstackmetadata.h"
~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;
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);
}
// 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);
--- /dev/null
+/*
+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,
+};
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"
#pragma once
+#include "inventoryoptimisation.h"
#include "metadata.h"
#include "tool.h"
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(
}
}
-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");
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);
/*
#include <set>
#include "irr_v3d.h"
+#include "inventoryoptimisation.h"
#include "mapnode.h"
#include "exceptions.h"
#include "constants.h"
// 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);
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);
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)
*/
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."
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);
}
}
#pragma once
#include <unordered_set>
+#include "inventoryoptimisation.h"
#include "metadata.h"
/*
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();
~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);
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;
}
{
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);
// 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);
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();
} 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();
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;
+}
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);
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);