Esempio n. 1
0
        private static void HandleMessage(IMasterServerMessageBase message, NetIncomingMessage netMsg, NetPeer peer)
        {
            switch ((message?.Data as MsBaseMsgData)?.MasterServerMessageSubType)
            {
            case MasterServerMessageSubType.REGISTER_SERVER:
                RegisterServer(message, netMsg);
                break;

            case MasterServerMessageSubType.REQUEST_SERVERS:
                var version = ((MsRequestServersMsgData)message.Data).CurrentVersion;
                Form.WriteLine($"Received LIST REQUEST from: {netMsg.SenderEndPoint} version: {version}");
                SendServerLists(netMsg, peer, version);
                break;

            case MasterServerMessageSubType.INTRODUCTION:
                Form.WriteLine("Received INTRODUCTION request from:" + netMsg.SenderEndPoint);
                var    msgData = (MsIntroductionMsgData)message.Data;
                Server server;
                if (ServerDictionary.TryGetValue(msgData.Id, out server))
                {
                    peer.Introduce(
                        server.InternalEndpoint,
                        server.ExternalEndpoint,
                        Common.CreateEndpointFromString(msgData.InternalEndpoint), // client internal
                        netMsg.SenderEndPoint,                                     // client external
                        msgData.Token);                                            // request token
                }
                else
                {
                    Form.WriteLine("Client requested introduction to nonlisted host!");
                }
                break;
            }
        }
Esempio n. 2
0
        public void Introduce(Machine clientMachine, Machine serverMachine)
        {
            if (clientMachine == null)
            {
                throw new ArgumentNullException("clientMachine");
            }
            if (serverMachine == null)
            {
                throw new ArgumentNullException("serverMachine");
            }

            Trace.WriteLine("Introduced " + clientMachine.ToString() + " to " + serverMachine.ToString());

            netPeer.Introduce(clientMachine.PrivateEndPoint, clientMachine.PublicEndPoint, serverMachine.PrivateEndPoint,
                              serverMachine.PublicEndPoint, String.Empty);
        }
