Beispiel #1
0
        private void AddOrUpdatePeer(RemotePeer peerNofication)
        {
            if (peerNofication == null)
            {
                Trace.Write("Couldn't parse notification.");
            }
            else if (peerNofication.Id != Id)
            {
                Peers.AddOrUpdate(peerNofication.Id, key =>
                {
                    Trace.WriteLine(
                        string.Format(
                            "New data from {0} received: {1} ",
                            peerNofication.Address,
                            peerNofication.Id));

                    return(peerNofication);
                },
                                  (key, oldvalue) =>
                {
                    Trace.WriteLine(string.Format("Update from {0} received: {1} ", peerNofication.Address, peerNofication.Id));
                    return(peerNofication);
                });

                foreach (var property in peerNofication.PeerProperties)
                {
                    Trace.WriteLine(string.Format("{0}:{1}", property.Key, property.Value));
                }
            }
        }
Beispiel #2
0
 public override int GetHashCode()
 {
     if (_channel != null)
     {
         return(_channel.GetHashCode());
     }
     return(RemotePeer.GetHashCode());
 }
Beispiel #3
0
 public bool Equals(PeerConnection other)
 {
     if (_channel != null)
     {
         return(_channel.Equals(other._channel));
     }
     return(RemotePeer.Equals(other.RemotePeer));
 }
        void INetworkApplication.LeaveOnServer(RemotePeer remotePeer, NetOutgoingMessage message)
        {
            var v = random.Next();

            Console.WriteLine("Goodbye " + remotePeer.PeerInfo + " = " + v + " (on server)" +
                              FormatPlayerData(remotePeer.PeerInfo));

            message.Write(v);
        }
Beispiel #5
0
        /// <summary>
        /// Used to add a peer.
        /// </summary>
        /// <param name="peer">Peer to add.</param>
        private void AddClient(NetPeer peer)
        {
            GameObject newPlayer = Instantiate(remotePeerPrefab, CompassAlignedScene.instance.transform);

            newPlayer.name = "Remote Client " + peer.EndPoint.ToString();
            RemotePeer newRemoteClient = newPlayer.GetComponentInChildren <RemotePeer>();

            otherPlayers.Add(peer, newRemoteClient);
        }
Beispiel #6
0
        public void TestReliableSequencedChannelReceiveOutOfSequence()
        {
            ReliableSequencedChannel sender   = new ReliableSequencedChannel(0);
            ReliableSequencedChannel receiver = new ReliableSequencedChannel(0);

            RemotePeer      firstPeer;
            ChanneledPacket firstPacket;
            {
                // Create first packet with sequence 1
                firstPeer = new RemotePeer();// (new IPEndPoint(IPAddress.Any, 5670));
                ulong sessionId = (ulong)0;
                firstPeer.ChallengeResult = sessionId;
                byte[] payload = new byte[0];
                firstPacket = sender.CreateOutgoingMessage(payload, 0, payload.Length);
            }
            {
                Random random = new Random(0);
                foreach (int i in Enumerable.Range(1, 100).OrderBy(x => random.Next()))
                {
                    RemotePeer fakePeer  = new RemotePeer(); // (new IPEndPoint(IPAddress.Any, 5670));
                    ulong      sessionId = (ulong)i;
                    fakePeer.ChallengeResult = sessionId;
                    byte[] payload = new byte[random.Next(0, 1024)];
                    random.NextBytes(payload);
                    ChanneledPacket         sent      = sender.CreateOutgoingMessage(payload, 0, payload.Length);
                    byte[]                  buffer    = new byte[5000];
                    int                     oSize     = sent.Write(buffer, fakePeer);
                    ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandleIncomingMessagePoll(buffer, oSize, out bool hasMore);
                    Assert.IsNull(incPacket);
                }
            }

            {
                byte[] buffer = new byte[5000];
                int    oSize  = firstPacket.Write(buffer, firstPeer);
                ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandleIncomingMessagePoll(buffer, oSize, out bool hasMore);

                Assert.NotNull(incPacket);
                Assert.IsTrue(incPacket.Payload.Length == 0);
                Assert.IsTrue(hasMore);
            }

            {
                Random random = new Random(0);
                foreach (int i in Enumerable.Range(1, 100).OrderBy(x => random.Next()))
                {
                    ulong  sessionId = (ulong)i;
                    byte[] payload   = new byte[random.Next(0, 1024)];
                    random.NextBytes(payload);
                    ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandlePoll();
                    Assert.NotNull(incPacket);
                    CollectionAssert.AreEqual(incPacket.Payload, payload);
                }
            }
        }
        void INetworkApplication.JoinOnServer(RemotePeer remotePeer, NetOutgoingMessage joinMessage,
                                              NetOutgoingMessage connectedMessage)
        {
            var v = random.Next();

            Console.WriteLine("Welcome " + remotePeer.PeerInfo + " = " + v + " (on server)" +
                              FormatPlayerData(remotePeer.PeerInfo));

            joinMessage.Write(v);
            connectedMessage.Write(v);
        }
