Ejemplo n.º 1
0
        /// <summary>
        /// Creates an RCCommand object from the given RCPackage.
        /// </summary>
        /// <param name="cmdPackage">The RCPackage to be deserialized.</param>
        /// <returns>The created RCCommand.</returns>
        public static RCCommand FromPackage(RCPackage cmdPackage)
        {
            if (cmdPackage == null)
            {
                throw new ArgumentNullException("cmdPackage");
            }
            if (!cmdPackage.IsCommitted)
            {
                throw new ArgumentException("The incoming package is not committed!", "cmdPackage");
            }
            if (cmdPackage.PackageFormat.ID != RCCommand.COMMAND_PACKAGEFORMAT)
            {
                throw new ArgumentException("The incoming package is not a command package!", "cmdPackage");
            }

            RCNumVector targetPosition  = RCNumVector.Undefined;
            int         targetPositionX = cmdPackage.ReadInt(2);
            int         targetPositionY = cmdPackage.ReadInt(3);

            if (targetPositionX != -1 && targetPositionY != -1)
            {
                targetPosition = new RCNumVector(new RCNumber(targetPositionX), new RCNumber(targetPositionY));
            }

            return(new RCCommand(
                       cmdPackage.ReadString(0),
                       cmdPackage.ReadIntArray(1),
                       targetPosition,
                       cmdPackage.ReadInt(4),
                       cmdPackage.ReadString(5)));
        }