Esempio n. 3
0
        private static void HandleMessage(IMasterServerMessageBase message, NetIncomingMessage netMsg, NetPeer peer)
        {
            if (BannedIpsRetriever.IsBanned(netMsg.SenderEndPoint))
            {
                LunaLog.Debug($"Ignoring BANNED ip: {netMsg.SenderEndPoint}");
                return;
            }

            try
            {
                switch ((message?.Data as MsBaseMsgData)?.MasterServerMessageSubType)
                {
                case MasterServerMessageSubType.RegisterServer:
                    RegisterServer(message, netMsg);
                    break;

                case MasterServerMessageSubType.RequestServers:
                    LunaLog.Normal($"LIST REQUEST from: {netMsg.SenderEndPoint}");
                    SendServerLists(netMsg, peer);
                    break;

                case MasterServerMessageSubType.Introduction:
                    var msgData = (MsIntroductionMsgData)message.Data;
                    if (ServerDictionary.TryGetValue(msgData.Id, out var server))
                    {
                        LunaLog.Normal($"INTRODUCTION request from: {netMsg.SenderEndPoint} to server: {server.ExternalEndpoint}");
                        peer.Introduce(server.InternalEndpoint, server.ExternalEndpoint,
                                       msgData.InternalEndpoint, // client internal
                                       netMsg.SenderEndPoint,    // client external
                                       msgData.Token);           // request token
                    }
                    else
                    {
                        LunaLog.Warning($"Client {netMsg.SenderEndPoint} requested introduction to non listed host!");
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                LunaLog.Error($"Error handling message. Details: {e}");
            }
        }
Esempio n. 4
0
        private void HandleRequestIntroduction(NetIncomingMessage msg)
        {
            IPEndPoint clientInternal = msg.ReadIPEndpoint();
            long       hostId         = msg.ReadInt64();
            string     token          = msg.ReadString();

            Object[] elist;
            if (registeredHosts.TryGetValue(hostId, out elist))
            {
                peer.Introduce(
                    (IPEndPoint)elist[0],
                    (IPEndPoint)elist[1],
                    clientInternal,
                    msg.SenderEndpoint,
                    token
                    );
            }
            else
            {
                Console.WriteLine("Client requested introduction to nonlisted host!");
            }
        }
Esempio n. 5
0
        private static void HandleMessage(IMasterServerMessageBase message, NetIncomingMessage netMsg, NetPeer peer)
        {
            try
            {
                switch ((message?.Data as MsBaseMsgData)?.MasterServerMessageSubType)
                {
                case MasterServerMessageSubType.RegisterServer:
                    RegisterServer(message, netMsg);
                    break;

                case MasterServerMessageSubType.RequestServers:
                    ConsoleLogger.Log(LogLevels.Normal, $"LIST REQUEST from: {netMsg.SenderEndPoint}");
                    SendServerLists(netMsg, peer);
                    break;

                case MasterServerMessageSubType.Introduction:
                    var msgData = (MsIntroductionMsgData)message.Data;
                    if (ServerDictionary.TryGetValue(msgData.Id, out var server))
                    {
                        ConsoleLogger.Log(LogLevels.Normal, $"INTRODUCTION request from: {netMsg.SenderEndPoint} to server: {server.ExternalEndpoint}");
                        peer.Introduce(server.InternalEndpoint, server.ExternalEndpoint,
                                       Common.CreateEndpointFromString(msgData.InternalEndpoint), // client internal
                                       netMsg.SenderEndPoint,                                     // client external
                                       msgData.Token);                                            // request token
                    }
                    else
                    {
                        ConsoleLogger.Log(LogLevels.Warning, $"Client {netMsg.SenderEndPoint} requested introduction to nonlisted host!");
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                ConsoleLogger.Log(LogLevels.Error, $"Error handling message. Details: {e}");
            }
        }
Esempio n. 6
0
        static void Main(string[] args)
        {
            Dictionary <long, IPEndPoint[]> registeredHosts = new Dictionary <long, IPEndPoint[]>();

            NetPeerConfiguration config = new NetPeerConfiguration("masterserver");

            config.SetMessageTypeEnabled(NetIncomingMessageType.UnconnectedData, true);
            config.Port = CommonConstants.MasterServerPort;

            NetPeer peer = new NetPeer(config);

            peer.Start();

            // keep going until ESCAPE is pressed
            Console.WriteLine("Press ESC to quit");
            while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape)
            {
                NetIncomingMessage msg;
                while ((msg = peer.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.UnconnectedData:
                        //
                        // We've received a message from a client or a host
                        //

                        // by design, the first byte always indicates action
                        switch ((MasterServerMessageType)msg.ReadByte())
                        {
                        case MasterServerMessageType.RegisterHost:

                            // It's a host wanting to register its presence
                            var id = msg.ReadInt64();                                             // server unique identifier

                            Console.WriteLine("Got registration for host " + id);
                            registeredHosts[id] = new IPEndPoint[]
                            {
                                msg.ReadIPEndPoint(),                                              // internal
                                    msg.SenderEndPoint                                             // external
                            };
                            break;

                        case MasterServerMessageType.RequestHostList:
                            // It's a client wanting a list of registered hosts
                            Console.WriteLine("Sending list of " + registeredHosts.Count + " hosts to client " + msg.SenderEndPoint);
                            foreach (var kvp in registeredHosts)
                            {
                                // send registered host to client
                                NetOutgoingMessage om = peer.CreateMessage();
                                om.Write(kvp.Key);
                                om.Write(kvp.Value[0]);
                                om.Write(kvp.Value[1]);
                                peer.SendUnconnectedMessage(om, msg.SenderEndPoint);
                            }

                            break;

                        case MasterServerMessageType.RequestIntroduction:
                            // It's a client wanting to connect to a specific (external) host
                            IPEndPoint clientInternal = msg.ReadIPEndPoint();
                            long       hostId         = msg.ReadInt64();
                            string     token          = msg.ReadString();

                            Console.WriteLine(msg.SenderEndPoint + " requesting introduction to " + hostId + " (token " + token + ")");

                            // find in list
                            IPEndPoint[] elist;
                            if (registeredHosts.TryGetValue(hostId, out elist))
                            {
                                // found in list - introduce client and host to eachother
                                Console.WriteLine("Sending introduction...");
                                peer.Introduce(
                                    elist[0],                                                 // host internal
                                    elist[1],                                                 // host external
                                    clientInternal,                                           // client internal
                                    msg.SenderEndPoint,                                       // client external
                                    token                                                     // request token
                                    );
                            }
                            else
                            {
                                Console.WriteLine("Client requested introduction to nonlisted host!");
                            }
                            break;
                        }
                        break;

                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.ErrorMessage:
                        // print diagnostics message
                        Console.WriteLine(msg.ReadString());
                        break;
                    }
                }
            }

            peer.Shutdown("shutting down");
        }
Esempio n. 7
0
        protected bool HandleMessage(NetIncomingMessage msg)
        {
            string senderGameAppId;
            string senderPayload;

            try
            {
                senderGameAppId = msg.ReadString();
                senderPayload   = msg.ReadString();
            }
            catch
            {
                return(false);
            }
            if (!senderGameAppId.Equals(GameAppId, StringComparison.InvariantCulture))
            {
                Console.WriteLine("Received message with incorrect game app id from " + msg.SenderEndPoint + ".");
                return(true);
            }
            var payloadValid = ValidatePayload(senderPayload);
            var messageType  = (MasterServerMessageType)msg.ReadByte();

            if (messageType == MasterServerMessageType.RequestGeneralInfo)
            {
                // Note: Payload does not need to be valid to request general info (useful to handle new version alerts)
                SendRequestGeneralInfoResponse(serverPeer, msg.SenderEndPoint, GeneralInfo);

                Console.WriteLine("Sent general info to " + msg.SenderEndPoint + ".");
                return(true);
            }

            if (!payloadValid)
            {
                SendErrorResponse(serverPeer, msg.SenderEndPoint, messageType, MasterServerMessageResult.InvalidPayload);

                Console.WriteLine("Received message that failed payload validation from " + msg.SenderEndPoint + ", error response sent.");
                return(true);
            }

            if (messageType == MasterServerMessageType.RegisterHost)
            {
                Guid       guid;
                IPEndPoint internalIp, externalIp;
                NetworkSessionPublicInfo publicInfo;
                if (!ParseRegisterHost(msg, out guid, out internalIp, out externalIp, out publicInfo))
                {
                    return(false);
                }

                hosts[guid] = new HostData(guid, internalIp, externalIp, publicInfo);

                Console.WriteLine("Host registered/updated. " + hosts[guid]);
            }
            else if (messageType == MasterServerMessageType.UnregisterHost)
            {
                Guid guid;
                if (!ParseUnregisterHost(msg, out guid))
                {
                    return(false);
                }

                if (hosts.ContainsKey(guid))
                {
                    var host = hosts[guid];
                    if (msg.SenderEndPoint.Equals(host.ExternalIp))
                    {
                        hosts.Remove(guid);

                        Console.WriteLine("Host unregistered. " + host);
                    }
                    else
                    {
                        Console.WriteLine("Unregister requested for host not registered by " + msg.SenderEndPoint + ".");
                    }
                }
                else
                {
                    Console.WriteLine("Unregister requested for unknown host from " + msg.SenderEndPoint + ".");
                }
            }
            else if (messageType == MasterServerMessageType.RequestHosts)
            {
                foreach (var host in hosts.Values)
                {
                    SendRequestHostsResponse(serverPeer, msg.SenderEndPoint, false, host.Guid, host.PublicInfo);
                }

                Console.WriteLine("List of " + hosts.Count + " hosts sent to " + msg.SenderEndPoint + ".");
            }
            else if (messageType == MasterServerMessageType.RequestIntroduction)
            {
                Guid       guid;
                IPEndPoint clientInternalIp, clientExternalIp;
                if (!ParseRequestIntroduction(msg, out guid, out clientInternalIp, out clientExternalIp))
                {
                    return(false);
                }

                if (hosts.ContainsKey(guid))
                {
                    var host = hosts[guid];
                    serverPeer.Introduce(host.InternalIp, host.ExternalIp, clientInternalIp, clientExternalIp, string.Empty);
                    Console.WriteLine("Introduced host " + host + " and client [InternalIp: " + clientInternalIp + ", ExternalIp: " + clientExternalIp + "].");
                }
                else
                {
                    Console.WriteLine("Introduction requested for unknwon host from " + msg.SenderEndPoint + ".");
                }
            }

            return(true);
        }
Esempio n. 8
0
        static void Main(string[] args)
        {
            Dictionary <long, CarGoServer.ServerData> registeredHosts = new Dictionary <long, CarGoServer.ServerData>();

            NetPeerConfiguration config = new NetPeerConfiguration("masterserver");

            config.SetMessageTypeEnabled(NetIncomingMessageType.UnconnectedData, true);
            config.Port = CommonConstants.MasterServerPort;

            NetPeer peer = new NetPeer(config);

            peer.Start();

            // keep going until ESCAPE is pressed
            Console.WriteLine("Press ESC to quit");
            while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape)
            {
                NetIncomingMessage msg;
                while ((msg = peer.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.UnconnectedData:
                        //
                        // We've received a message from a client or a host
                        //

                        // by design, the first byte always indicates action
                        switch ((MasterServerMessageType)msg.ReadByte())
                        {
                        case MasterServerMessageType.RegisterHost:

                            // It's a host wanting to register its presence
                            var id = msg.ReadInt64();         // server unique identifier
                                                              //var name = msg.ReadString();
                            CarGoServer.ServerData serverData = new CarGoServer.ServerData();
                            msg.ReadAllFields(serverData);
                            IPAddress address;
                            IPAddress.TryParse(serverData.localAddress, out address);
                            IPEndPoint hostEndPoint = new IPEndPoint(address, serverData.serverPort);
                            Console.WriteLine("Got registration for host " + id);
                            registeredHosts[id] = serverData;
                            break;

                        case MasterServerMessageType.RequestHostList:
                            // It's a client wanting a list of registered hosts
                            //Console.WriteLine("Sending list of " + registeredHosts.Count + " hosts to client " + msg.SenderEndPoint);
                            foreach (var hostData in registeredHosts)
                            {
                                if (hostData.Value.showInServerList)
                                {
                                    // send registered host to client
                                    //Console.WriteLine("sending " + hostData.Value.serverName);
                                    NetOutgoingMessage om = peer.CreateMessage();
                                    om.Write((byte)CarGo.Network.MessageType.ServerInList);
                                    om.Write(hostData.Key);
                                    om.WriteAllFields(hostData.Value);
                                    peer.SendUnconnectedMessage(om, msg.SenderEndPoint);
                                }
                            }

                            break;

                        case MasterServerMessageType.RequestIntroduction:
                            // It's a client wanting to connect to a specific (external) host
                            IPEndPoint clientInternal = msg.ReadIPEndPoint();
                            long       hostId         = msg.ReadInt64();
                            string     token          = msg.ReadString();

                            Console.WriteLine(msg.SenderEndPoint + " requesting introduction to " + hostId + " (token " + token + ")");

                            // find in list
                            IPEndPoint[]           elist;
                            CarGoServer.ServerData data;
                            long      publicAddress;
                            IPAddress localAddress;

                            if (registeredHosts.TryGetValue(hostId, out data))
                            {
                                IPAddress.TryParse(data.localAddress, out localAddress);
                                if (long.TryParse(data.publicAddress, out publicAddress))
                                {
                                    // found in list - introduce client and host to eachother
                                    Console.WriteLine("Sending introduction...");
                                    peer.Introduce(
                                        new IPEndPoint(localAddress, data.serverPort),  // host internal
                                        new IPEndPoint(publicAddress, data.serverPort), // host external
                                        clientInternal,                                 // client internal
                                        msg.SenderEndPoint,                             // client external
                                        token                                           // request token
                                        );
                                }
                            }
                            else
                            {
                                Console.WriteLine("Client requested introduction to nonlisted host!");
                            }
                            break;

                        case MasterServerMessageType.GetHostByCode:
                            CarGoServer.ServerData serverData1;
                            if (registeredHosts.TryGetValue(msg.ReadInt64(), out serverData1))
                            {
                                NetOutgoingMessage om = peer.CreateMessage();
                                om.Write((byte)CarGo.Network.MessageType.ReceiveServerAddress);
                                om.WriteAllFields(serverData1);
                                peer.SendUnconnectedMessage(om, msg.SenderEndPoint);
                            }
                            else
                            {
                                Console.WriteLine("Code not correct");
                            }
                            break;
                        }
                        break;

                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.ErrorMessage:
                        // print diagnostics message
                        Console.WriteLine(msg.ReadString());
                        break;
                    }
                }
            }

            peer.Shutdown("shutting down");
        }
Esempio n. 9
0
        /// <summary>
        /// Handle messages from server or client and choose what to do with them.
        /// </summary>
        private void HandleMessage()
        {
            NetIncomingMessage netIncomingMessage;

            while ((netIncomingMessage = m_netPeer.ReadMessage()) != null)
            {
                switch (netIncomingMessage.MessageType)
                {
                case NetIncomingMessageType.UnconnectedData:
                {
                    switch ((ServerMessageTypes)netIncomingMessage.ReadByte())
                    {
                    case ServerMessageTypes.RegisterHost:
                    {
                        ServerMessage serverMessage = new ServerMessage(netIncomingMessage);                 // Decode server message.

                        serverMessage.IPendPoint = new IPEndPoint[]
                        {
                            netIncomingMessage.ReadIPEndPoint(),
                                netIncomingMessage.SenderEndPoint
                        };

                        if (m_registredServers.ContainsKey(serverMessage.ID) == false)
                        {
                            m_registredServers.Add(serverMessage.ID, serverMessage);
                        }
                        else
                        {
                            m_registredServers[serverMessage.ID] = serverMessage;
                        }

                        Log.HandleLog(LOGMessageTypes.Info, "Got registration for host", String.Format("{0}.", serverMessage.ID));
                        break;
                    }

                    case ServerMessageTypes.RequestHostList:
                    {
                        Log.HandleLog(LOGMessageTypes.Info, "Sending list of", m_registredServers.Count, "hosts to client", String.Format("{0}.", netIncomingMessage.SenderEndPoint));

                        foreach (KeyValuePair <long, ServerMessage> RegistredServer in this.m_registredServers)
                        {
                            NetOutgoingMessage netOutgoingMessage = m_netPeer.CreateMessage();

                            IServerMessage IserverMessage = new ServerMessage
                            {
                                ID             = RegistredServer.Value.ID,
                                IPAddress      = RegistredServer.Value.IPAddress,
                                Port           = RegistredServer.Value.Port,
                                Hostname       = RegistredServer.Value.Hostname,
                                Players        = RegistredServer.Value.Players,
                                MaximumPlayers = RegistredServer.Value.MaximumPlayers,

                                Ping        = 0,
                                IPendPoint  = null,
                                MessageType = ServerMessageTypes.RequestHostList
                            };

                            IserverMessage.EncodeMessage(netOutgoingMessage);                                        // Encode message.

                            m_netPeer.SendUnconnectedMessage(netOutgoingMessage, netIncomingMessage.SenderEndPoint); // Send encoded message to client.
                        }
                        break;
                    }

                    case ServerMessageTypes.RequestIntroduction:
                    {
                        IPEndPoint clientInternal = netIncomingMessage.ReadIPEndPoint();
                        long       ServerID       = netIncomingMessage.ReadInt64();
                        string     Token          = netIncomingMessage.ReadString();

                        Log.HandleLog(LOGMessageTypes.Info, netIncomingMessage.SenderEndPoint, "requesting introduction to", ServerID, String.Format("(token{0}).", Token));

                        if (this.m_registredServers.ContainsKey(ServerID))
                        {
                            Log.HandleLog(LOGMessageTypes.Info, "Sending introduction...");

                            m_netPeer.Introduce(this.m_registredServers[ServerID].IPendPoint[0], this.m_registredServers[ServerID].IPendPoint[1], clientInternal,
                                                netIncomingMessage.SenderEndPoint, Token);
                        }
                        else
                        {
                            Console.WriteLine("Client requested introduction to nonlisted host!");
                        }
                        break;
                    }
                    }

                    break;
                }

                case NetIncomingMessageType.DebugMessage:
                case NetIncomingMessageType.VerboseDebugMessage:
                {
                    Log.HandleLog(LOGMessageTypes.Debug, netIncomingMessage.ReadString());
                    break;
                }

                case NetIncomingMessageType.WarningMessage:
                {
                    Log.HandleLog(LOGMessageTypes.Warning, netIncomingMessage.ReadString());
                    break;
                }

                case NetIncomingMessageType.ErrorMessage:
                {
                    Log.HandleLog(LOGMessageTypes.Error, netIncomingMessage.ReadString());
                    break;
                }
                }
            }
        }
Esempio n. 10
0
        private static void HandleMessage(IMasterServerMessageBase message, NetIncomingMessage netMsg, NetPeer peer)
        {
            if (BannedIpsRetriever.IsBanned(netMsg.SenderEndPoint))
            {
                LunaLog.Debug($"Ignoring BANNED ip: {netMsg.SenderEndPoint}");
                return;
            }

            try
            {
                switch ((message?.Data as MsBaseMsgData)?.MasterServerMessageSubType)
                {
                case MasterServerMessageSubType.RegisterServer:
                    RegisterServer(message, netMsg);
                    break;

                case MasterServerMessageSubType.RequestServers:
                    LunaLog.Normal($"LIST REQUEST from: {netMsg.SenderEndPoint}");
                    SendServerLists(netMsg, peer);
                    break;

                case MasterServerMessageSubType.Introduction:
                    var msgData = (MsIntroductionMsgData)message.Data;
                    if (ServerDictionary.TryGetValue(msgData.Id, out var server))
                    {
                        _ = Task.Run(() =>
                        {
                            if (!server.InternalEndpoint6.Address.Equals(IPAddress.IPv6Loopback) &&
                                !server.InternalEndpoint6.Address.Equals(IPAddress.IPv6Loopback))
                            {
                                // Both client and server are listening on IPv6, try an IPv6 firewall punchthrough
                                // This also triggers a first punchthrough on IPv4 with the public addresses
                                LunaLog.Normal(
                                    $"INTRODUCTION request from: {msgData.InternalEndpoint6} to server: {server.InternalEndpoint6}");
                                peer.Introduce(server.InternalEndpoint6, server.ExternalEndpoint,
                                               msgData.InternalEndpoint6, // client internal
                                               netMsg.SenderEndPoint,     // client external
                                               msgData.Token);            // request token

                                // Give the first introduction attempt some time
                                Thread.Sleep(50);
                            }

                            LunaLog.Normal(
                                $"INTRODUCTION request from: {netMsg.SenderEndPoint} to server: {server.ExternalEndpoint}");
                            peer.Introduce(server.InternalEndpoint, server.ExternalEndpoint,
                                           msgData.InternalEndpoint, // client internal
                                           netMsg.SenderEndPoint,    // client external
                                           msgData.Token);           // request token
                        });
                    }
                    else
                    {
                        LunaLog.Warning($"Client {netMsg.SenderEndPoint} requested introduction to non listed host!");
                    }
                    break;
                }
            }
            catch (Exception e)
            {
                LunaLog.Error($"Error handling message. Details: {e}");
            }
        }
Esempio n. 11
0
        static void Main(string[] args)
        {
            Console.WriteLine("Server Started");

            Dictionary <IPEndPoint, AvailableGame> registeredHosts = new Dictionary <IPEndPoint, AvailableGame>();

            NetPeerConfiguration config = new NetPeerConfiguration("masterserver");

            config.SetMessageTypeEnabled(NetIncomingMessageType.UnconnectedData, true);
            config.Port = 6000;

            NetPeer peer = new NetPeer(config);

            peer.Start();

            // keep going until ESCAPE is pressed
            Console.WriteLine("Press ESC to quit");
            while (!Console.KeyAvailable || Console.ReadKey().Key != ConsoleKey.Escape)
            {
                System.Threading.Thread.Sleep(10);
                NetIncomingMessage msg;
                while ((msg = peer.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.UnconnectedData:
                        //
                        // We've received a message from a client or a host
                        //

                        // by design, the first byte always indicates action
                        switch (msg.ReadByte())
                        {
                        case 0:         // register a new game
                            // currently only one game per host per router.
                            if (!registeredHosts.ContainsKey(msg.SenderEndpoint))
                            {
                                AvailableGame game = new AvailableGame();
                                game.Count             = msg.ReadInt32();
                                game.GamerTag          = msg.ReadString();
                                game.PrivateGamerSlots = msg.ReadInt32();
                                game.MaxGamers         = msg.ReadInt32();
                                game.IsHost            = msg.ReadBoolean();
                                game.InternalIP        = msg.ReadIPEndpoint();
                                game.ExternalIP        = msg.SenderEndpoint;
                                game.Game = msg.ReadString();


                                Console.WriteLine("Got registration for host " + game.ToString());
                                registeredHosts.Add(game.ExternalIP, game);
                            }
                            break;

                        case 1:
                            // It's a client wanting a list of registered hosts
                            Console.WriteLine("Sending list of " + registeredHosts.Count + " hosts to client " + msg.SenderEndpoint);
                            string appid = msg.ReadString();
                            foreach (AvailableGame g1 in registeredHosts.Values)
                            {
                                if (g1.Game == appid)
                                {
                                    // send registered host to client
                                    NetOutgoingMessage om = peer.CreateMessage();
                                    om.Write(g1.Count);
                                    om.Write(g1.GamerTag);
                                    om.Write(g1.PrivateGamerSlots);
                                    om.Write(g1.MaxGamers);
                                    om.Write(g1.IsHost);
                                    om.Write(g1.InternalIP);
                                    om.Write(g1.ExternalIP);
                                    peer.SendUnconnectedMessage(om, msg.SenderEndpoint);
                                }
                            }

                            break;

                        case 2:
                            // It's a client wanting to connect to a specific (external) host
                            IPEndPoint clientInternal = msg.ReadIPEndpoint();
                            IPEndPoint hostExternal   = msg.ReadIPEndpoint();
                            string     token          = msg.ReadString();

                            Console.WriteLine(msg.SenderEndpoint + " requesting introduction to " + hostExternal + " (token " + token + ")");

                            // find in list
                            foreach (AvailableGame elist in registeredHosts.Values)
                            {
                                if (elist.ExternalIP.Equals(hostExternal))
                                {
                                    // found in list - introduce client and host to eachother
                                    Console.WriteLine("Sending introduction...");
                                    peer.Introduce(
                                        elist.InternalIP,   // host internal
                                        elist.ExternalIP,   // host external
                                        clientInternal,     // client internal
                                        msg.SenderEndpoint, // client external
                                        token               // request token
                                        );
                                    break;
                                }
                            }
                            break;

                        case 3:
                            if (registeredHosts.ContainsKey(msg.SenderEndpoint))
                            {
                                AvailableGame game     = registeredHosts[msg.SenderEndpoint];
                                string        tag      = msg.ReadString();
                                string        gamename = msg.ReadString();
                                if (game.GamerTag == tag)
                                {
                                    Console.WriteLine("Remove for host " + game.ExternalIP.ToString());
                                    registeredHosts.Remove(game.ExternalIP);
                                }
                            }
                            break;

                        case 4:
                            if (registeredHosts.ContainsKey(msg.SenderEndpoint))
                            {
                                AvailableGame game  = registeredHosts[msg.SenderEndpoint];
                                int           count = msg.ReadInt32();
                                string        tag   = msg.ReadString();
                                if (game.GamerTag == tag)
                                {
                                    Console.WriteLine("Update for host " + game.ExternalIP.ToString());
                                    game.Count             = count;
                                    game.PrivateGamerSlots = msg.ReadInt32();
                                    game.MaxGamers         = msg.ReadInt32();
                                    game.IsHost            = msg.ReadBoolean();
                                    game.InternalIP        = msg.ReadIPEndpoint();
                                    game.Game = msg.ReadString();
                                }
                            }
                            break;
                        }
                        break;

                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.ErrorMessage:
                        // print diagnostics message
                        Console.WriteLine(msg.ReadString());
                        break;
                    }
                }
            }

            peer.Shutdown("shutting down");
        }