Ejemplo n.º 1
0
        /// <summary>
        /// Attempts to connect to another server application from this server core/application.
        /// </summary>
        /// <param name="endPoint"></param>
        /// <param name="applicationName"></param>
        /// <param name="hailMessage"></param>
        /// <param name="callbackObject">Object that will be returned in the response. (Not sent to the server)</param>
        /// <returns>Indicates whether a connection has been successfully attempted (doesn't indicate if it was established).</returns>
        public bool ConnectToServer(IPEndPoint endPoint, string hailMessage, object callbackObject = null)
        {
            if (endPoint == null)
            {
                return(false);
            }
            else
            {
                var msg = lidgrenServerObj.CreateMessage();
                msg.Write(hailMessage);
                msg.Write(ServerTypeUniqueByte);

#if DEBUGBUILD
                this.ClassLogger.LogDebug("Attempting to connect to another server.");
#endif
                NetConnection possibleConnection = lidgrenServerObj.Connect(endPoint, msg);

                ConnectionResponse response = new ConnectionResponse(endPoint, possibleConnection, hailMessage, callbackObject);

                this.UnhandledServerConnections.Add(response);
                return(true);
            }
        }
Ejemplo n.º 2
0
        private void MGServer_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            NetPeerConfiguration config = new NetPeerConfiguration(applicationIdentifier);

            config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);
            config.EnableMessageType(NetIncomingMessageType.DiscoveryResponse);
            config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);

            if (availableSession == null)
            {
                config.Port = port;
            }

            // create and start server
            peer = new NetServer(config);
            peer.Start();

            myLocalAddress = GetMyLocalIpAddress();

            IPAddress adr = IPAddress.Parse(myLocalAddress);

            myLocalEndPoint = new IPEndPoint(adr, port);

            // force a little wait until we have a LocalGamer otherwise things
            // break. This is the first item in the queue so it shouldnt take long before we
            // can continue.
            while (session.LocalGamers.Count <= 0)
            {
                Thread.Sleep(10);
            }

            if (availableSession != null)
            {
                if (!this.online)
                {
                    peer.Connect(availableSession.EndPoint);
                }
                else
                {
                    RequestNATIntroduction(availableSession.EndPoint, peer);
                }
            }
            else
            {
                if (this.online)
                {
                    IPAddress ipaddr = NetUtility.Resolve(masterServer);
                    if (ipaddr != null)
                    {
                        m_masterServer = new IPEndPoint(ipaddr, masterserverport);
                        LocalNetworkGamer localMe = session.LocalGamers [0];

                        NetOutgoingMessage om = peer.CreateMessage();

                        om.Write((byte)0);
                        om.Write(session.AllGamers.Count);
                        om.Write(localMe.Gamertag);
                        om.Write(session.PrivateGamerSlots);
                        om.Write(session.MaxGamers);
                        om.Write(localMe.IsHost);
                        om.Write(myLocalEndPoint);
                        om.Write(peer.Configuration.AppIdentifier);
                        // send up session properties
                        int[] propertyData = new int[session.SessionProperties.Count * 2];
                        NetworkSessionProperties.WriteProperties(session.SessionProperties, propertyData);
                        for (int x = 0; x < propertyData.Length; x++)
                        {
                            om.Write(propertyData [x]);
                        }
                        peer.SendUnconnectedMessage(om, m_masterServer);                          // send message to peer
                    }
                    else
                    {
                        throw new Exception("Could not resolve live host");
                    }
                }
            }

            // run until we are done
            do
            {
                NetIncomingMessage msg;
                while ((msg = peer.ReadMessage()) != null)
                {
                    switch (msg.MessageType)
                    {
                    case NetIncomingMessageType.UnconnectedData:
                        break;

                    case NetIncomingMessageType.NatIntroductionSuccess:
#if !WINDOWS_PHONE
                        Game.Instance.Log("NAT punch through OK " + msg.SenderEndPoint);
#endif
                        peer.Connect(msg.SenderEndPoint);
                        break;

                    case NetIncomingMessageType.DiscoveryRequest:
                        //
                        // Server received a discovery request from a client; send a discovery response (with no extra data attached)
                        //
                        // Get the primary local gamer
                        LocalNetworkGamer localMe = session.LocalGamers [0];

                        NetOutgoingMessage om = peer.CreateMessage();

                        om.Write(session.RemoteGamers.Count);
                        om.Write(localMe.Gamertag);
                        om.Write(session.PrivateGamerSlots);
                        om.Write(session.MaxGamers);
                        om.Write(localMe.IsHost);
                        int[] propertyData = new int[session.SessionProperties.Count * 2];
                        NetworkSessionProperties.WriteProperties(session.SessionProperties, propertyData);
                        for (int x = 0; x < propertyData.Length; x++)
                        {
                            om.Write(propertyData [x]);
                        }

                        peer.SendDiscoveryResponse(om, msg.SenderEndPoint);
                        break;

                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.ErrorMessage:
                        //
                        // Just print diagnostic messages to console
                        //
#if !WINDOWS_PHONE
                        Game.Instance.Log(msg.ReadString());
#endif
                        break;

                    case NetIncomingMessageType.StatusChanged:
                        NetConnectionStatus status = (NetConnectionStatus)msg.ReadByte();
                        if (status == NetConnectionStatus.Disconnected)
                        {
#if !WINDOWS_PHONE
                            Game.Instance.Log(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " disconnected! from " + msg.SenderEndPoint);
#endif
                            CommandGamerLeft cgj  = new CommandGamerLeft(msg.SenderConnection.RemoteUniqueIdentifier);
                            CommandEvent     cmde = new CommandEvent(cgj);
                            session.commandQueue.Enqueue(cmde);
                        }
                        if (status == NetConnectionStatus.Connected)
                        {
                            //
                            // A new player just connected!
                            //
                            if (!pendingGamers.ContainsKey(msg.SenderConnection.RemoteUniqueIdentifier))
                            {
#if !WINDOWS_PHONE
                                Game.Instance.Log(NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) + " connected! from " + msg.SenderEndPoint);
#endif
                                pendingGamers.Add(msg.SenderConnection.RemoteUniqueIdentifier, msg.SenderConnection);
                                SendProfileRequest(msg.SenderConnection);
                            }
                            else
                            {
#if !WINDOWS_PHONE
                                Game.Instance.Log("Already have a connection for that user, this is probably due to both NAT intro requests working");
#endif
                            }
                        }

                        break;

                    case NetIncomingMessageType.Data:

                        NetworkMessageType mt = (NetworkMessageType)msg.ReadByte();
                        switch (mt)
                        {
                        case NetworkMessageType.Data:
                            byte[] data = new byte[msg.LengthBytes - 1];
                            msg.ReadBytes(data, 0, data.Length);
                            CommandEvent cme = new CommandEvent(new CommandReceiveData(msg.SenderConnection.RemoteUniqueIdentifier,
                                                                                       data));
                            session.commandQueue.Enqueue(cme);
                            break;

                        case NetworkMessageType.Introduction:

                            var introductionAddress = msg.ReadString();

                            try {
                                IPEndPoint endPoint = ParseIPEndPoint(introductionAddress);

                                if (myLocalEndPoint.ToString() != endPoint.ToString() && !AlreadyConnected(endPoint))
                                {
#if !WINDOWS_PHONE
                                    Game.Instance.Log("Received Introduction for: " + introductionAddress +
                                                      " and I am: " + myLocalEndPoint + " from: " + msg.SenderEndPoint);
#endif
                                    peer.Connect(endPoint);
                                }
                            } catch (Exception exc) {
#if !WINDOWS_PHONE
                                Game.Instance.Log("Error parsing Introduction: " + introductionAddress + " : " + exc.Message);
#endif
                            }

                            break;

                        case NetworkMessageType.GamerProfile:
#if !WINDOWS_PHONE
                            Game.Instance.Log("Profile recieved from: " + NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier));
#endif
                            if (pendingGamers.ContainsKey(msg.SenderConnection.RemoteUniqueIdentifier))
                            {
                                pendingGamers.Remove(msg.SenderConnection.RemoteUniqueIdentifier);
                                msg.ReadInt32();
                                string gamerTag = msg.ReadString();
                                msg.ReadInt32();
                                msg.ReadInt32();
                                GamerStates state = (GamerStates)msg.ReadInt32();
                                state &= ~GamerStates.Local;
                                CommandGamerJoined cgj = new CommandGamerJoined(msg.SenderConnection.RemoteUniqueIdentifier);
                                cgj.GamerTag = gamerTag;
                                cgj.State    = state;
                                CommandEvent cmde = new CommandEvent(cgj);
                                session.commandQueue.Enqueue(cmde);
                            }
                            else
                            {
#if !WINDOWS_PHONE
                                Game.Instance.Log("We received a profile for an existing gamer.  Need to update it.");
#endif
                            }
                            break;

                        case NetworkMessageType.RequestGamerProfile:
#if !WINDOWS_PHONE
                            Game.Instance.Log("Profile Request recieved from: " + msg.SenderEndPoint);
#endif
                            SendProfile(msg.SenderConnection);
                            break;

                        case NetworkMessageType.GamerStateChange:
                            GamerStates gamerstate = (GamerStates)msg.ReadInt32();
                            gamerstate &= ~GamerStates.Local;
#if !WINDOWS_PHONE
                            Game.Instance.Log("State Change from: " + msg.SenderEndPoint + " new State: " + gamerstate);
#endif
                            foreach (var gamer in session.RemoteGamers)
                            {
                                if (gamer.RemoteUniqueIdentifier == msg.SenderConnection.RemoteUniqueIdentifier)
                                {
                                    gamer.State = gamerstate;
                                }
                            }
                            break;

                        case NetworkMessageType.SessionStateChange:
                            NetworkSessionState sessionState = (NetworkSessionState)msg.ReadInt32();

                            foreach (var gamer in session.RemoteGamers)
                            {
                                if (gamer.RemoteUniqueIdentifier == msg.SenderConnection.RemoteUniqueIdentifier)
                                {
#if !WINDOWS_PHONE
                                    Game.Instance.Log("Session State change from: " + NetUtility.ToHexString(msg.SenderConnection.RemoteUniqueIdentifier) +
                                                      " session is now: " + sessionState);
#endif
                                    if (gamer.IsHost && sessionState == NetworkSessionState.Playing)
                                    {
                                        session.StartGame();
                                    }
                                }
                            }

                            break;
                        }
                        break;
                    }
                }

                // sleep to allow other processes to run smoothly
                // This may need to be changed depending on network throughput
                Thread.Sleep(1);

                if (worker.CancellationPending)
                {
#if !WINDOWS_PHONE
                    Game.Instance.Log("worker CancellationPending");
#endif
                    e.Cancel = true;
                    done     = true;
                }
            } while (!done);
        }