Beispiel #8
0
 internal void RegisterPeer(UserId peerId, X509Certificate2 certificate)
 {
     if (_id != peerId)
     {
         lock (_syncObject)
         {
             var peer = new RemotePeer(peerId, certificate);
             _peers.Add(peer.Id, peer);
         }
     }
 }
        void INetworkApplication.LeaveOnClient(RemotePeer remotePeer, NetIncomingMessage message)
        {
            int v;

            try
            {
                v = message.ReadInt32();
            }
            catch (Exception e)
            {
                throw new ProtocolException("", e);
            }

            Console.WriteLine("Goodbye " + remotePeer.PeerInfo + " = " + v + " (on client)" +
                              FormatPlayerData(remotePeer.PeerInfo));
        }
Beispiel #10
0
        void INetworkApplication.HostMigrationChangeHost(RemotePeer newHost, NetIncomingMessage message)
        {
            int v;

            try
            {
                v = message.ReadInt32();
            }
            catch (Exception e)
            {
                throw new ProtocolException("", e);
            }

            Console.WriteLine("Host Migration to " + newHost.PeerInfo + " = " + v + " (on client)" +
                              FormatPlayerData(newHost.PeerInfo));
        }
Beispiel #11
0
        private void ReceiveBroadcastNotification(IAsyncResult ar)
        {
            if (Stopping)
            {
                return;
            }

            Trace.WriteLine("Received notification from broadcast peer.");
            var ip = new IPEndPoint(IPAddress.Any, BROADCAST_NOTIFICATION_PORT_NUMBER);

            byte[]     notification   = broadcast.EndReceive(ar, ref ip);
            RemotePeer peerNofication = FromNotification(notification);

            AddOrUpdatePeer(peerNofication);
            broadcast.BeginReceive(this.ReceiveBroadcastNotification, null);
        }
Beispiel #12
0
        private void OnAuthChange(Steamworks.SteamId steamID, Steamworks.SteamId ownerID, Steamworks.AuthResponse status)
        {
            RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamID);

            DebugConsole.Log(steamID + " validation: " + status + ", " + (remotePeer != null));

            if (remotePeer == null)
            {
                return;
            }

            if (remotePeer.Authenticated)
            {
                if (status != Steamworks.AuthResponse.OK)
                {
                    DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication status changed: " + status.ToString());
                }
                return;
            }

            if (status == Steamworks.AuthResponse.OK)
            {
                remotePeer.OwnerSteamID   = ownerID;
                remotePeer.Authenticated  = true;
                remotePeer.Authenticating = false;
                foreach (var msg in remotePeer.UnauthedMessages)
                {
                    //rewrite the owner id before
                    //forwarding the messages to
                    //the server, since it's only
                    //known now
                    int prevBitPosition = msg.Message.BitPosition;
                    msg.Message.BitPosition = sizeof(ulong) * 8;
                    msg.Message.Write(ownerID);
                    msg.Message.BitPosition = prevBitPosition;
                    byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
                    Array.Resize(ref msgToSend, msg.Message.LengthBytes);
                    ChildServerRelay.Write(msgToSend);
                }
                remotePeer.UnauthedMessages.Clear();
            }
            else
            {
                DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication failed: " + status.ToString());
                return;
            }
        }
Beispiel #13
0
        public void SendFish(Fish f)
        {
            if (Stopping)
            {
                return;
            }

            if (!Peers.Values.Any())
            {
                Trace.WriteLine("Nowhere to send " + f.Name);
                return;
            }

            // Send to the most recent peer we heard from.
            RemotePeer peer = Peers.Values.OrderByDescending(v => v.LastHeardFrom)
                              .FirstOrDefault(p => p.PeerProperties["Occupants"] < 200 && p.PeerProperties["Algae"] < 128);

            if (peer == null)
            {
                Trace.WriteLine("No suitable peers to send {0}", f.Name);
            }

            if (peer != null && f != null)
            {
                try
                {
                    using (var client = new TcpClient())
                    {
                        client.Connect(new IPEndPoint(peer.Address, peer.Port));
                        using (NetworkStream stream = client.GetStream())
                        {
                            f.ToStream(stream);
                        }
                    }
                    FireFishSent(f);
                }
                catch (Exception e)
                {
                    Trace.WriteLine("Exception on send.");
                    Trace.WriteLine(e);
                }
            }
        }
