예제 #1
0
        /// <summary>
        /// This function reads and processes every incoming message arriving from the server.
        /// </summary>
        /// <returns>False, if the connection manager thread has to stop, true otherwise.</returns>
        private bool ProcessIncomingMessages()
        {
            List <RCPackage> incomingPackages = new List <RCPackage>();

            if (this.connection.ReceiveIncomingPackages(ref incomingPackages))
            {
                foreach (RCPackage package in incomingPackages)
                {
                    if (package.PackageType == RCPackageType.NETWORK_CUSTOM_PACKAGE &&
                        package.Sender >= 0 && package.Sender < this.memberCount && package.Sender != this.clientID)
                    {
                        /// Custom message from a member --> notify the listener.
                        this.listener.PackageArrived(package, package.Sender);
                    }
                    else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                             package.PackageFormat.ID == Network.FORMAT_LOBBY_LINE_STATE_REPORT)
                    {
                        /// Line state report from the server.
                        short            clientID       = package.ReadShort(0);
                        byte[]           lineStateBytes = package.ReadByteArray(1);
                        LobbyLineState[] lineStates     = new LobbyLineState[lineStateBytes.Length];
                        bool             lineStatesOK   = true;
                        for (int i = 0; i < lineStateBytes.Length; i++)
                        {
                            if (lineStateBytes[i] == (byte)LobbyLineState.Closed ||
                                lineStateBytes[i] == (byte)LobbyLineState.Engaged ||
                                lineStateBytes[i] == (byte)LobbyLineState.Opened)
                            {
                                lineStates[i] = (LobbyLineState)lineStateBytes[i];
                            }
                            else
                            {
                                lineStatesOK = false;
                            }
                        }
                        lineStatesOK = lineStatesOK && (clientID == this.clientID) && (lineStateBytes.Length == this.memberCount);
                        if (!lineStatesOK)
                        {
                            /// Line state report error --> shutdown.
                            this.connection.Shutdown();
                            if (this.Disposed != null)
                            {
                                this.Disposed(this);
                            }
                            this.listener.LobbyLost();
                            return(false);
                        }
                        else
                        {
                            /// Line state report arrived --> notify the listener
                            this.listener.LineStateReport(clientID, lineStates);
                            ///return true;
                        }
                    }
                    else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                             package.PackageFormat.ID == Network.FORMAT_DISCONNECT_INDICATOR)
                    {
                        /// Disconnection indicator from the server.
                        RCPackage disconnectAck = RCPackage.CreateNetworkControlPackage(Network.FORMAT_DISCONNECT_ACK);
                        disconnectAck.WriteString(0, string.Empty);
                        disconnectAck.WriteByteArray(1, new byte[0] {
                        });
                        this.connection.SendPackage(disconnectAck);
                        this.connection.Shutdown();
                        if (this.Disposed != null)
                        {
                            this.Disposed(this);
                        }
                        this.listener.LobbyLost();
                        return(false);
                    }
                    else if (package.PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                             package.PackageFormat.ID != Network.FORMAT_DEDICATED_MESSAGE &&
                             package.PackageFormat.ID != Network.FORMAT_DISCONNECT_ACK &&
                             package.PackageFormat.ID != Network.FORMAT_DISCONNECT_INDICATOR &&
                             package.PackageFormat.ID != Network.FORMAT_LOBBY_INFO &&
                             package.PackageFormat.ID != Network.FORMAT_LOBBY_INFO_VANISHED &&
                             package.PackageFormat.ID != Network.FORMAT_LOBBY_LINE_STATE_REPORT)
                    {
                        /// Custom internal message from the server --> notify the listener
                        TraceManager.WriteAllTrace(string.Format("Incoming package: {0}", package.ToString()), NetworkingSystemTraceFilters.INFO);
                        this.listener.ControlPackageArrived(package);
                    }
                    else
                    {
                        /// Unexpected package format and type --> immediate shutdown
                        this.connection.Shutdown();
                        if (this.Disposed != null)
                        {
                            this.Disposed(this);
                        }
                        this.listener.LobbyLost();
                        return(false);
                    }
                } /// end-foreach (RCPackage package in incomingPackages)

                /// Incoming packages has been processed.
                return(true);
            }
            else
            {
                /// Receive error --> immediate shutdown
                this.connection.Shutdown();
                if (this.Disposed != null)
                {
                    this.Disposed(this);
                }
                this.listener.LobbyLost();
                return(false);
            }
        }
예제 #2
0
        /// <summary>
        /// Continues the connection procedure to the server.
        /// </summary>
        /// <returns>
        /// In case of error this function automatically shuts down the connection, notifies the listener and
        /// returns false. Otherwise it returns true. If the line state report arrives from the server, this
        /// function automatically notifies the listener.
        /// </returns>
        private bool ContinueConnectToTheServer()
        {
            RCPackage lineStateReport = null;

            if (this.connection.ContinueConnectToTheServer(out lineStateReport))
            {
                if (lineStateReport != null)
                {
                    short            clientID       = lineStateReport.ReadShort(0);
                    byte[]           lineStateBytes = lineStateReport.ReadByteArray(1);
                    LobbyLineState[] lineStates     = new LobbyLineState[lineStateBytes.Length];
                    bool             lineStatesOK   = true;
                    for (int i = 0; i < lineStateBytes.Length; i++)
                    {
                        if (lineStateBytes[i] == (byte)LobbyLineState.Closed ||
                            lineStateBytes[i] == (byte)LobbyLineState.Engaged ||
                            lineStateBytes[i] == (byte)LobbyLineState.Opened)
                        {
                            lineStates[i] = (LobbyLineState)lineStateBytes[i];
                        }
                        else
                        {
                            lineStatesOK = false;
                        }
                    }
                    lineStatesOK = lineStatesOK && clientID > 0 && clientID < lineStateBytes.Length;
                    if (!lineStatesOK)
                    {
                        /// Line state report error --> shutdown.
                        this.connection.Shutdown();
                        if (this.Disposed != null)
                        {
                            this.Disposed(this);
                        }
                        this.listener.LobbyLost();
                        return(false);
                    }
                    else
                    {
                        /// Connection procedure finished --> send a line state report to the listener.
                        this.clientID    = clientID;
                        this.memberCount = lineStates.Length;
                        this.listener.LineStateReport(clientID, lineStates);
                        return(true);
                    }
                }
                /// No error but connection procedure not finished.
                return(true);
            }
            else
            {
                /// Connection rejected by the server or an error occured --> shutdown.
                this.connection.Shutdown();
                if (this.Disposed != null)
                {
                    this.Disposed(this);
                }
                this.listener.LobbyLost();
                return(false);
            }
        }