2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2019 Peter Powell <petpow@saberuk.com>
6 * This file is part of InspIRCd. InspIRCd is free software: you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 Serializable::Data& Serializable::Data::Load(const std::string& key, std::string& out)
24 EntryMap::iterator iter = this->entries.find(key);
25 if (iter == this->entries.end())
27 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Unable to load missing kv %s!", key.c_str());
32 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Loaded kv %s: %s", key.c_str(), out.c_str());
37 Serializable::Data& Serializable::Data::Load(const std::string& key, Serializable::Data& out)
39 ChildMap::iterator iter = this->children.find(key);
40 if (iter == this->children.end())
42 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Unable to load missing data %s!", key.c_str());
47 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Loaded data: %s", key.c_str());
52 Serializable::Data& Serializable::Data::Store(const std::string& key, const std::string& value)
54 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Stored kv %s: %s", key.c_str(), value.c_str());
55 this->entries[key] = value;
59 Serializable::Data& Serializable::Data::Store(const std::string& key, const Serializable::Data& value)
61 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Stored data: %s", key.c_str());
62 this->children[key] = value;
66 bool Extensible::Deserialize(Serializable::Data& data)
68 // If the extensible has been culled then it shouldn't be deserialized.
72 const Serializable::Data::EntryMap& entries = data.GetEntries();
73 for (Serializable::Data::EntryMap::const_iterator iter = entries.begin(); iter != entries.end(); ++iter)
75 const std::string& name = iter->first;
76 ExtensionItem* item = ServerInstance->Extensions.GetItem(name);
79 item->FromInternal(this, iter->second);
83 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to deserialize the %s extension item but it doesn't exist",
89 bool Extensible::Serialize(Serializable::Data& data)
91 // If the extensible has been culled then it shouldn't be serialized.
94 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to serialize an extensible which has been culled");
98 for (Extensible::ExtensibleStore::const_iterator iter = extensions.begin(); iter != extensions.end(); ++iter)
100 ExtensionItem* item = iter->first;
101 const std::string value = item->ToInternal(this, iter->second);
103 data.Store(item->name, value);
108 bool User::Deserialize(Serializable::Data& data)
110 // If the user is quitting they shouldn't be deserialized.
113 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to deserialize %s who is in the process of quitting",
118 // Check we're actually deserialising data for this user.
119 std::string client_uuid;
120 data.Load("uuid", client_uuid);
121 if (!client_uuid.empty() && client_uuid != uuid)
123 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to deserialize %s into %s",
124 client_uuid.c_str(), uuid.c_str());
128 // Deserialize the extensions first.
129 Serializable::Data exts;
130 data.Load("extensions", exts);
131 if (!Extensible::Deserialize(exts))
135 std::string client_addr;
136 std::string user_modes;
137 std::string user_oper;
138 std::string user_snomasks;
140 // Apply the members which can be applied directly.
141 data.Load("age", age)
142 .Load("awaymsg", awaymsg)
143 .Load("awaytime", awaytime)
144 .Load("client_sa.addr", client_addr)
145 .Load("client_sa.port", client_port)
146 .Load("displayhost", displayhost)
147 .Load("ident", ident)
148 .Load("modes", user_modes)
150 .Load("oper", user_oper)
151 .Load("realhost", realhost)
152 .Load("realname", realname)
153 .Load("signon", signon)
154 .Load("snomasks", user_snomasks);
156 // Apply the rest of the members.
157 modes = std::bitset<ModeParser::MODEID_MAX>(user_modes);
158 snomasks = std::bitset<64>(user_snomasks);
160 ServerConfig::OperIndex::const_iterator iter = ServerInstance->Config->OperTypes.find(user_oper);
161 if (iter != ServerInstance->Config->OperTypes.end())
164 oper = new OperInfo(user_oper);
166 irc::sockets::sockaddrs sa;
167 if (irc::sockets::aptosa(client_addr, client_port, sa) || irc::sockets::untosa(client_addr, sa))
174 bool User::Serialize(Serializable::Data& data)
176 // If the user is quitting they shouldn't be serialized.
179 ServerInstance->Logs->Log("SERIALIZE", LOG_DEBUG, "Tried to serialize %s who is in the process of quitting",
184 // If the user is unregistered they shouldn't be serialised.
185 if (registered != REG_ALL)
188 // Serialize the extensions first.
189 Serializable::Data exts;
190 if (!Extensible::Serialize(exts))
192 data.Store("extensions", exts);
194 // The following member variables not checked above are not serialised:
195 // * cached_fullhost (serialising cache variables is unnecessary)
196 // * cached_fullrealhost (serialising cache variables is unnecessary)
197 // * cached_hostip (serialising cache variables is unnecessary)
198 // * cached_makehost (serialising cache variables is unnecessary)
199 // * cachedip (serialising cache variables is unnecessary)
200 // * server (specific to the origin server)
201 // * usertype (can't be networked reliably)
202 data.Store("age", age)
203 .Store("awaymsg", awaymsg)
204 .Store("awaytime", awaytime)
205 .Store("client_sa.addr", client_sa.addr())
206 .Store("client_sa.port", client_sa.port())
207 .Store("displayhost", displayhost)
208 .Store("ident", ident)
209 .Store("modes", modes.to_string())
211 .Store("oper", oper ? oper->name : "")
212 .Store("realhost", realhost)
213 .Store("realname", realname)
214 .Store("signon", signon)
215 .Store("snomasks", snomasks.to_string())
216 .Store("uuid", uuid);
221 bool LocalUser::Deserialize(Serializable::Data& data)
224 // Deserialize the base class first.
225 if (!User::Deserialize(data))
231 std::string server_addr;
233 // Apply the members which can be applied directly.
234 data.Load("bytes_in", bytes_in)
235 .Load("bytes_out", bytes_out)
236 .Load("cmds_in", cmds_in)
237 .Load("cmds_out", cmds_out)
238 .Load("CommandFloodPenalty", CommandFloodPenalty)
239 .Load("exempt", user_exempt)
240 .Load("idle_lastmsg", idle_lastmsg)
241 .Load("lastping", user_lastping)
242 .Load("nextping", nextping)
243 .Load("password", password)
244 .Load("server_sa.addr", server_addr)
245 .Load("server_sa.port", server_port);
247 // Apply the rest of the members.
248 irc::sockets::sockaddrs sa;
249 if (irc::sockets::aptosa(server_addr, server_port, sa) || irc::sockets::untosa(server_addr, sa))
252 // These are bitfields so we need to ensure they only get the appropriate bits.
253 exempt = user_exempt ? 1 : 0;
254 lastping = user_lastping ? 1 : 0;
258 bool LocalUser::Serialize(Serializable::Data& data)
260 // Serialize the base class first.
261 if (!User::Serialize(data))
264 // The following member variables not checked above are not serialised:
265 // * already_sent (can't be networked reliably)
266 // * eh (shouldn't be networked)
267 // * MyClass (might not be the same on a different server)
268 // * serializer (might not be the same on a different connection)
269 data.Store("bytes_in", bytes_in)
270 .Store("bytes_out", bytes_out)
271 .Store("cmds_in", cmds_in)
272 .Store("cmds_out", cmds_out)
273 .Store("CommandFloodPenalty", CommandFloodPenalty)
274 .Store("exempt", exempt)
275 .Store("idle_lastmsg", idle_lastmsg)
276 .Store("lastping", lastping)
277 .Store("nextping", nextping)
278 .Store("password", password)
279 .Store("server_sa.addr", server_sa.addr())
280 .Store("server_sa.port", server_sa.port());