Ejemplo n.º 2
0
        /// <see cref="ITileSetLoader.LoadTileSet"/>
        public ITileSet LoadTileSet(byte[] data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            int       parsedBytes;
            RCPackage package = RCPackage.Parse(data, 0, data.Length, out parsedBytes);

            if (!package.IsCommitted)
            {
                throw new ArgumentException("TileSet data package is not committed!", "data");
            }
            if (package.PackageType != RCPackageType.CUSTOM_DATA_PACKAGE)
            {
                throw new ArgumentException("TileSet data package must be RCPackageType.CUSTOM_DATA_PACKAGE!", "data");
            }
            if (package.PackageFormat.ID != PackageFormats.TILESET_FORMAT)
            {
                throw new ArgumentException("Format of TileSet data package must be RC.Engine.Maps.TileSetFormat!", "data");
            }

            TileSet tileset = XmlTileSetReader.Read(package.ReadString(0), package.ReadString(1));

            return(tileset);
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Called when a NETWORK_CUSTOM_PACKAGE has arrived from the lobby.
 /// </summary>
 /// <remarks>Must be implemented at both server and client side.</remarks>
 public virtual void PackageArrivedHdl(int timestamp, RCPackage package, int senderID)
 {
     if (IsSimulationRunning_i())
     {
         /// Package arrived during simulation stage must be handled.
         if (package.PackageFormat.ID == DssRoot.DSS_COMMAND)
         {
             if (!CommandPackageArrived(package, senderID))
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_COMMAND package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_COMMIT)
         {
             if (!this.root.SimulationMgr.RegisterCommit(package, senderID))
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_COMMIT package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_COMMIT_ANSWER)
         {
             if (!this.root.SimulationMgr.RegisterCommitAnswer(package, senderID))
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_COMMIT_ANSWER package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_LEAVE)
         {
             if (this.root.SimulationMgr.RegisterLeaveMessage(package, senderID))
             {
                 this.root.OperatorLeftSimulationStage(senderID);
             }
             else
             {
                 this.root.SimulationMgr.SimulationStageError(string.Format("Processing incoming DSS_LEAVE package failed. Sender: {0}. Package: {1}", senderID, package.ToString()),
                                                              new byte[] { });
             }
         }
         else if (package.PackageFormat.ID == DssRoot.DSS_SIM_ERROR)
         {
             string errorDescr = package.ReadString(0);
             byte[] customData = package.ReadByteArray(1);
             this.root.SimulationMgr.SimulationStageErrorReceived(string.Format("DSS_SIM_ERROR received from operator-{0}: {1}", senderID, errorDescr), customData);
         }
         else
         {
             this.root.SimulationMgr.SimulationStageError(string.Format("Unexpected package arrived from operator-{0}: {1}", senderID, package.ToString()),
                                                          new byte[] { });
         }
     }
     else
     {
         /// Package arrived during setup stage is not allowed.
         PackageArrivedDuringSetupStage_i(package, senderID);
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates a MapHeader structure from the given RCPackage.
        /// </summary>
        /// <param name="package">The RCPackage that contains the map header informations.</param>
        /// <returns>The created MapHeader structure.</returns>
        public static MapHeader FromPackage(RCPackage package)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (!package.IsCommitted)
            {
                throw new ArgumentException("The header package is not committed!", "package");
            }
            if (package.PackageType != RCPackageType.CUSTOM_DATA_PACKAGE)
            {
                throw new ArgumentException("Invalid package type!", "package");
            }
            if (package.PackageFormat.ID != MapFileFormat.MAP_HEADER)
            {
                throw new ArgumentException("Invalid package format!", "package");
            }

            MapHeader header = new MapHeader();

            header.appVersion   = new Version(package.ReadInt(0), package.ReadInt(1), package.ReadInt(2), package.ReadInt(3));
            header.mapName      = package.ReadString(4);
            header.tilesetName  = package.ReadString(5);
            header.mapSize      = new RCIntVector(package.ReadShort(6), package.ReadShort(7));
            header.maxPlayers   = package.ReadByte(8);
            header.checksumList = new List <int>(package.ReadIntArray(9));

            if (header.mapName == null)
            {
                throw new MapException("Map name information is missing!");
            }
            if (header.tilesetName == null)
            {
                throw new MapException("Tileset name information is missing!");
            }
            if (header.mapSize.X <= 0 || header.mapSize.Y <= 0)
            {
                throw new MapException("Map size cannot be negative or 0!");
            }
            if (header.maxPlayers <= 0)
            {
                throw new MapException("Maximum number of players cannot be negative or 0!");
            }
            return(header);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Constructs a LobbyInfo object from an RCPackage.
        /// </summary>
        /// <param name="source">The package that contains the LobbyInfo data.</param>
        /// <returns>The contructed LobbyInfo or null if no LobbyInfo can be constructed from the given RCPackage.</returns>
        public static LobbyInfo FromRCPackage(RCPackage source)
        {
            if (null != source && source.IsCommitted && source.PackageFormat.ID == Network.FORMAT_LOBBY_INFO)
            {
                string idStr = source.ReadString(0);
                Guid   id;
                if (!Guid.TryParse(idStr, out id))
                {
                    TraceManager.WriteAllTrace(string.Format("Unable to parse {0} as a GUID!", idStr), NetworkingSystemTraceFilters.INFO);
                    return(null);
                }

                byte[]    customDataBytes = source.ReadByteArray(3);
                int       parsedBytes     = 0;
                RCPackage customData      = null;

                if (customDataBytes.Length > 0)
                {
                    RCPackage.Parse(customDataBytes, 0, customDataBytes.Length, out parsedBytes);
                }
                if (customDataBytes.Length == 0 ||
                    (null != customData && customData.IsCommitted && parsedBytes == customDataBytes.Length))
                {
                    LobbyInfo retInfo = new LobbyInfo(id,                                               /// ID
                                                      source.ReadString(1),                             /// IPAddress
                                                      source.ReadInt(2),                                /// PortNumber
                                                      (customDataBytes.Length != 0) ? customData : null /// Custom infos about the lobby
                                                      );
                    return(retInfo);
                }
                else
                {
                    TraceManager.WriteAllTrace("LobbyInfo.FromRCPackage failed: unexpected CustomData package format!", NetworkingSystemTraceFilters.INFO);
                    return(null);
                }
            }
            else
            {
                TraceManager.WriteAllTrace("LobbyInfo.FromRCPackage failed: unexpected package format!", NetworkingSystemTraceFilters.INFO);
                return(null);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="package"></param>
        private void CreateJoinRow(RCPackage package)
        {
            string runningThreadName = package.ReadString(1);
            string waitingThreadName = package.ReadString(3);
            long   timestamp         = package.ReadLong(4);

            if (!this.threadsToColumns.ContainsKey(runningThreadName))
            {
                int idxOfCol = this.gridLog.Columns.Add(runningThreadName, runningThreadName);
                this.threadsToColumns.Add(runningThreadName, idxOfCol);
            }
            if (!this.threadsToColumns.ContainsKey(waitingThreadName))
            {
                int idxOfCol = this.gridLog.Columns.Add(waitingThreadName, waitingThreadName);
                this.threadsToColumns.Add(waitingThreadName, idxOfCol);
            }

            object[] rowContent = new object[this.threadsToColumns.Count];
            rowContent[this.threadsToColumns[runningThreadName]] = "THREAD_FINISH";
            rowContent[this.threadsToColumns[waitingThreadName]] = "THREAD_JOIN";

            int idxOfRow = this.gridLog.Rows.Add(rowContent);

            this.gridLog.Rows[idxOfRow].HeaderCell.Value = timestamp.ToString();

            DataGridViewCell cellOfRunning = this.gridLog[this.threadsToColumns[runningThreadName], idxOfRow];
            DataGridViewCell cellOfWaiting = this.gridLog[this.threadsToColumns[waitingThreadName], idxOfRow];

            cellOfRunning.Style.BackColor = Color.LightPink;
            cellOfWaiting.Style.BackColor = Color.LightPink;

            if (!this.doubleSelections.ContainsKey(cellOfRunning))
            {
                this.doubleSelections.Add(cellOfRunning, cellOfWaiting);
            }
            if (!this.doubleSelections.ContainsKey(cellOfWaiting))
            {
                this.doubleSelections.Add(cellOfWaiting, cellOfRunning);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="package"></param>
        private void CreateForkRow(RCPackage package)
        {
            string newThreadName    = package.ReadString(1);
            string parentThreadName = package.ReadString(3);
            long   timestamp        = package.ReadLong(4);

            if (!this.threadsToColumns.ContainsKey(newThreadName))
            {
                int idxOfCol = this.gridLog.Columns.Add(newThreadName, newThreadName);
                this.threadsToColumns.Add(newThreadName, idxOfCol);
            }
            if (!this.threadsToColumns.ContainsKey(parentThreadName))
            {
                int idxOfCol = this.gridLog.Columns.Add(parentThreadName, parentThreadName);
                this.threadsToColumns.Add(parentThreadName, idxOfCol);
            }

            object[] rowContent = new object[this.threadsToColumns.Count];
            rowContent[this.threadsToColumns[newThreadName]]    = "THREAD_START";
            rowContent[this.threadsToColumns[parentThreadName]] = "THREAD_FORK";

            int idxOfRow = this.gridLog.Rows.Add(rowContent);

            this.gridLog.Rows[idxOfRow].HeaderCell.Value = timestamp.ToString();

            DataGridViewCell cellOfNew    = this.gridLog[this.threadsToColumns[newThreadName], idxOfRow];
            DataGridViewCell cellOfParent = this.gridLog[this.threadsToColumns[parentThreadName], idxOfRow];

            cellOfNew.Style.BackColor    = Color.LightGreen;
            cellOfParent.Style.BackColor = Color.LightGreen;

            if (!this.doubleSelections.ContainsKey(cellOfNew))
            {
                this.doubleSelections.Add(cellOfNew, cellOfParent);
            }
            if (!this.doubleSelections.ContainsKey(cellOfParent))
            {
                this.doubleSelections.Add(cellOfParent, cellOfNew);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="package"></param>
        private void CreateExceptionRow(RCPackage package)
        {
            string threadName = package.ReadString(1);
            long   timestamp  = package.ReadLong(2);
            bool   isFatal    = (package.ReadByte(3) == (byte)0x00) ? false : true;
            string ex         = package.ReadString(4);

            if (!this.threadsToColumns.ContainsKey(threadName))
            {
                int idxOfCol = this.gridLog.Columns.Add(threadName, threadName);
                this.threadsToColumns.Add(threadName, idxOfCol);
            }

            object[] rowContent = new object[this.threadsToColumns.Count];
            rowContent[this.threadsToColumns[threadName]] = isFatal ? "FATAL_EXCEPTION" : "EXCEPTION";

            int idxOfRow = this.gridLog.Rows.Add(rowContent);

            this.gridLog.Rows[idxOfRow].HeaderCell.Value = timestamp.ToString();

            DataGridViewCell cellOfException = this.gridLog[this.threadsToColumns[threadName], idxOfRow];

            cellOfException.Style.BackColor = isFatal ? Color.Red : Color.Yellow;

            if (isFatal)
            {
                if (!this.fatalExceptions.ContainsKey(cellOfException))
                {
                    this.fatalExceptions.Add(cellOfException, ex);
                }
            }
            else
            {
                if (!this.normalExceptions.ContainsKey(cellOfException))
                {
                    this.normalExceptions.Add(cellOfException, ex);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="package"></param>
        private void CreateEventFormatRow(RCPackage package)
        {
            string threadName = package.ReadString(1);
            long   timestamp  = package.ReadLong(2);
            string evt        = package.ReadString(3);

            if (!this.threadsToColumns.ContainsKey(threadName))
            {
                int idxOfCol = this.gridLog.Columns.Add(threadName, threadName);
                this.threadsToColumns.Add(threadName, idxOfCol);
            }

            object[] rowContent = new object[this.threadsToColumns.Count];
            rowContent[this.threadsToColumns[threadName]] = evt;

            int idxOfRow = this.gridLog.Rows.Add(rowContent);

            this.gridLog.Rows[idxOfRow].HeaderCell.Value = timestamp.ToString();

            DataGridViewCell cellOfEvent = this.gridLog[this.threadsToColumns[threadName], idxOfRow];

            cellOfEvent.Style.BackColor = Color.LightGray;
        }
Ejemplo n.º 10
0
 /// <see cref="ILobbyListener.ControlPackageArrived"/>
 public void ControlPackageArrived(RCPackage package, int senderID)
 {
     if (this.InvokeRequired)
     {
         /// Invoke this function from the UI thread.
         this.Invoke(new InternalArrivedFromClientCallback(this.ControlPackageArrived), new object[2] {
             package, senderID
         });
     }
     else
     {
         /// Normal invoke.
         if (senderID >= 0 && senderID < this.textBoxes.Length && package.PackageFormat.ID == MY_FORMAT)
         {
             this.textChangingFromNetwork  = true;
             this.textBoxes[senderID].Text = package.ReadString(0);
             this.textChangingFromNetwork  = false;
             UpdateControls();
         }
     }
 }
Ejemplo n.º 11
0
 /// <see cref="ILobbyListener.ControlPackageArrived"/>
 public void ControlPackageArrived(RCPackage package)
 {
     if (this.InvokeRequired)
     {
         /// Invoke this function from the UI thread.
         this.Invoke(new InternalArrivedFromServerCallback(this.ControlPackageArrived), new object[1] {
             package
         });
     }
     else
     {
         /// Normal invoke.
         if (package.PackageFormat.ID == MY_FORMAT)
         {
             this.textChangingFromNetwork = true;
             this.textBoxes[0].Text       = package.ReadString(0);
             this.textChangingFromNetwork = false;
             UpdateControls();
         }
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Registers the given DSS_LEAVE message arrived from the given operator.
        /// </summary>
        /// <param name="leaveMsg">The arrived DSS_LEAVE message.</param>
        /// <param name="senderID">The sender operator.</param>
        /// <returns>True in case of success, false otherwise.</returns>
        public bool RegisterLeaveMessage(RCPackage leaveMsg, int senderID)
        {
            if (!this.initialized)
            {
                throw new DssException("DssSimulationMgr is uninitialized!");
            }

            /// If we are currently finishing the simulation --> do nothing
            if (this.hostLeft)
            {
                return(true);
            }

            if (leaveMsg == null || !leaveMsg.IsCommitted)
            {
                throw new ArgumentException("leaveMsg");
            }
            if (senderID == this.root.IdOfThisPeer)
            {
                throw new DssException("Unexpected DSS_LEAVE sender!");
            }
            if (senderID < 0 || senderID >= this.root.OpCount)
            {
                throw new ArgumentException("senderID");
            }

            if (leaveMsg.PackageFormat.ID != DssRoot.DSS_LEAVE)
            {
                /// Package format error.
                return(false);
            }

            string reason = leaveMsg.ReadString(0);

            byte[] customData = leaveMsg.ReadByteArray(1);
            TraceManager.WriteAllTrace(string.Format("DSS_LEAVE: sender={0}, reason= {1}", senderID, reason), DssTraceFilters.SIMULATION_INFO);

            /// Set the corresponding operator flag to false.
            this.operatorFlags[senderID] = false;

            if (senderID > 0)
            {
                /// GUEST-leave
                /// Unregister all CommitMonitors that became unnecessary.
                List <int> commitAwTicketsToUnreg = new List <int>();
                foreach (KeyValuePair <int, CommitMonitor> monitor in this.commitAwMonitors)
                {
                    monitor.Value.Refresh();
                    if (monitor.Value.IsCommitAnswered)
                    {
                        commitAwTicketsToUnreg.Add(monitor.Value.Ticket);
                    }
                }
                foreach (int ticket in commitAwTicketsToUnreg)
                {
                    UnregisterCommitMonitor(ticket);
                }

                /// Try to register the leave of operator to the nextRound.
                if (!this.nextRound.Leave(senderID))
                {
                    /// If failed, try to register to the nextNextRound.
                    if (!this.nextNextRound.Leave(senderID))
                    {
                        /// If failed, try to register to the nextNextNextRound.
                        if (!this.nextNextNextRound.Leave(senderID))
                        {
                            /// Error: unable to register
                            TraceManager.WriteAllTrace(string.Format("Unable to register the leave of operator-{0}.", senderID), DssTraceFilters.SIMULATION_ERROR);
                            return(false);
                        }
                    }
                }

                /// Now check whether the next round has become committed with this leave message.
                if (this.waitingForCommit && this.nextRound.IsCommitted)
                {
                    TraceManager.WriteAllTrace("WAITING FOR COMMIT END (guest left)", DssTraceFilters.SIMULATION_INFO);
                    /// The missing commit has arrived, so we can continue the simulation
                    this.waitingForCommit = false;
                    /// Compute the scheduled time for the next frame
                    int nextFrameStartTime = this.currentRound.BaseTime
                                             + (this.currentRound.CurrentFrameIndex + 1) * this.currentRound.TargetFrameTime;
                    SendCommit();
                    SwapRounds();
                    /// Schedule the next frame.
                    SetNextFrameExecutionTime(Math.Max(nextFrameStartTime, DssRoot.Time));
                }
            }
            else
            {
                /// HOST-leave
                /// Stop the timers
                UnregisterAllCommitMonitors();
                StopCommitTimeoutClock();

                if (this.waitingForCommit && this.nextRound.IsCommitted)
                {
                    /// Can continue with the next round

                    TraceManager.WriteAllTrace("WAITING FOR COMMIT END (host left)", DssTraceFilters.SIMULATION_INFO);
                    /// The missing commit has arrived, so we can continue the simulation
                    this.waitingForCommit = false;
                    /// Compute the scheduled time for the next frame
                    int nextFrameStartTime = this.currentRound.BaseTime
                                             + (this.currentRound.CurrentFrameIndex + 1) * this.currentRound.TargetFrameTime;
                    SendCommit();
                    SwapRounds();
                    /// Schedule the next frame.
                    SetNextFrameExecutionTime(Math.Max(nextFrameStartTime, DssRoot.Time));
                }
                else if (this.waitingForCommit && !this.nextRound.IsCommitted)
                {
                    /// Cannot continue with the next round --> notify the client module and exit the event loop
                    NotifyClientAboutLeavingGuests(this.nextRound);
                    NotifyClientAboutLeavingGuests(this.nextNextRound);
                    NotifyClientAboutLeavingGuests(this.nextNextNextRound);
                    this.root.SimulatorIface.HostLeftDssDuringSim();
                    this.root.EventQueue.ExitEventLoop();
                }
                this.hostLeft = true;
            }

            return(true);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// The starting function of the searcher thread.
        /// </summary>
        private void SearchProc()
        {
            while (!this.searchFinished.WaitOne(NetworkingSystemConstants.LOBBY_INFO_RECEIVE_FREQUENCY))
            {
                /// Read an RCPackage from the network.
                IPAddress sender = IPAddress.Any;
                RCPackage announcementPackage = ReadPackage_i(ref sender);
                while (announcementPackage != null)
                {
                    if (announcementPackage.PackageType == RCPackageType.CUSTOM_DATA_PACKAGE)
                    {
                        if (announcementPackage.PackageFormat.ID == Network.FORMAT_LOBBY_INFO)
                        {
                            /// Try to create a LobbyInfo object from the package.
                            LobbyInfo info = LobbyInfo.FromRCPackage(announcementPackage);
                            if (info != null && info.ID != Guid.Empty)
                            {
                                info.IPAddress = sender.ToString();
                                /// Search in the local registry.
                                if (this.collectedInfos.ContainsKey(info.ID) && this.timers.ContainsKey(info.ID))
                                {
                                    /// If found we check if it has been changed since last check.
                                    bool changed = this.collectedInfos[info.ID].IPAddress.CompareTo(info.IPAddress) != 0 ||
                                                   this.collectedInfos[info.ID].PortNumber != info.PortNumber;

                                    /// Check for differences in the custom data.
                                    if (info.CustomData != null)
                                    {
                                        if (this.collectedInfos[info.ID].CustomData != null)
                                        {
                                            if (!RCPackage.IsEqual(this.collectedInfos[info.ID].CustomData, info.CustomData))
                                            {
                                                changed = true;
                                            }
                                        }
                                        else
                                        {
                                            /// Custom data appeared.
                                            changed = true;
                                        }
                                    }
                                    else
                                    {
                                        if (this.collectedInfos[info.ID].CustomData != null)
                                        {
                                            /// Custom data disappeared.
                                            changed = true;
                                        }
                                    }

                                    this.collectedInfos[info.ID] = info;    /// save the info
                                    this.timers[info.ID].Restart();         /// restarts it's timer
                                    /// notify the listener that the lobby has changed
                                    if (changed)
                                    {
                                        this.locator.LobbyChanged(info);
                                    }
                                }
                                else
                                {
                                    /// If not found...
                                    this.collectedInfos.Add(info.ID, info);     /// save the info
                                    this.timers.Add(info.ID, new Stopwatch());  /// create timer for the info
                                    this.timers[info.ID].Start();               /// start timer for the info
                                    /// notify the listener that a new lobby has been found
                                    this.locator.LobbyFound(info);
                                }
                            }
                        }
                        else if (announcementPackage.PackageFormat.ID == Network.FORMAT_LOBBY_INFO_VANISHED)
                        {
                            string idStr = announcementPackage.ReadString(0);
                            Guid   id;
                            if (Guid.TryParse(idStr, out id) && id != Guid.Empty)
                            {
                                /// Search in the local registry.
                                if (this.collectedInfos.ContainsKey(id) && this.timers.ContainsKey(id))
                                {
                                    LobbyInfo vanishedLobby = this.collectedInfos[id];
                                    this.collectedInfos.Remove(id);
                                    this.timers.Remove(id);
                                    this.locator.LobbyVanished(vanishedLobby);
                                }
                            }
                        }
                    }

                    announcementPackage = ReadPackage_i(ref sender);
                } /// end-while

                /// Check the timers.
                List <Guid> removedKeys = new List <Guid>();
                foreach (KeyValuePair <Guid, Stopwatch> timer in this.timers)
                {
                    if (timer.Value.ElapsedMilliseconds > NetworkingSystemConstants.LOBBY_INFO_TIMEOUT)
                    {
                        removedKeys.Add(timer.Key);
                    }
                }
                foreach (Guid key in removedKeys)
                {
                    LobbyInfo vanishedLobby = this.collectedInfos[key];
                    this.collectedInfos.Remove(key);
                    this.timers.Remove(key);
                    this.locator.LobbyVanished(vanishedLobby);
                }
            }
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Called when a control packages arrived from the host during setup stage.
 /// </summary>
 /// <param name="package">The arrived control package.</param>
 public void SetupStageCtrlPackage(RCPackage package)
 {
     if (this.sm.CurrentState == this.WaitingConnectionACK)
     {
         if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_ACK)
         {
             int otherMajor    = package.ReadInt(0);
             int otherMinor    = package.ReadInt(1);
             int otherBuild    = package.ReadInt(2);
             int otherRevision = package.ReadInt(3);
             if (otherMajor >= 0 && otherMinor >= 0 && otherBuild >= 0 && otherRevision >= 0)
             {
                 Version otherVer = new Version(otherMajor, otherMinor, otherBuild, otherRevision);
                 if (DssRoot.IsCompatibleVersion(otherVer))
                 {
                     this.WaitingConnectionACK_WaitingSetupStepRQ.Fire();
                     this.controller.ExecuteFirings();
                     return;
                 }
                 else
                 {
                     TraceManager.WriteAllTrace(string.Format("Incompatible with host version: {0} (RC.DssServices)", otherVer), DssTraceFilters.SETUP_STAGE_ERROR);
                     SetupStageError();
                     return;
                 }
             }
             else
             {
                 TraceManager.WriteAllTrace("Unable to parse version information!", DssTraceFilters.SETUP_STAGE_ERROR);
                 SetupStageError();
                 return;
             }
         } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_ACK)
         else if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REJECT)
         {
             TraceManager.WriteAllTrace(string.Format("Connection request rejected by the host! Reason: {0}", package.ReadString(0)), DssTraceFilters.SETUP_STAGE_ERROR);
             SetupStageError();
             return;
         }
         else
         {
             TraceManager.WriteAllTrace("Unexpected answer from host to connection request!", DssTraceFilters.SETUP_STAGE_ERROR);
             SetupStageError();
             return;
         }
     }
     else if (this.sm.CurrentState == this.WaitingSetupStepRQ)
     {
         if (package.PackageFormat.ID == DssRoot.DSS_LEAVE)
         {
             /// The host left the DSS
             this.guestRoot.SetupIface.HostLeftDss();
             StopTimeouts();
             this.guestRoot.EventQueue.ExitEventLoop();
             return;
         } /// end-if (package.PackageFormat.ID == DssRoot.DSS_LEAVE)
         else if (package.PackageFormat.ID == DssRoot.DSS_CTRL_DROP_GUEST)
         {
             /// The current guest has been dropped out of the DSS by the host.
             this.guestRoot.SetupIface.DroppedByHost();
             StopTimeouts();
             this.guestRoot.EventQueue.ExitEventLoop();
             return;
         } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_DROP_GUEST)
         else if (package.PackageFormat.ID == DssRoot.DSS_CTRL_START_SIMULATION)
         {
             int[]  leftList = null;
             int[]  lostList = null;
             bool[] opFlags  = null;
             if (ParseStartSimPackage(package, out leftList, out lostList, out opFlags))
             {
                 StopTimeouts();
                 CallNotificationMethods(leftList, lostList);
                 this.guestRoot.SetupIface.SimulationStarted();
                 this.opFlagsTmp = opFlags;
                 this.WaitingSetupStepRQ_Simulating.Fire();
                 this.controller.ExecuteFirings();
                 return;
             }
             else
             {
                 SetupStageError();
                 return;
             }
         } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_START_SIMULATION)
         else
         {
             this.guestRoot.Step.IncomingPackage(package);
             if (this.guestRoot.Step.State == SetupStepState.READY)
             {
                 /// Setup step request arrived.
                 this.WaitingSetupStepRQ_SendingSetupStepAW.Fire();
                 this.controller.ExecuteFirings();
                 return;
             }
             else if (this.guestRoot.Step.State == SetupStepState.ERROR)
             {
                 /// Setup step request error.
                 SetupStageError();
                 return;
             }
             else
             {
                 /// Setup step request not finished yet, more packages to wait.
                 return;
             }
         }
     } /// end-if (this.sm.CurrentState == this.WaitingSetupStepRQ)
     else
     {
         /// Go to error state if the package cannot be handled until now.
         SetupStageError();
         return;
     }
 }
Ejemplo n.º 15
0
        /// <summary>
        /// This function is called when a control package arrives at setup stage.
        /// </summary>
        /// <param name="package">The arrived control package.</param>
        public void SetupStageCtrlPackage(RCPackage package)
        {
            bool error = false;

            if (this.sm.CurrentState == this.WaitingConnectionRQ)
            {
                if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REQUEST)
                {
                    RCPackage rejPackage    = null;
                    int       otherMajor    = package.ReadInt(0);
                    int       otherMinor    = package.ReadInt(1);
                    int       otherBuild    = package.ReadInt(2);
                    int       otherRevision = package.ReadInt(3);
                    if (otherMajor >= 0 && otherMinor >= 0 && otherBuild >= 0 && otherRevision >= 0)
                    {
                        Version otherVer = new Version(otherMajor, otherMinor, otherBuild, otherRevision);
                        if (DssRoot.IsCompatibleVersion(otherVer))
                        {
                            /// We send back a DSS_CTRL_CONN_ACK package.
                            RCPackage ackPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_ACK);
                            ackPackage.WriteInt(0, DssRoot.APPLICATION_VERSION.Major);
                            ackPackage.WriteInt(1, DssRoot.APPLICATION_VERSION.Minor);
                            ackPackage.WriteInt(2, DssRoot.APPLICATION_VERSION.Build);
                            ackPackage.WriteInt(3, DssRoot.APPLICATION_VERSION.Revision);

                            this.manager.HostRoot.Lobby.SendControlPackage(ackPackage, this.channel.Index + 1);
                            this.WaitingConnectionRQ_SendingSetupStepRQ.Fire();
                        }
                        else
                        {
                            /// We send back a DSS_CTRL_CONN_REJECT package
                            rejPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REJECT);
                            string reason = string.Format("Incompatible with host version: {0} (RC.DssServices)",
                                                          DssRoot.APPLICATION_VERSION.ToString());
                            rejPackage.WriteString(0, reason);
                            rejPackage.WriteByteArray(1, new byte[0]);
                        }
                    }
                    else
                    {
                        /// We create a DSS_CTRL_CONN_REJECT package
                        rejPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REJECT);
                        rejPackage.WriteString(0, "Unable to parse version information!");
                        rejPackage.WriteByteArray(1, new byte[0]);
                    }


                    /// We send back a DSS_CTRL_CONN_REJECT package if necessary.
                    if (rejPackage != null && rejPackage.IsCommitted)
                    {
                        this.manager.HostRoot.Lobby.SendControlPackage(rejPackage, this.channel.Index + 1);

                        error = true;
                    }
                } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REQUEST)
            }     /// end-if (this.sm.CurrentState == this.WaitingConnectionRQ)
            else if (this.sm.CurrentState == this.WaitingSetupStepAW)
            {
                if (package.PackageFormat.ID == DssRoot.DSS_LEAVE)
                {
                    string leaveReason = package.ReadString(0);
                    string trcMsg      = string.Format("Guest-{0} has left the DSS. Reason: {1}",
                                                       this.channel.Index,
                                                       leaveReason.Length != 0 ? leaveReason : "-");
                    TraceManager.WriteAllTrace(trcMsg, DssTraceFilters.SETUP_STAGE_INFO);
                    this.WaitingSetupStepAW_Inactive.Fire();
                    this.channel.GuestLeaveSetupStage();
                } /// end-if (package.PackageFormat.ID == DssRoot.DSS_LEAVE)
                else
                {
                    SetupStep currentStep = this.manager.HostRoot.GetStep(this.channel.Index);
                    currentStep.IncomingPackage(package);
                    if (currentStep.State == SetupStepState.READY)
                    {
                        /// Setup step answer arrived.
                        this.WaitingSetupStepAW_SendingSetupStepRQ.Fire();
                    }
                    else if (currentStep.State == SetupStepState.ERROR)
                    {
                        /// Setup step answer error.
                        error = true;
                    }
                    else
                    {
                        /// Setup step answer not finished yet, more packages to wait.
                    }
                }
            } /// end-if (this.sm.CurrentState == this.WaitingSetupStepAW)

            if (error)
            {
                /// Go to error state if the package cannot be handled until now.
                SetupStageError();
                this.channel.SetupStageError();
                return;
            }
        }