Beispiel #14
0
        private void DisconnectPeer(RemotePeer peer, string msg)
        {
            if (!string.IsNullOrWhiteSpace(msg))
            {
                if (peer.DisconnectTime == null)
                {
                    peer.DisconnectTime = Timing.TotalTime + 1.0;
                }

                IWriteMessage outMsg = new WriteOnlyMessage();
                outMsg.Write((byte)(PacketHeader.IsServerMessage | PacketHeader.IsDisconnectMessage));
                outMsg.Write(msg);

                Steamworks.SteamNetworking.SendP2PPacket(peer.SteamID, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
            }
            else
            {
                ClosePeerSession(peer);
            }
        }
Beispiel #15
0
        private void ReceiveUnicastNotification(IAsyncResult ar)
        {
            if (Stopping)
            {
                return;
            }

            Trace.WriteLine("Received notification from manual peer.");
            Socket socket = this.manualPeerListener.EndAcceptSocket(ar);

            using (var s = new NetworkStream(socket))
            {
                RemotePeer peerNofication = FromNotification(s);
                this.AddOrUpdatePeer(peerNofication);
                this.manualPeers.AddOrUpdate(new ManualPeer {
                    Address = peerNofication.ManualNotificationAddress, Port = peerNofication.ManualNotificationPort
                });
            }

            this.manualPeerListener.BeginAcceptSocket(this.ReceiveUnicastNotification, null);
        }
Beispiel #16
0
        private void OnAuthChange(ulong steamID, ulong ownerID, ClientAuthStatus status)
        {
            RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamID);

            DebugConsole.Log(steamID + " validation: " + status + ", " + (remotePeer != null));

            if (remotePeer == null)
            {
                return;
            }

            if (remotePeer.Authenticated)
            {
                if (status != ClientAuthStatus.OK)
                {
                    DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication status changed: " + status.ToString());
                }
                return;
            }

            if (status == ClientAuthStatus.OK)
            {
                remotePeer.Authenticated  = true;
                remotePeer.Authenticating = false;
                foreach (var msg in remotePeer.UnauthedMessages)
                {
                    NetSendResult result = netClient.SendMessage(msg.Second, msg.First);
                    if (result != NetSendResult.Queued && result != NetSendResult.Sent)
                    {
                        DebugConsole.NewMessage("Failed to send unauthed message to host: " + result);
                    }
                }
                remotePeer.UnauthedMessages.Clear();
            }
            else
            {
                DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication failed: " + status.ToString());
                return;
            }
        }
Beispiel #17
0
        public static void Main(string[] args)
        {
            RudelNetwork serverNetwork         = new RudelNetwork();
            byte         serverReliableChannel = serverNetwork.AddChannel(ChannelType.ReliableSequenced);

            RudelNetwork clientNetwork         = new RudelNetwork();
            byte         clientReliableChannel = clientNetwork.AddChannel(ChannelType.ReliableSequenced);


            serverNetwork.Start();
            clientNetwork.Start();

            LocalPeer server = serverNetwork.CreateLocalPeer();

            server.StartListening(new IPEndPoint(IPAddress.Any, 4343));
            LocalPeer client = clientNetwork.CreateLocalPeer();

            client.StartListening(new IPEndPoint(IPAddress.Any, 3434));

            // Don't actually need this. You will get it in the connect event
            RemotePeer clientServerPeer = client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 4343));


            // TODO: Poll for messages
            while (true)
            {
                NetworkEvent serverEvent = server.Poll();
                if (serverEvent != null)
                {
                    Console.WriteLine("@Server: " + serverEvent.EventType);
                }

                NetworkEvent clientEvent = client.Poll();
                if (clientEvent != null)
                {
                    Console.WriteLine("@Client: " + clientEvent.EventType);
                }
            }
        }
Beispiel #18
0
        private void OnAuthChange(Steamworks.SteamId steamID, Steamworks.SteamId ownerID, Steamworks.AuthResponse status)
        {
            RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamID);

            DebugConsole.Log(steamID + " validation: " + status + ", " + (remotePeer != null));

            if (remotePeer == null)
            {
                return;
            }

            if (remotePeer.Authenticated)
            {
                if (status != Steamworks.AuthResponse.OK)
                {
                    DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication status changed: " + status.ToString());
                }
                return;
            }

            if (status == Steamworks.AuthResponse.OK)
            {
                remotePeer.Authenticated  = true;
                remotePeer.Authenticating = false;
                foreach (var msg in remotePeer.UnauthedMessages)
                {
                    byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
                    Array.Resize(ref msgToSend, msg.Message.LengthBytes);
                    ChildServerRelay.Write(msgToSend);
                }
                remotePeer.UnauthedMessages.Clear();
            }
            else
            {
                DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam authentication failed: " + status.ToString());
                return;
            }
        }