Ejemplo n.º 3
0
        public static void Main(string[] args)
        {
            try
            {
                using (var server = new NetServer())
                {
                    server.Listen((self) =>
                    {
                        System.Console.WriteLine("Server is listening on: " + self.Address.ToString());
                    });
                    server.Connect((channel) =>
                    {
                        System.Console.WriteLine("Client connected.");

                        channel.Fault((c, exception) =>
                        {
                            System.Console.WriteLine(((MiniNet.Exceptions.SocketException)exception).StatusCode.ToString());
                            System.Console.WriteLine(exception.ToString());
                        });

                        var encoding = Encoding.Unicode;
                        var decoder  = new StringDecoder(encoding);
                        var encoder  = new StringEncoder(encoding);

                        //channel.Authenticate();
                        channel.Start();

                        channel.Message((self, buffer) =>
                        {
                            if (buffer.Size > 0)
                            {
                                var str = decoder.Process(buffer);
                                System.Console.WriteLine(str + "-" + buffer.Size + "-");
                                System.Console.WriteLine(buffer.DumpHex(int.MaxValue));
                            }
                        });

                        /*var payload = "Server: Hello Client";
                         * var message = MiniNet.Buffers.Buffer.Create(encoding.GetByteCount(payload));
                         *
                         * encoder.Process(message, payload);
                         * channel.SendAsync(message);*/

                        Thread.Sleep(1000);
                        //channel.Close();
                    });
                    server.Fault((exception) =>
                    {
                        System.Console.WriteLine(exception.ToString());
                    });
                    server.Bind(8080, "localhost");

                    using (var client = new TcpClient())
                    {
                        client.NoDelay = true;
                        client.Connect(server.Address.Host, server.Address.Port);
                        Thread.Sleep(100);

                        var encoding = new UnicodeEncoding(false, false, true);
                        var stream   = client.GetStream();
                        //var reader = new StreamReader(stream, encoding);
                        var writer = new StreamWriter(stream, encoding)
                        {
                            AutoFlush = true
                        };

                        for (int i = 1; i <= 4; i++)
                        {
                            /*var bytesReceived = new byte[1024];
                             * var lengthReceived = client.GetStream().Read(bytesReceived, 0, bytesReceived.Length);
                             * if (lengthReceived > 0)
                             * {
                             *  var message = encoding.GetString(bytesReceived, 0, lengthReceived);
                             *  System.Console.WriteLine(MiniNet.Buffers.Buffer.DumpHex(bytesReceived, 0, lengthReceived, int.MaxValue));
                             *  System.Console.WriteLine("'" + message + "'" + lengthReceived);
                             * }*/

                            writer.Write("Client: Hello Server");
                        }

                        Thread.Sleep(100);
                        System.Console.WriteLine("Press ENTER to quit");
                        System.Console.ReadLine();
                        client.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex.ToString());
                System.Console.WriteLine(ex.StackTrace);
            }
        }