summaryrefslogtreecommitdiff
path: root/src/staticobject.cpp
blob: 1160ec68f1c01dee8aa3c6791eec6ecf65ae09fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>

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.
*/

#include "staticobject.h"
#include "util/serialize.h"
#include "server/serveractiveobject.h"

StaticObject::StaticObject(const ServerActiveObject *s_obj, const v3f &pos_):
	type(s_obj->getType()),
	pos(pos_)
{
	s_obj->getStaticData(&data);
}

void StaticObject::serialize(std::ostream &os)
{
	// type
	writeU8(os, type);
	// pos
	writeV3F1000(os, pos);
	// data
	os<<serializeString16(data);
}

void StaticObject::deSerialize(std::istream &is, u8 version)
{
	// type
	type = readU8(is);
	// pos
	pos = readV3F1000(is);
	// data
	data = deSerializeString16(is);
}

void StaticObjectList::serialize(std::ostream &os)
{
	// Check for problems first
	auto problematic = [] (StaticObject &obj) -> bool {
		if (obj.data.size() > U16_MAX) {
			errorstream << "StaticObjectList::serialize(): "
				"object has excessive static data (" << obj.data.size() <<
				"), deleting it." << std::endl;
			return true;
		}
		return false;
	};
	for (auto it = m_stored.begin(); it != m_stored.end(); ) {
		if (problematic(*it))
			it = m_stored.erase(it);
		else
			it++;
	}
	for (auto it = m_active.begin(); it != m_active.end(); ) {
		if (problematic(it->second))
			it = m_active.erase(it);
		else
			it++;
	}

	// version
	u8 version = 0;
	writeU8(os, version);

	// count
	size_t count = m_stored.size() + m_active.size();
	// Make sure it fits into u16, else it would get truncated and cause e.g.
	// issue #2610 (Invalid block data in database: unsupported NameIdMapping version).
	if (count > U16_MAX) {
		errorstream << "StaticObjectList::serialize(): "
			<< "too many objects (" << count << ") in list, "
			<< "not writing them to disk." << std::endl;
		writeU16(os, 0);  // count = 0
		return;
	}
	writeU16(os, count);

	for (StaticObject &s_obj : m_stored) {
		s_obj.serialize(os);
	}

	for (auto &i : m_active) {
		StaticObject s_obj = i.second;
		s_obj.serialize(os);
	}
}
void StaticObjectList::deSerialize(std::istream &is)
{
	if (m_active.size()) {
		errorstream << "StaticObjectList::deSerialize(): "
			<< "deserializing objects while " << m_active.size()
			<< " active objects already exist (not cleared). "
			<< m_stored.size() << " stored objects _were_ cleared"
			<< std::endl;
	}
	m_stored.clear();

	// version
	u8 version = readU8(is);
	// count
	u16 count = readU16(is);
	for(u16 i = 0; i < count; i++) {
		StaticObject s_obj;
		s_obj.deSerialize(is, version);
		m_stored.push_back(s_obj);
	}
}