Beispiel #19
0
        public void TestReliableSequencedChannelReceiveInSequence()
        {
            ReliableSequencedChannel sender   = new ReliableSequencedChannel(0);
            ReliableSequencedChannel receiver = new ReliableSequencedChannel(0);

            Random random = new Random(0);

            for (int i = 0; i < 100000; i++)
            {
                RemotePeer fakePeer  = new RemotePeer();// new IPEndPoint(IPAddress.Any, 5670));
                ulong      sessionId = RandomUtils.GetULong(false);
                fakePeer.ChallengeResult = sessionId;
                int    payLength = random.Next(0, 1024);
                byte[] payload   = new byte[payLength];
                random.NextBytes(payload);
                ChanneledPacket         sent      = sender.CreateOutgoingMessage(payload, 0, payload.Length);
                byte[]                  buffer    = new byte[5000];
                int                     oSize     = sent.Write(buffer, fakePeer);
                ReliableSequencedPacket incPacket = (ReliableSequencedPacket)receiver.HandleIncomingMessagePoll(buffer, oSize, out bool hasMore);
                Assert.IsNotNull(incPacket, "it:" + i);
                Assert.AreEqual(payLength, incPacket.Payload.Length);
                CollectionAssert.AreEqual(payload, incPacket.Payload);
            }
        }
Beispiel #20
0
        public void TestConnection()
        {
            RudelNetwork network = new RudelNetwork();

            network.Start();

            LocalPeer server = new LocalPeer(network);

            server.StartListening(new IPEndPoint(IPAddress.Any, 5057));



            LocalPeer client = new LocalPeer(network);

            client.StartListening(new IPEndPoint(IPAddress.Any, 5058));


            RemotePeer remotePeer = client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5057));

            while (true)
            {
                Debug.Print(remotePeer.ConnectionState.ToString());
            }
        }
Beispiel #21
0
 private void ClosePeerSession(RemotePeer peer)
 {
     Steamworks.SteamNetworking.CloseP2PSessionWithUser(peer.SteamID);
     remotePeers.Remove(peer);
 }
Beispiel #22
0
        private void HandleDataMessage(IReadMessage inc)
        {
            if (!isActive)
            {
                return;
            }

            UInt64         recipientSteamId = inc.ReadUInt64();
            DeliveryMethod deliveryMethod   = (DeliveryMethod)inc.ReadByte();

            int p2pDataStart = inc.BytePosition;

            byte incByte = inc.ReadByte();

            bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
            bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
            bool isDisconnectMessage            = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
            bool isServerMessage    = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
            bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;

            if (recipientSteamId != selfSteamID)
            {
                if (!isServerMessage)
                {
                    DebugConsole.ThrowError("Received non-server message meant for remote peer");
                    return;
                }

                RemotePeer peer = remotePeers.Find(p => p.SteamID == recipientSteamId);

                if (peer == null)
                {
                    return;
                }

                if (isDisconnectMessage)
                {
                    DisconnectPeer(peer, inc.ReadString());
                    return;
                }

                Steamworks.P2PSend sendType;
                switch (deliveryMethod)
                {
                case DeliveryMethod.Reliable:
                case DeliveryMethod.ReliableOrdered:
                    //the documentation seems to suggest that the Reliable send type
                    //enforces packet order (TODO: verify)
                    sendType = Steamworks.P2PSend.Reliable;
                    break;

                default:
                    sendType = Steamworks.P2PSend.Unreliable;
                    break;
                }

                byte[] p2pData;

                if (isConnectionInitializationStep)
                {
                    p2pData    = new byte[inc.LengthBytes - p2pDataStart + 8];
                    p2pData[0] = inc.Buffer[p2pDataStart];
                    Lidgren.Network.NetBitWriter.WriteUInt64(SteamManager.CurrentLobbyID, 64, p2pData, 8);
                    Array.Copy(inc.Buffer, p2pDataStart + 1, p2pData, 9, inc.LengthBytes - p2pDataStart - 1);
                }
                else
                {
                    p2pData = new byte[inc.LengthBytes - p2pDataStart];
                    Array.Copy(inc.Buffer, p2pDataStart, p2pData, 0, p2pData.Length);
                }

                if (p2pData.Length + 4 >= MsgConstants.MTU)
                {
                    DebugConsole.Log("WARNING: message length comes close to exceeding MTU, forcing reliable send (" + p2pData.Length.ToString() + " bytes)");
                    sendType = Steamworks.P2PSend.Reliable;
                }

                bool successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType);
                sentBytes += p2pData.Length;

                if (!successSend)
                {
                    if (sendType != Steamworks.P2PSend.Reliable)
                    {
                        DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + p2pData.Length.ToString() + " bytes)");
                        sendType    = Steamworks.P2PSend.Reliable;
                        successSend = Steamworks.SteamNetworking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, 0, sendType);
                        sentBytes  += p2pData.Length;
                    }
                    if (!successSend)
                    {
                        DebugConsole.ThrowError("Failed to send message to remote peer! (" + p2pData.Length.ToString() + " bytes)");
                    }
                }
            }
            else
            {
                if (isDisconnectMessage)
                {
                    DebugConsole.ThrowError("Received disconnect message from owned server");
                    return;
                }
                if (!isServerMessage)
                {
                    DebugConsole.ThrowError("Received non-server message from owned server");
                    return;
                }
                if (isHeartbeatMessage)
                {
                    return; //timeout is handled by Lidgren, ignore this message
                }
                if (isConnectionInitializationStep)
                {
                    IWriteMessage outMsg = new WriteOnlyMessage();
                    outMsg.Write(selfSteamID);
                    outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
                    outMsg.Write(Name);

                    byte[] msgToSend = (byte[])outMsg.Buffer.Clone();
                    Array.Resize(ref msgToSend, outMsg.LengthBytes);
                    ChildServerRelay.Write(msgToSend);
                    return;
                }
                else
                {
                    if (initializationStep != ConnectionInitialization.Success)
                    {
                        OnInitializationComplete?.Invoke();
                        initializationStep = ConnectionInitialization.Success;
                    }
                    UInt16       length = inc.ReadUInt16();
                    IReadMessage msg    = new ReadOnlyMessage(inc.Buffer, isCompressed, inc.BytePosition, length, ServerConnection);
                    OnMessageReceived?.Invoke(msg);

                    return;
                }
            }
        }
