예제 #1
0
        private void HandleDataMessage(NetIncomingMessage inc)
        {
            if (!isActive)
            {
                return;
            }

            byte incByte      = inc.ReadByte();
            bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
            bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;

            //DebugConsole.NewMessage(isCompressed + " " + isConnectionInitializationStep + " " + (int)incByte);

            if (isConnectionInitializationStep && initializationStep != ConnectionInitialization.Success)
            {
                ReadConnectionInitializationStep(inc);
            }
            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);
            }
        }
예제 #2
0
        private void OnP2PData(ulong steamId, byte[] data, int dataLength)
        {
            if (!isActive)
            {
                return;
            }
            if (steamId != hostSteamId)
            {
                return;
            }

            timeout = Screen.Selected == GameMain.GameScreen ?
                      NetworkConnection.TimeoutThresholdInGame :
                      NetworkConnection.TimeoutThreshold;

            byte incByte      = data[0];
            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 (!isServerMessage)
            {
                return;
            }

            if (isConnectionInitializationStep)
            {
                ulong low     = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8);
                ulong high    = Lidgren.Network.NetBitWriter.ReadUInt32(data, 32, 8 + 32);
                ulong lobbyId = low + (high << 32);

                Steam.SteamManager.JoinLobby(lobbyId, false);
                IReadMessage inc = new ReadOnlyMessage(data, false, 1 + 8, dataLength - 9, ServerConnection);
                if (initializationStep != ConnectionInitialization.Success)
                {
                    incomingInitializationMessages.Add(inc);
                }
            }
            else if (isHeartbeatMessage)
            {
                return; //TODO: implement heartbeats
            }
            else if (isDisconnectMessage)
            {
                IReadMessage inc = new ReadOnlyMessage(data, false, 1, dataLength - 1, ServerConnection);
                string       msg = inc.ReadString();
                Close(msg);
                OnDisconnectMessageReceived?.Invoke(msg);
            }
            else
            {
                UInt16 length = data[1];
                length |= (UInt16)(((UInt32)data[2]) << 8);

                IReadMessage inc = new ReadOnlyMessage(data, isCompressed, 3, length, ServerConnection);
                incomingDataMessages.Add(inc);
            }
        }
        public override void Update(float deltaTime)
        {
            if (!started)
            {
                return;
            }

            if (OnOwnerDetermined != null && OwnerConnection != null)
            {
                OnOwnerDetermined?.Invoke(OwnerConnection);
                OnOwnerDetermined = null;
            }

            //backwards for loop so we can remove elements while iterating
            for (int i = connectedClients.Count - 1; i >= 0; i--)
            {
                SteamP2PConnection conn = connectedClients[i] as SteamP2PConnection;
                conn.Decay(deltaTime);
                if (conn.Timeout < 0.0)
                {
                    Disconnect(conn, "Timed out");
                }
            }

            try
            {
                while (ChildServerRelay.Read(out byte[] incBuf))
                {
                    IReadMessage inc = new ReadOnlyMessage(incBuf, false, 0, incBuf.Length, OwnerConnection);

                    HandleDataMessage(inc);
                }
            }

            catch (Exception e)
            {
                string errorMsg = "Server failed to read an incoming message. {" + e + "}\n" + e.StackTrace;
                GameAnalyticsManager.AddErrorEventOnce("SteamP2PServerPeer.Update:ClientReadException" + e.TargetSite.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
#if DEBUG
                DebugConsole.ThrowError(errorMsg);
#else
                if (GameSettings.VerboseLogging)
                {
                    DebugConsole.ThrowError(errorMsg);
                }
#endif
            }

            for (int i = 0; i < pendingClients.Count; i++)
            {
                PendingClient pendingClient = pendingClients[i];
                UpdatePendingClient(pendingClient);
                if (i >= pendingClients.Count || pendingClients[i] != pendingClient)
                {
                    i--;
                }
            }
        }
예제 #4
0
        private void HandleDataMessage(NetIncomingMessage inc)
        {
            if (netServer == null)
            {
                return;
            }

            PendingClient pendingClient = pendingClients.Find(c => c.Connection == inc.SenderConnection);

            byte incByte      = inc.ReadByte();
            bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
            bool isConnectionInitializationStep = (incByte & (byte)PacketHeader.IsConnectionInitializationStep) != 0;

            if (isConnectionInitializationStep && pendingClient != null)
            {
                ReadConnectionInitializationStep(pendingClient, inc);
            }
            else if (!isConnectionInitializationStep)
            {
                LidgrenConnection conn = connectedClients.Find(c => c.NetConnection == inc.SenderConnection);
                if (conn == null)
                {
                    if (pendingClient != null)
                    {
                        RemovePendingClient(pendingClient, DisconnectReason.AuthenticationRequired, "Received data message from unauthenticated client");
                    }
                    else if (inc.SenderConnection.Status != NetConnectionStatus.Disconnected &&
                             inc.SenderConnection.Status != NetConnectionStatus.Disconnecting)
                    {
                        inc.SenderConnection.Disconnect(DisconnectReason.AuthenticationRequired.ToString() + "/ Received data message from unauthenticated client");
                    }
                    return;
                }
                if (pendingClient != null)
                {
                    pendingClients.Remove(pendingClient);
                }
                if (serverSettings.BanList.IsBanned(conn.IPEndPoint.Address, conn.SteamID, out string banReason))
                {
                    Disconnect(conn, DisconnectReason.Banned.ToString() + "/ " + banReason);
                    return;
                }
                UInt16 length = inc.ReadUInt16();

                //DebugConsole.NewMessage(isCompressed + " " + isConnectionInitializationStep + " " + (int)incByte + " " + length);

                IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, conn);
                OnMessageReceived?.Invoke(conn, msg);
            }
        }
