+#include "inspircd.h"
+#include "xline.h"
+#include "main.h"
+#include "modules/spanningtree.h"
+
+#include "utils.h"
+#include "treeserver.h"
+
+/** We use this constructor only to create the 'root' item, Utils->TreeRoot, which
+ * represents our own server. Therefore, it has no route, no parent, and
+ * no socket associated with it. Its version string is our own local version.
+ */
+TreeServer::TreeServer()
+ : Server(ServerInstance->Config->ServerName, ServerInstance->Config->ServerDesc)
+ , Parent(NULL), Route(NULL)
+ , VersionString(ServerInstance->GetVersionString())
+ , fullversion(ServerInstance->GetVersionString(true))
+ , Socket(NULL), sid(ServerInstance->Config->GetSID()), behind_bursting(0), isdead(false)
+ , pingtimer(this)
+ , ServerUser(ServerInstance->FakeClient)
+ , age(ServerInstance->Time()), UserCount(ServerInstance->Users.LocalUserCount())
+ , OperCount(0), rtt(0), StartBurst(0), Hidden(false)
+{
+ AddHashEntry();
+}
+
+/** When we create a new server, we call this constructor to initialize it.
+ * This constructor initializes the server's Route and Parent, and sets up
+ * the ping timer for the server.
+ */
+TreeServer::TreeServer(const std::string& Name, const std::string& Desc, const std::string& id, TreeServer* Above, TreeSocket* Sock, bool Hide)
+ : Server(Name, Desc)
+ , Parent(Above), Socket(Sock), sid(id), behind_bursting(Parent->behind_bursting), isdead(false)
+ , pingtimer(this)
+ , ServerUser(new FakeUser(id, this))
+ , age(ServerInstance->Time()), UserCount(0), OperCount(0), rtt(0), StartBurst(0), Hidden(Hide)
+{
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "New server %s behind_bursting %u", GetName().c_str(), behind_bursting);
+ CheckULine();
+
+ ServerInstance->Timers.AddTimer(&pingtimer);
+
+ /* find the 'route' for this server (e.g. the one directly connected
+ * to the local server, which we can use to reach it)
+ *
+ * In the following example, consider we have just added a TreeServer
+ * class for server G on our network, of which we are server A.
+ * To route traffic to G (marked with a *) we must send the data to
+ * B (marked with a +) so this algorithm initializes the 'Route'
+ * value to point at whichever server traffic must be routed through
+ * to get here. If we were to try this algorithm with server B,
+ * the Route pointer would point at its own object ('this').
+ *
+ * A
+ * / \
+ * + B C
+ * / \ \
+ * D E F
+ * / \
+ * * G H
+ *
+ * We only run this algorithm when a server is created, as
+ * the routes remain constant while ever the server exists, and
+ * do not need to be re-calculated.