Beispiel #23
0
        private void OnP2PData(ulong steamId, byte[] data, int dataLength, int channel)
        {
            if (!isActive)
            {
                return;
            }

            RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamId);

            if (remotePeer == null || remotePeer.DisconnectTime != null)
            {
                return;
            }

            IWriteMessage outMsg = new WriteOnlyMessage();

            outMsg.Write(steamId);
            outMsg.Write(data, 1, dataLength - 1);

            DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];

            byte incByte      = data[1];
            bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
            bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
            bool isDisconnectMessage            = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
            bool isServerMessage    = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
            bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;

            if (!remotePeer.Authenticated)
            {
                if (!remotePeer.Authenticating)
                {
                    if (isConnectionInitializationStep)
                    {
                        remotePeer.DisconnectTime = null;

                        IReadMessage             authMsg            = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
                        ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
                        //Console.WriteLine("received init step from "+steamId.ToString()+" ("+initializationStep.ToString()+")");
                        if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
                        {
                            remotePeer.Authenticating = true;

                            authMsg.ReadString(); //skip name
                            authMsg.ReadInt32();  //skip owner key
                            authMsg.ReadUInt64(); //skip steamid
                            UInt16 ticketLength = authMsg.ReadUInt16();
                            byte[] ticket       = authMsg.ReadBytes(ticketLength);

                            Steamworks.BeginAuthResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId);
                            if (authSessionStartState != Steamworks.BeginAuthResult.OK)
                            {
                                DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam auth session failed to start: " + authSessionStartState.ToString());
                                return;
                            }
                        }
                    }
                }
            }

            if (remotePeer.Authenticating)
            {
                remotePeer.UnauthedMessages.Add(new RemotePeer.UnauthedMessage()
                {
                    DeliveryMethod = deliveryMethod, Message = outMsg
                });
            }
            else
            {
                byte[] msgToSend = (byte[])outMsg.Buffer.Clone();
                Array.Resize(ref msgToSend, outMsg.LengthBytes);
                ChildServerRelay.Write(msgToSend);
            }
        }