예제 #5
0
        public override void Update(float deltaTime)
        {
            if (!isActive)
            {
                return;
            }

            if (ChildServerRelay.HasShutDown || (ChildServerRelay.Process?.HasExited ?? true))
            {
                Close();
                var msgBox = new GUIMessageBox(TextManager.Get("ConnectionLost"), TextManager.Get("ServerProcessClosed"));
                msgBox.Buttons[0].OnClicked += (btn, obj) => { GameMain.MainMenuScreen.Select(); return(false); };
                return;
            }

            for (int i = remotePeers.Count - 1; i >= 0; i--)
            {
                if (remotePeers[i].DisconnectTime != null && remotePeers[i].DisconnectTime < Timing.TotalTime)
                {
                    ClosePeerSession(remotePeers[i]);
                }
            }

            for (int i = 0; i < 100; i++)
            {
                if (!Steamworks.SteamNetworking.IsP2PPacketAvailable())
                {
                    break;
                }
                var packet = Steamworks.SteamNetworking.ReadP2PPacket();
                if (packet.HasValue)
                {
                    OnP2PData(packet?.SteamId ?? 0, packet?.Data, packet?.Data.Length ?? 0, 0);
                    receivedBytes += packet?.Data.Length ?? 0;
                }
            }

            GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.ReceivedBytes, receivedBytes);
            GameMain.Client?.NetStats?.AddValue(NetStats.NetStatType.SentBytes, sentBytes);

            while (ChildServerRelay.Read(out byte[] incBuf))
            {
                ChildServerRelay.DisposeLocalHandles();
                IReadMessage inc = new ReadOnlyMessage(incBuf, false, 0, incBuf.Length, ServerConnection);
                HandleDataMessage(inc);
            }
        }
예제 #6
0
        private void HandleDataMessage(NetIncomingMessage inc)
        {
            if (netServer == null)
            {
                return;
            }

            if (inc.SenderConnection != netConnection)
            {
                return;
            }

            UInt64 senderSteamId = inc.ReadUInt64();

            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 (isServerMessage)
            {
                DebugConsole.ThrowError("Got server message from" + senderSteamId.ToString());
                return;
            }

            if (senderSteamId != OwnerSteamID) //sender is remote, handle disconnects and heartbeats
            {
                PendingClient      pendingClient   = pendingClients.Find(c => c.SteamID == senderSteamId);
                SteamP2PConnection connectedClient = connectedClients.Find(c => c.SteamID == senderSteamId);

                pendingClient?.Heartbeat();
                connectedClient?.Heartbeat();

                if (serverSettings.BanList.IsBanned(senderSteamId))
                {
                    if (pendingClient != null)
                    {
                        RemovePendingClient(pendingClient, DisconnectReason.Banned, "Banned");
                    }
                    else if (connectedClient != null)
                    {
                        Disconnect(connectedClient, DisconnectReason.Banned.ToString() + "/ Banned");
                    }
                    return;
                }
                else if (isDisconnectMessage)
                {
                    if (pendingClient != null)
                    {
                        string disconnectMsg = $"ServerMessage.HasDisconnected~[client]={pendingClient.Name}";
                        RemovePendingClient(pendingClient, DisconnectReason.Unknown, disconnectMsg);
                    }
                    else if (connectedClient != null)
                    {
                        string disconnectMsg = $"ServerMessage.HasDisconnected~[client]={connectedClient.Name}";
                        Disconnect(connectedClient, disconnectMsg, false);
                    }
                    return;
                }
                else if (isHeartbeatMessage)
                {
                    //message exists solely as a heartbeat, ignore its contents
                    return;
                }
                else if (isConnectionInitializationStep)
                {
                    if (pendingClient != null)
                    {
                        ReadConnectionInitializationStep(pendingClient, new ReadOnlyMessage(inc.Data, false, inc.PositionInBytes, inc.LengthBytes - inc.PositionInBytes, null));
                    }
                    else
                    {
                        ConnectionInitialization initializationStep = (ConnectionInitialization)inc.ReadByte();
                        if (initializationStep == ConnectionInitialization.ConnectionStarted)
                        {
                            pendingClients.Add(new PendingClient(senderSteamId));
                        }
                    }
                }
                else if (connectedClient != null)
                {
                    UInt16 length = inc.ReadUInt16();

                    IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, connectedClient);
                    OnMessageReceived?.Invoke(connectedClient, msg);
                }
            }
            else //sender is owner
            {
                if (OwnerConnection != null)
                {
                    (OwnerConnection as SteamP2PConnection).Heartbeat();
                }

                if (isDisconnectMessage)
                {
                    DebugConsole.ThrowError("Received disconnect message from owner");
                    return;
                }
                if (isServerMessage)
                {
                    DebugConsole.ThrowError("Received server message from owner");
                    return;
                }
                if (isConnectionInitializationStep)
                {
                    if (OwnerConnection == null)
                    {
                        string ownerName = inc.ReadString();
                        OwnerConnection = new SteamP2PConnection(ownerName, OwnerSteamID)
                        {
                            Status = NetworkConnectionStatus.Connected
                        };

                        OnInitializationComplete?.Invoke(OwnerConnection);
                    }
                    return;
                }
                if (isHeartbeatMessage)
                {
                    return;
                }
                else
                {
                    UInt16 length = inc.ReadUInt16();

                    IReadMessage msg = new ReadOnlyMessage(inc.Data, isCompressed, inc.PositionInBytes, length, OwnerConnection);
                    OnMessageReceived?.Invoke(OwnerConnection, msg);
                }
            }
        }
예제 #7
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;
                }
            }
        }
예제 #8
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);
            }
        }
예제 #9
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;
                }
            }
        }
예제 #10
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);
                }
            }
        }