+#include "main.h"
+#include "utils.h"
+#include "treeserver.h"
+#include "commands.h"
+
+CommandMap::CommandMap(Module* Creator)
+ : Command(Creator, "MAP", 0, 1)
+{
+ allow_empty_last_param = false;
+ Penalty = 2;
+}
+
+static inline bool IsHidden(User* user, TreeServer* server)
+{
+ if (!user->IsOper())
+ {
+ if (server->Hidden)
+ return true;
+ if (Utils->HideULines && server->IsULine())
+ return true;
+ }
+
+ return false;
+}
+
+// Calculate the map depth the servers go, and the longest server name
+static void GetDepthAndLen(TreeServer* current, unsigned int depth, unsigned int& max_depth, unsigned int& max_len, unsigned int& max_version)
+{
+ if (depth > max_depth)
+ max_depth = depth;
+
+ if (current->GetName().length() > max_len)
+ max_len = current->GetName().length();
+
+ if (current->GetRawVersion().length() > max_version)
+ max_version = current->GetRawVersion().length();
+
+ const TreeServer::ChildServers& servers = current->GetChildren();
+ for (TreeServer::ChildServers::const_iterator i = servers.begin(); i != servers.end(); ++i)
+ {
+ TreeServer* child = *i;
+ GetDepthAndLen(child, depth + 1, max_depth, max_len, max_version);
+ }
+}
+
+static std::vector<std::string> GetMap(User* user, TreeServer* current, unsigned int max_len, unsigned int max_version_len, unsigned int depth)
+{
+ float percent = 0;
+
+ const user_hash& users = ServerInstance->Users->GetUsers();
+ if (!users.empty())
+ {
+ // If there are no users, WHO THE HELL DID THE /MAP?!?!?!
+ percent = current->UserCount * 100.0 / users.size();
+ }
+
+ std::string buffer = current->GetName();
+ if (user->IsOper())
+ {
+ buffer += " (" + current->GetId();
+
+ const std::string& cur_vers = current->GetRawVersion();
+ if (!cur_vers.empty())
+ buffer += " " + cur_vers;
+
+ buffer += ")";
+
+ buffer.append(max_version_len - current->GetRawVersion().length(), ' ');
+ }
+
+ // Pad with spaces until its at max len, max_len must always be >= my names length
+ buffer.append(max_len - current->GetName().length(), ' ');