Beispiel #24
0
        private void HandleDataMessage(NetIncomingMessage inc)
        {
            if (!isActive)
            {
                return;
            }

            UInt64 recipientSteamId = inc.ReadUInt64();

            int p2pDataStart = inc.PositionInBytes;

            byte incByte = inc.ReadByte();

            bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
            bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
            bool isDisconnectMessage            = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
            bool isServerMessage    = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
            bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;

            if (recipientSteamId != selfSteamID)
            {
                if (!isServerMessage)
                {
                    DebugConsole.ThrowError("Received non-server message meant for remote peer");
                    return;
                }

                RemotePeer peer = remotePeers.Find(p => p.SteamID == recipientSteamId);

                if (peer == null)
                {
                    return;
                }

                if (isDisconnectMessage)
                {
                    DisconnectPeer(peer, inc.ReadString());
                    return;
                }

                Facepunch.Steamworks.Networking.SendType sendType;
                switch (inc.DeliveryMethod)
                {
                case NetDeliveryMethod.ReliableUnordered:
                case NetDeliveryMethod.ReliableSequenced:
                case NetDeliveryMethod.ReliableOrdered:
                    //the documentation seems to suggest that the Reliable send type
                    //enforces packet order (TODO: verify)
                    sendType = Facepunch.Steamworks.Networking.SendType.Reliable;
                    break;

                default:
                    sendType = Facepunch.Steamworks.Networking.SendType.Unreliable;
                    break;
                }

                byte[] p2pData;

                if (isConnectionInitializationStep)
                {
                    p2pData    = new byte[inc.LengthBytes - p2pDataStart + 8];
                    p2pData[0] = inc.Data[p2pDataStart];
                    Lidgren.Network.NetBitWriter.WriteUInt64(Steam.SteamManager.Instance.Lobby.CurrentLobby, 64, p2pData, 8);
                    Array.Copy(inc.Data, p2pDataStart + 1, p2pData, 9, inc.LengthBytes - p2pDataStart - 1);
                }
                else
                {
                    p2pData = new byte[inc.LengthBytes - p2pDataStart];
                    Array.Copy(inc.Data, p2pDataStart, p2pData, 0, p2pData.Length);
                }

                if (p2pData.Length + 4 >= MsgConstants.MTU)
                {
                    DebugConsole.Log("WARNING: message length comes close to exceeding MTU, forcing reliable send (" + p2pData.Length.ToString() + " bytes)");
                    sendType = Facepunch.Steamworks.Networking.SendType.Reliable;
                }

                bool successSend = Steam.SteamManager.Instance.Networking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, sendType);

                if (!successSend)
                {
                    if (sendType != Facepunch.Steamworks.Networking.SendType.Reliable)
                    {
                        DebugConsole.Log("WARNING: message couldn't be sent unreliably, forcing reliable send (" + p2pData.Length.ToString() + " bytes)");
                        sendType    = Facepunch.Steamworks.Networking.SendType.Reliable;
                        successSend = Steam.SteamManager.Instance.Networking.SendP2PPacket(recipientSteamId, p2pData, p2pData.Length, sendType);
                    }
                    if (!successSend)
                    {
                        DebugConsole.ThrowError("Failed to send message to remote peer! (" + p2pData.Length.ToString() + " bytes)");
                    }
                }
            }
            else
            {
                if (isDisconnectMessage)
                {
                    DebugConsole.ThrowError("Received disconnect message from owned server");
                    return;
                }
                if (!isServerMessage)
                {
                    DebugConsole.ThrowError("Received non-server message from owned server");
                    return;
                }
                if (isHeartbeatMessage)
                {
                    return; //timeout is handled by Lidgren, ignore this message
                }
                if (isConnectionInitializationStep)
                {
                    NetOutgoingMessage outMsg = netClient.CreateMessage();
                    outMsg.Write(selfSteamID);
                    outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
                    outMsg.Write(Name);
                    NetSendResult result = netClient.SendMessage(outMsg, NetDeliveryMethod.ReliableUnordered);
                    if (result != NetSendResult.Queued && result != NetSendResult.Sent)
                    {
                        DebugConsole.NewMessage("Failed to send initialization message to host: " + result);
                    }

                    return;
                }
                else
                {
                    if (initializationStep != ConnectionInitialization.Success)
                    {
                        OnInitializationComplete?.Invoke();
                        initializationStep = ConnectionInitialization.Success;
                    }
                    UInt16       length = inc.ReadUInt16();
                    IReadMessage msg    = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, ServerConnection);
                    OnMessageReceived?.Invoke(msg);

                    return;
                }
            }
        }
