public override OutgoingMessage CreateMessage()
 {
     OutgoingMessage outMessage = new OutgoingMessage();
     outMessage.Write(messageType);
     WriteMessage(outMessage);
     OutgoingMessage rv = new OutgoingMessage();
     rv.Write(outMessage.GetBytes());
     return rv;
 }
        public void ReadLoopbackWorldResponse(XmlNode node)
        {
            // WorldResponse response;
            string world_id = null;
            string update_url = null;
            string patcher_url = null;
            string hostname = null;
            int port = 0;
            List<string> world_repositories = new List<string>();
            bool standalone = false;
            string startup_script = null;
            if (node.Attributes["world_id"] == null)
                log.Warn("loopback_world_response element missing world_id attribute");
            else
                world_id = node.Attributes["world_id"].Value;
            LoopbackWorldResponse loopbackWorldResponse = new LoopbackWorldResponse();
            foreach (XmlNode child in node.ChildNodes) {
                switch (child.Name) {
                    case "account":
                        if (child.Attributes["id_token"] != null) {
                            string token = child.Attributes["id_token"].Value;
                            loopbackWorldResponse.idToken = Convert.FromBase64String(token);
                        } else if (child.Attributes["id_number"] != null) {
                            string number = child.Attributes["id_number"].Value;
                            int id = int.Parse(number);

                            // Make an old style token for older servers
                            loopbackWorldResponse.oldToken = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(id));

                            // Build a fake token to send to the login server
                            OutgoingMessage tokenBuilder = new OutgoingMessage();
                            tokenBuilder.Write((byte)1);      // version
                            tokenBuilder.Write((byte)1);      // type
                            tokenBuilder.Write("master");     // issuer
                            tokenBuilder.Write(1L);           // token id
                            tokenBuilder.Write(1L);           // key id
                            tokenBuilder.Write(0L);           // expiry
                            tokenBuilder.Write((byte)24);     // TreeMap type
                            tokenBuilder.Write(1);            // num entries
                            tokenBuilder.Write("account_id"); // entry key
                            tokenBuilder.Write((byte)3);      // int type
                            tokenBuilder.Write(id);           // account_id
                            tokenBuilder.Write((byte)0);      // authenticator
                            loopbackWorldResponse.idToken = tokenBuilder.GetBytes();
                        } else {
                            log.Warn("account element missing multiverse_id attribute");
                        }
                        break;
                    case "update_url":
                        if (child.Attributes["href"] != null)
                            update_url = child.Attributes["href"].Value;
                        else
                            log.Warn("update_url element missing href attribute");
                        break;
                    case "patcher_url":
                        if (child.Attributes["href"] != null)
                            patcher_url = child.Attributes["href"].Value;
                        else
                            log.Warn("patcher_url element missing href attribute");
                        break;
                    case "server":
                        if (child.Attributes["hostname"] != null)
                            hostname = child.Attributes["hostname"].Value;
                        else
                            log.Warn("server element missing hostname attribute");
                        if (child.Attributes["port"] != null) {
                            if (!int.TryParse(child.Attributes["port"].Value, out port))
                                log.Warn("server element has invalid port attribute");
                        } else
                            log.Warn("server element missing port attribute");
                        break;
                    case "world_repository":
                        if (child.Attributes["world_id"] != null)
                            world_repositories.Add(Path.Combine(WorldServerEntry.WorldsFolder, child.Attributes["world_id"].Value));
                        else if (child.Attributes["path"] != null)
                            world_repositories.Add(child.Attributes["path"].Value);
                        else
                            log.Warn("world_repository element missing world_id or path attribute");
                        break;
                    case "standalone":
                        if (child.Attributes["script"] != null) {
                            standalone = true;
                            startup_script = child.Attributes["script"].Value;
                        } else
                            log.Warn("standalone element missing script attribute");
                        break;
                }
            }
            loopbackWorldResponse.worldServerEntry = new WorldServerEntry(world_id, hostname, port, patcher_url, update_url);
            loopbackWorldResponse.worldServerEntry.WorldRepositoryDirectories = world_repositories;
            loopbackWorldResponse.worldServerEntry.Standalone = standalone;
            loopbackWorldResponse.worldServerEntry.StartupScript = startup_script;
            worldServerEntries.Add(loopbackWorldResponse);
        }