Beispiel #25
0
        private void OnP2PData(ulong steamId, byte[] data, int dataLength, int channel)
        {
            if (!isActive)
            {
                return;
            }

            RemotePeer remotePeer = remotePeers.Find(p => p.SteamID == steamId);

            if (remotePeer == null || remotePeer.DisconnectTime != null)
            {
                return;
            }

            NetOutgoingMessage outMsg = netClient.CreateMessage();

            outMsg.Write(steamId);
            outMsg.Write(data, 1, dataLength - 1);

            NetDeliveryMethod lidgrenDeliveryMethod = NetDeliveryMethod.Unreliable;

            switch ((DeliveryMethod)data[0])
            {
            case DeliveryMethod.Unreliable:
                lidgrenDeliveryMethod = NetDeliveryMethod.Unreliable;
                break;

            case DeliveryMethod.Reliable:
                lidgrenDeliveryMethod = NetDeliveryMethod.ReliableUnordered;
                break;

            case DeliveryMethod.ReliableOrdered:
                lidgrenDeliveryMethod = NetDeliveryMethod.ReliableOrdered;
                break;
            }

            byte incByte      = data[1];
            bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
            bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;
            bool isDisconnectMessage            = (incByte & (byte)PacketHeader.IsDisconnectMessage) != 0;
            bool isServerMessage    = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
            bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;

            if (!remotePeer.Authenticated)
            {
                if (!remotePeer.Authenticating)
                {
                    if (isConnectionInitializationStep)
                    {
                        remotePeer.DisconnectTime = null;

                        IReadMessage             authMsg            = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
                        ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
                        if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
                        {
                            remotePeer.Authenticating = true;

                            authMsg.ReadString(); //skip name
                            authMsg.ReadUInt64(); //skip steamid
                            UInt16 ticketLength = authMsg.ReadUInt16();
                            byte[] ticket       = authMsg.ReadBytes(ticketLength);

                            ClientStartAuthSessionResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId);
                            if (authSessionStartState != ClientStartAuthSessionResult.OK)
                            {
                                DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam auth session failed to start: " + authSessionStartState.ToString());
                                return;
                            }
                        }
                    }
                }
            }

            if (remotePeer.Authenticating)
            {
                remotePeer.UnauthedMessages.Add(new Pair <NetDeliveryMethod, NetOutgoingMessage>(lidgrenDeliveryMethod, outMsg));
            }
            else
            {
                NetSendResult result = netClient.SendMessage(outMsg, lidgrenDeliveryMethod);
                if (result != NetSendResult.Queued && result != NetSendResult.Sent)
                {
                    DebugConsole.NewMessage("Failed to send message from " + SteamManager.SteamIDUInt64ToString(remotePeer.SteamID) + " to host: " + result);
                }
            }
        }
        public void ConnectionAccepted(RemotePeer peer)
        {
            _netQueue.Add(
                delegate
                {
                    // P.pr("Accepted from: " + client.Client.RemoteEndPoint, Color.Blue);
                    //NetworkModule.SendNotification("Accepted from: " + client.Client.RemoteEndPoint,
            //                                                       NotificationType.RESOURCE);

                    // To jest bez sensu:

                    foreach (User user in _netModule.UsersStructure)
                    {
                        if (user.isConnected && peer.Endpoint.Address.Equals(user.currentAddress.Address))
                        {
                            _userConnectionMap.LinkUserAndConnection(user, peer);
                            break;
                        }
                    }
                });
        }
Beispiel #27
0
 public RemotePeerTest()
 {
     socket = A.Fake <AsyncSocket>();
     p      = new RemotePeer(socket);
 }
Beispiel #28
0
        public void Refresh(OpTransfer transfer)
        {
            if (!transfer.Peers.ContainsKey(RoutingID))
            {
                Text = "Error";
                return;
            }

            RemotePeer peer = transfer.Peers[RoutingID];

            int upPiece = -1, downPiece = -1;

            string text = "";

            // remote name / IP - last seen, timeout: x
            // flags: UL (active?, chunk index, progress) / DL (chunk index, progress) / RBU

            if (peer.DhtIndex < transfer.RoutingTable.Length && transfer.RoutingTable[peer.DhtIndex] == peer)
            {
                text += "(B" + peer.DhtIndex + ") ";
            }

            text += Service.Core.GetName(peer.Client.UserID) + ", ";
            text += "Last Seen: " + peer.LastSeen.ToShortTimeString() + ", ";
            //text += "Timeout: " + peer.PingTimeout + ", ";

            if (peer.RemoteBitfieldUpdated)
            {
                text += "Out of Date, ";
            }

            if (Service.UploadPeers.ContainsKey(peer.RoutingID))
            {
                UploadPeer upload = Service.UploadPeers[peer.RoutingID];
                text += "Last Upload: " + upload.LastAttempt.ToShortTimeString() + ", ";

                if (upload.Active == peer)
                {
                    text += "Upload: ";

                    if (upload.Active.LastRequest != null && upload.Active.CurrentPos != 0)
                    {
                        TransferRequest req = upload.Active.LastRequest;
                        upPiece = req.ChunkIndex;
                        int percent = (int)((req.EndByte - upload.Active.CurrentPos) * 100 / (req.EndByte - req.StartByte));

                        // Piece 4 - 34%,
                        text += "Piece " + upPiece + " - " + percent + "%, ";
                    }
                    else
                    {
                        text += "Pending, ";
                    }
                }

                if (peer.LastError != null)
                {
                    text += "Stopped: " + peer.LastError + ", ";
                }
            }

            if (Service.DownloadPeers.ContainsKey(peer.RoutingID))
            {
                if (Service.DownloadPeers[peer.RoutingID].Requests.ContainsKey(transfer.FileID))
                {
                    TransferRequest req = Service.DownloadPeers[peer.RoutingID].Requests[transfer.FileID];

                    text += "Download: ";

                    if (req.CurrentPos != 0)
                    {
                        downPiece = req.ChunkIndex;
                        int percent = (int)((req.EndByte - req.CurrentPos) * 100 / (req.EndByte - req.StartByte));

                        // Piece 4 - 34%,
                        text += "Piece " + downPiece + " - " + percent + "%, ";
                    }
                    else
                    {
                        text += "Pending, ";
                    }
                }
            }

            Text = text.Substring(0, text.Length - 2);

            Bitfield.UpdateField(peer.RemoteBitfield, upPiece, downPiece);
        }
        //#######################################
        /// <summary>
        ///   Usuniecie polaczenia z listy, jesli polaczenie bylo przypisane do usera, jest on zwracany
        /// </summary>
        /// <param name = "peer">obiekt polaczenia do usuniecia</param>
        /// <returns>obiekt usera (jesli polaczenie bylo przypisane do usera) lub null</returns>
        private User RemoveConnection(RemotePeer peer)
        {
            //NetworkModule.SendNotification("Connections left: " + _connections.Count, NotificationType.DIAGNOSTIC);

            return _userConnectionMap.RemoveUserLink(peer);
        }
        /// <summary>
        ///   Nastapilo rozlaczenie ustanowionego wczesniej polaczenia
        /// </summary>
        /// <param name = "peer">Obiekt polaczenia, ktore zostalo przerwane</param>
        public void ConnectionLost(RemotePeer peer)
        {
            //NetworkModule.SendNotification("Lost connection with: " + peer.EndPointAddress, NotificationType.RESOURCE);

            _netQueue.Add(
                delegate
                {
                    if (_netModule.NetworkState is StateNonArbiter)
                    {
                        StateNonArbiter state = (StateNonArbiter) _netModule.NetworkState;
                        RemotePeer p;

                        //TODO: bez sensu:
            //                            if (_connections.TryGetValue(state.Arbiter, out p) && p == peer)
            //                            {
            //                                _netQueue.Add(() => _netModule.ChangeStateTo(new StateDisconnected(_netModule)));
            //                            }
                    }

                    User user = RemoveConnection(peer);

                    // jesli z tym polaczeniem byl skojazony user, obiekt przekazywany jest glebiej
                    if (user != null)
                    {
                        _netModule.TaskCenter.ObjectReceived(peer, user, new ConnectionLost());
                    }
                });
        }
Beispiel #31
0
 private void ClosePeerSession(RemotePeer peer)
 {
     Steam.SteamManager.Instance.Networking.CloseSession(peer.SteamID);
     remotePeers.Remove(peer);
 }
Beispiel #32
0
 public RemotePeer GetOrRegister(NetworkManager net)
 {
     RemotePeer peer;
     if (_owners.TryGetValue(net, out peer))
     {
         // polaczenie juz zwiazane z tym managerem
         return peer;
     }
     // polaczenie nie zwiazane z tym managerem
     peer = new RemotePeer(_managerHigher, _proxy);
     _owners.Add(net, peer);
     return peer;
 }
        //#######################################
        // Metody obslugi zawierania polaczen: (wywolywane sa z obcych watkow)
        //#######################################
        /// <summary>
        ///   Wywolywana w przypadku udanej lub nie proby laczenia sie do uzytkownika w sieci.
        /// </summary>
        /// <param name = "userInfo">login uzytkownika z ktorym udalo sie polaczyc, lub null w przeciwnym przypadku</param>
        /// <param name = "peer">Obiekt udanego polaczenia, lub null w przeciwnym przypadku</param>
        public void UserChosen(object userInfo, RemotePeer peer)
        {
            _netQueue.Add(
                delegate
                {
                    if (peer != null)
                    {
                        User user = _netModule.UsersStructure[(string) userInfo];

                        //  P.pr("Connected to user: "******" - " + peer.Address, Color.Blue);
                        //NetworkModule.SendNotification(
            //                                "Connected to user: "******" - " + peer.EndPointAddress,
            //                                NotificationType.RESOURCE);

                        _netModule.TaskCenter.StartConnectionTask(peer);
                    }
                    else
                    {
                        //SharedContext.service.EnqueueMessage(new ToInterfaceLoginResult(true, null));
                        ChangeToArbiter();
                    }
                });
        }