Beispiel #1
0
        /// <see cref="ITrace.WriteJoin"/>
        public void WriteJoin(RCThread runningThread, RCThread waitingThread)
        {
            if (runningThread == null)
            {
                throw new ArgumentNullException("runningThread");
            }
            if (waitingThread == null)
            {
                throw new ArgumentNullException("waitingThread");
            }

            RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_JOIN_FORMAT);

            packageToWrite.WriteInt(0, runningThread.WrappedThread.ManagedThreadId);
            packageToWrite.WriteString(1, runningThread.Name);
            packageToWrite.WriteInt(2, waitingThread.WrappedThread.ManagedThreadId);
            packageToWrite.WriteString(3, waitingThread.Name);
            packageToWrite.WriteLong(4, timer.ElapsedMilliseconds);

            byte[] buffer = new byte[packageToWrite.PackageLength];
            packageToWrite.WritePackageToBuffer(buffer, 0);

            this.outputWriter.Write(buffer);
            this.outputWriter.Flush();
            this.outputStream.Flush();
        }
Beispiel #2
0
        /// <see cref="ITrace.WriteFork"/>
        public void WriteFork(RCThread newThread, RCThread parentThread)
        {
            if (newThread == null)
            {
                throw new ArgumentNullException("newThread");
            }
            if (parentThread == null)
            {
                throw new ArgumentNullException("parentThread");
            }

            RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_FORK_FORMAT);

            packageToWrite.WriteInt(0, newThread.WrappedThread.ManagedThreadId);
            packageToWrite.WriteString(1, newThread.Name);
            packageToWrite.WriteInt(2, parentThread.WrappedThread.ManagedThreadId);
            packageToWrite.WriteString(3, parentThread.Name);
            packageToWrite.WriteLong(4, timer.ElapsedMilliseconds);

            byte[] buffer = new byte[packageToWrite.PackageLength];
            packageToWrite.WritePackageToBuffer(buffer, 0);

            this.outputWriter.Write(buffer);
            this.outputWriter.Flush();
            this.outputStream.Flush();
        }
Beispiel #3
0
        /// <summary>
        /// Creates an RCPackage from this command.
        /// </summary>
        /// <returns>The created RCPackage.</returns>
        public RCPackage ToPackage()
        {
            RCPackage package = RCPackage.CreateCustomDataPackage(RCCommand.COMMAND_PACKAGEFORMAT);

            package.WriteString(0, this.commandType ?? string.Empty);
            package.WriteIntArray(1, this.recipientEntities);
            package.WriteInt(2, this.targetPosition != RCNumVector.Undefined ? this.targetPosition.X.Bits : -1);
            package.WriteInt(3, this.targetPosition != RCNumVector.Undefined ? this.targetPosition.Y.Bits : -1);
            package.WriteInt(4, this.targetEntity);
            package.WriteString(5, this.parameter ?? string.Empty);
            return(package);
        }
Beispiel #4
0
        /// <summary>
        /// Called when we have successfully connected to the lobby.
        /// </summary>
        public void LobbyIsRunning()
        {
            /// We send a DSS_CTRL_CONN_REQUEST package.
            RCPackage reqPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REQUEST);

            reqPackage.WriteInt(0, DssRoot.APPLICATION_VERSION.Major);
            reqPackage.WriteInt(1, DssRoot.APPLICATION_VERSION.Minor);
            reqPackage.WriteInt(2, DssRoot.APPLICATION_VERSION.Build);
            reqPackage.WriteInt(3, DssRoot.APPLICATION_VERSION.Revision);
            this.guestRoot.Lobby.SendControlPackage(reqPackage);

            /// Then we fire the corresponding trigger at the session state machine.
            this.Start_WaitingConnectionACK.Fire();
            this.controller.ExecuteFirings();
        }
Beispiel #5
0
        /// <see cref="ITrace.WriteLine"/>
        public void WriteLine(object obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            string strToWrite = obj.ToString();

            if (strToWrite == null)
            {
                strToWrite = string.Empty;
            }

            RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_EVENT_FORMAT);

            packageToWrite.WriteInt(0, RCThread.CurrentThread.WrappedThread.ManagedThreadId);
            packageToWrite.WriteString(1, RCThread.CurrentThread.Name);
            packageToWrite.WriteLong(2, timer.ElapsedMilliseconds);
            packageToWrite.WriteString(3, strToWrite);

            byte[] buffer = new byte[packageToWrite.PackageLength];
            packageToWrite.WritePackageToBuffer(buffer, 0);

            this.outputWriter.Write(buffer);
            this.outputWriter.Flush();
            this.outputStream.Flush();
        }
Beispiel #6
0
        /// <see cref="ITrace.WriteLine"/>
        public void WriteException(Exception ex, bool isFatal)
        {
            if (ex == null)
            {
                throw new ArgumentNullException("ex");
            }

            string strToWrite = ex.ToString();

            if (strToWrite == null)
            {
                strToWrite = string.Empty;
            }

            RCPackage packageToWrite = RCPackage.CreateCustomDataPackage(RCL_EXCEPTION_FORMAT);

            packageToWrite.WriteInt(0, RCThread.CurrentThread.WrappedThread.ManagedThreadId);
            packageToWrite.WriteString(1, RCThread.CurrentThread.Name);
            packageToWrite.WriteLong(2, timer.ElapsedMilliseconds);
            packageToWrite.WriteByte(3, isFatal ? (byte)0x01 : (byte)0x00);
            packageToWrite.WriteString(4, strToWrite);

            byte[] buffer = new byte[packageToWrite.PackageLength];
            packageToWrite.WritePackageToBuffer(buffer, 0);

            this.outputWriter.Write(buffer);
            this.outputWriter.Flush();
            this.outputStream.Flush();
        }
        /// <summary>
        /// Sends a commit for this.nextNextRound to the lobby.
        /// </summary>
        /// <remarks>
        /// Call this function only if this.currentRound has been finished.
        /// </remarks>
        private void SendCommit()
        {
            if (!this.initialized)
            {
                throw new DssException("DssSimulationMgr is uninitialized!");
            }
            if (this.currentRound.StepNextFrame())
            {
                throw new DssException("DssSimulationMgr.SendCommit() denied!");
            }

            if (!this.hostLeft)
            {
                byte[] stateHash  = this.root.SimulatorIface.StateHash;
                int    highestAPT = this.HighestAPT;

                /// Generate a ticket for the commit.
                int ticket = -1;
                do
                {
                    ticket = RandomService.DefaultGenerator.Next();
                } while (this.commitAwMonitors.ContainsKey(ticket));

                /// Create the commit package.
                RCPackage commitPackage = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_COMMIT);
                commitPackage.WriteShort(0, (short)this.aftCalculator.Average);
                commitPackage.WriteShort(1, (short)highestAPT);           /// The highest measured APT
                commitPackage.WriteInt(2, this.nextNextRound.RoundIndex); /// Round index of the commit
                commitPackage.WriteInt(3, ticket);                        /// Commit answer ticket
                commitPackage.WriteByteArray(4, stateHash != null ? stateHash : new byte[0] {
                });                                                       /// State-hash value

                /// Send the commit package to the lobby.
                this.root.LobbyIface.SendPackage(commitPackage);

                RegisterCommitMonitor(ticket);

                TraceManager.WriteAllTrace(string.Format("Self commit round {0}", this.nextNextRound.RoundIndex), DssTraceFilters.SIMULATION_INFO);
                if (!this.nextNextRound.Commit(this.root.IdOfThisPeer, this.aftCalculator.Average, highestAPT, stateHash))
                {
                    SimulationStageError(string.Format("Commit of round-{0} failed!", this.nextNextRound.RoundIndex),
                                         new byte[0] {
                    });
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Creates the header package of the given map.
        /// </summary>
        /// <param name="map">Reference to the map.</param>
        /// <returns>The data package that contains the header of the given map.</returns>
        private RCPackage CreateMapHeaderPackage(IMapAccess map)
        {
            RCPackage mapHeader  = RCPackage.CreateCustomDataPackage(MapFileFormat.MAP_HEADER);
            Version   appVersion = new Version(ConstantsTable.Get <string>("RC.App.Version"));

            mapHeader.WriteInt(0, appVersion.Major);
            mapHeader.WriteInt(1, appVersion.Minor);
            mapHeader.WriteInt(2, appVersion.Build);
            mapHeader.WriteInt(3, appVersion.Revision);
            mapHeader.WriteString(4, map.MapName);
            mapHeader.WriteString(5, map.Tileset.Name);
            mapHeader.WriteShort(6, (short)map.Size.X);
            mapHeader.WriteShort(7, (short)map.Size.Y);
            mapHeader.WriteByte(8, (byte)8); // TODO: get the maximum number of players
            mapHeader.WriteIntArray(9, new int[0] {
            });                              // TODO: get checksum values of the map
            return(mapHeader);
        }
Beispiel #9
0
        /// <see cref="IScenarioLoader.SaveScenario"/>
        public byte[] SaveScenario(Scenario scenario)
        {
            if (scenario == null)
            {
                throw new ArgumentNullException("scenario");
            }

            /// Create the packages that describes the entities of the scenario.
            List <RCPackage> entityPackages = new List <RCPackage>();
            int retArrayLength = 0;

            foreach (MineralField mineralField in scenario.GetAllElements <MineralField>())
            {
                RCIntVector lastKnownQuadCoords = mineralField.MapObject.QuadraticPosition.Location;
                RCPackage   mineralFieldPackage = RCPackage.CreateCustomDataPackage(ScenarioFileFormat.MINERAL_FIELD);
                mineralFieldPackage.WriteShort(0, (short)lastKnownQuadCoords.X);
                mineralFieldPackage.WriteShort(1, (short)lastKnownQuadCoords.Y);
                mineralFieldPackage.WriteInt(2, mineralField.ResourceAmount.Read());
                entityPackages.Add(mineralFieldPackage);
                retArrayLength += mineralFieldPackage.PackageLength;
            }
            foreach (VespeneGeyser vespeneGeyser in scenario.GetAllElements <VespeneGeyser>())
            {
                RCIntVector lastKnownQuadCoords  = vespeneGeyser.MapObject.QuadraticPosition.Location;
                RCPackage   vespeneGeyserPackage = RCPackage.CreateCustomDataPackage(ScenarioFileFormat.VESPENE_GEYSER);
                vespeneGeyserPackage.WriteShort(0, (short)lastKnownQuadCoords.X);
                vespeneGeyserPackage.WriteShort(1, (short)lastKnownQuadCoords.Y);
                vespeneGeyserPackage.WriteInt(2, vespeneGeyser.ResourceAmount.Read());
                entityPackages.Add(vespeneGeyserPackage);
                retArrayLength += vespeneGeyserPackage.PackageLength;
            }
            foreach (StartLocation startLocation in scenario.GetAllElements <StartLocation>())
            {
                RCIntVector lastKnownQuadCoords  = startLocation.MapObject.QuadraticPosition.Location;
                RCPackage   startLocationPackage = RCPackage.CreateCustomDataPackage(ScenarioFileFormat.START_LOCATION);
                startLocationPackage.WriteShort(0, (short)lastKnownQuadCoords.X);
                startLocationPackage.WriteShort(1, (short)lastKnownQuadCoords.Y);
                startLocationPackage.WriteByte(2, (byte)startLocation.PlayerIndex);
                entityPackages.Add(startLocationPackage);
                retArrayLength += startLocationPackage.PackageLength;
            }

            /// Write the packages into the returned byte array.
            byte[] retArray = new byte[retArrayLength];
            int    offset   = 0;

            foreach (RCPackage package in entityPackages)
            {
                offset += package.WritePackageToBuffer(retArray, offset);
            }

            return(retArray);
        }
        /// <summary>
        /// Internal function to timestamp and send the given commands to the lobby.
        /// </summary>
        /// <param name="cmds">The list of the commands to send.</param>
        private void SendCommandsToLobby(RCPackage[] cmds)
        {
            if (!this.initialized)
            {
                throw new DssException("DssSimulationMgr is uninitialized!");
            }
            if (cmds != null && cmds.Length != 0)
            {
                /// Compute the length of the buffer needed for sending the commands as a byte sequence
                int bufferLength = 0;
                for (int i = 0; i < cmds.Length; i++)
                {
                    if (cmds[i] != null && cmds[i].IsCommitted && cmds[i].PackageType == RCPackageType.CUSTOM_DATA_PACKAGE &&
                        !DssRoot.IsInternalFormat(cmds[i].PackageFormat))
                    {
                        bufferLength += cmds[i].PackageLength;
                    }
                    else
                    {
                        throw new DssException("Unexpected command from the client module!");
                    }
                }

                /// Create the buffer and write the commands into this buffer
                byte[] cmdBuffer = new byte[bufferLength];
                int    offset    = 0;
                for (int i = 0; i < cmds.Length; i++)
                {
                    offset += cmds[i].WritePackageToBuffer(cmdBuffer, offset);
                }

                /// Create the DSS_COMMAND package and send it to the lobby
                RCPackage cmdPackage = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_COMMAND);
                cmdPackage.WriteInt(0, this.nextNextRound.RoundIndex);       /// Round index of the command
                cmdPackage.WriteInt(1, this.currentRound.CurrentFrameIndex); /// Frame index of the command
                cmdPackage.WriteByteArray(2, cmdBuffer);                     /// The command list

                this.root.LobbyIface.SendPackage(cmdPackage);                /// Send the command package to the lobby
            }
        }
        /// <summary>
        /// Registers the given commit arrived from the given operator.
        /// </summary>
        /// <param name="commit">The arrived commit package.</param>
        /// <param name="senderID">The sender operator.</param>
        /// <returns>True in case of success, false otherwise.</returns>
        public bool RegisterCommit(RCPackage commit, 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 (commit == null || !commit.IsCommitted)
            {
                throw new ArgumentException("commit");
            }
            if (senderID == this.root.IdOfThisPeer)
            {
                throw new DssException("Unexpected commit sender!");
            }
            if (senderID < 0 || senderID >= this.root.OpCount)
            {
                throw new ArgumentException("senderID");
            }

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

            short senderAFT = commit.ReadShort(0);
            short senderAPT = commit.ReadShort(1);
            int   roundIdx  = commit.ReadInt(2);
            int   ticket    = commit.ReadInt(3);

            byte[] stateHash = commit.ReadByteArray(4);

            if (senderAFT < 0)
            {
                return(false);
            }
            if (senderAPT < 0)
            {
                return(false);
            }
            if (stateHash == null)
            {
                return(false);
            }

            bool success = false;

            if (roundIdx == this.nextRound.RoundIndex)
            {
                success = this.nextRound.Commit(senderID, senderAFT, senderAPT, stateHash);
                if (this.waitingForCommit && this.nextRound.IsCommitted)
                {
                    TraceManager.WriteAllTrace("WAITING FOR COMMIT END", 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 (roundIdx == this.nextNextRound.RoundIndex)
            {
                success = this.nextNextRound.Commit(senderID, senderAFT, senderAPT, stateHash);
            }
            else
            {
                TraceManager.WriteAllTrace(string.Format("RoundIdx mismatch! RoundIdx: {0}", roundIdx), DssTraceFilters.SIMULATION_ERROR);
            }

            if (success)
            {
                /// Create the answer for the commit and send it back to the sender.
                RCPackage commitAw = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_COMMIT_ANSWER);
                commitAw.WriteInt(0, ticket);
                this.root.LobbyIface.SendPackage(commitAw, new int[1] {
                    senderID
                });
            }
            return(success);
        }
        /// <summary>
        /// Resets the state of the DssSimulationMgr. Call this function every time you start a simulation stage.
        /// </summary>
        /// <param name="opFlags">
        /// The current operator flag array. See the comment at this.operatorFlags for more information.
        /// </param>
        public void Reset(bool[] opFlags)
        {
            if (opFlags == null)
            {
                throw new ArgumentNullException("opFlags");
            }
            if (opFlags.Length != this.root.OpCount)
            {
                throw new ArgumentException("Array length mismatch.", "opFlags");
            }

            this.aftCalculator = new AverageCalculator(DssConstants.AVG_CALC_VECTOR_LENGTH,
                                                       DssConstants.INITIAL_AFT);
            this.aptCalculators = new AverageCalculator[this.root.OpCount];
            for (int i = 0; i < this.aptCalculators.Length; i++)
            {
                this.aptCalculators[i] = new AverageCalculator(DssConstants.AVG_CALC_VECTOR_LENGTH,
                                                               DssConstants.INITIAL_APT);
            }

            if (this.commitAwTimeouts != null)
            {
                foreach (KeyValuePair <AlarmClock, CommitMonitor> item in this.commitAwTimeouts)
                {
                    item.Key.Cancel();
                }
            }
            this.commitAwMonitors = new Dictionary <int, CommitMonitor>();
            this.commitAwTimeouts = new Dictionary <AlarmClock, CommitMonitor>();

            StopCommitTimeoutClock();
            StopSimulationFrameClock();

            this.operatorFlags = opFlags;

            this.currentRound = new SimulationRound(this.operatorFlags);
            this.currentRound.Reset(true, 0);
            this.currentRound.ComputeSpeedControl();
            this.nextRound = new SimulationRound(this.operatorFlags);
            this.nextRound.Reset(false, 1);
            this.nextNextRound = new SimulationRound(this.operatorFlags);
            this.nextNextRound.Reset(false, 2);
            this.nextNextNextRound = new SimulationRound(this.operatorFlags);
            this.nextNextNextRound.Reset(false, 3);
            this.waitingForCommit = false;

            this.initialized = true;
            this.hostLeft    = false;

            int ticket = RandomService.DefaultGenerator.Next();

            byte[] stateHash  = this.root.SimulatorIface.StateHash;
            int    highestAPT = this.HighestAPT;

            this.commitTimeoutClock = this.root.AlarmClkMgr.SetAlarmClock(DssRoot.Time + DssConstants.COMMIT_TIMEOUT,
                                                                          this.CommitTimeout);

            /// Create the first commit package.
            RCPackage commitPackage = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_COMMIT);

            commitPackage.WriteShort(0, (short)this.aftCalculator.Average);
            commitPackage.WriteShort(1, (short)highestAPT); /// The highest measured APT
            commitPackage.WriteInt(2, 1);                   /// Round index of the commit is 1 (next round is committed)
            commitPackage.WriteInt(3, ticket);              /// Commit answer ticket
            commitPackage.WriteByteArray(4, stateHash != null ? stateHash : new byte[0] {
            });                                             /// State-hash value

            /// Send the commit package to the lobby.
            this.root.LobbyIface.SendPackage(commitPackage);

            RegisterCommitMonitor(ticket);

            TraceManager.WriteAllTrace(string.Format("Self commit round {0}", this.nextRound.RoundIndex), DssTraceFilters.SIMULATION_INFO);
            if (!this.nextRound.Commit(this.root.IdOfThisPeer, this.aftCalculator.Average, highestAPT, stateHash))
            {
                SimulationStageError(string.Format("Commit of round-{0} failed!", this.nextRound.RoundIndex),
                                     new byte[0] {
                });
            }
        }
Beispiel #13
0
        /// <summary>
        /// Processes the actions arrived from the UI.
        /// </summary>
        private DssSetupResult ProcessUiActions(IDssGuestChannel[] channelsToGuests)
        {
            PlayerColor currentColor     = this.simulator.GetPlayer(0).Color;
            PlayerColor newColor         = PlayerColor.White;
            bool        newColorSelected = false;

            UiActionType[] uiActions    = null;
            int[]          firstParams  = null;
            int[]          secondParams = null;
            this.ActionQueue.GetAllActions(out uiActions, out firstParams, out secondParams);

            for (int i = 0; i < uiActions.Length; i++)
            {
                if (uiActions[i] == UiActionType.CloseBtnPressed)
                {
                    int opID = firstParams[i];
                    if (channelsToGuests[opID - 1].ChannelState == DssChannelState.GUEST_CONNECTED)
                    {
                        if (this.simulator.GetPlayer(opID).IsActive)
                        {
                            this.simulator.GetPlayer(opID).Deactivate();
                        }
                        /// Drop the guest if it is connected to the channel...
                        channelsToGuests[opID - 1].DropGuest(false);
                    }
                    else
                    {
                        /// otherwise close the channel.
                        channelsToGuests[opID - 1].CloseChannel();
                    }

                    /// and notify the UI.
                    this.uiCallMarshal.SetGuestControlStatus(opID - 1, GuestControlStatus.HostSideClosed);
                }
                else if (uiActions[i] == UiActionType.OpenBtnPressed)
                {
                    int opID = firstParams[i];
                    if (channelsToGuests[opID - 1].ChannelState == DssChannelState.GUEST_CONNECTED)
                    {
                        if (this.simulator.GetPlayer(opID).IsActive)
                        {
                            this.simulator.GetPlayer(opID).Deactivate();
                        }
                        /// Drop the guest if it is connected to the channel...
                        channelsToGuests[opID - 1].DropGuest(true);
                    }
                    else
                    {
                        /// otherwise open the channel.
                        channelsToGuests[opID - 1].OpenChannel();
                    }

                    /// and notify the UI.
                    this.uiCallMarshal.SetGuestControlStatus(opID - 1, GuestControlStatus.HostSideOpened);
                }
                else if (uiActions[i] == UiActionType.NewColorSelected)
                {
                    int opID = firstParams[i];
                    if (opID == 0)
                    {
                        newColor         = (PlayerColor)secondParams[i];
                        newColorSelected = true;

                        for (int j = 0; j < channelsToGuests.Length; j++)
                        {
                            if (channelsToGuests[j].ChannelState == DssChannelState.GUEST_CONNECTED)
                            {
                                RCPackage colorChgNotif = RCPackage.CreateNetworkControlPackage(TestClientMessages.COLOR_CHANGE_NOTIFICATION);
                                colorChgNotif.WriteInt(0, opID);
                                colorChgNotif.WriteByte(1, (byte)newColor);
                                this.rqs[j].Add(colorChgNotif);
                            }
                        }
                    }

                    /// Notify the UI
                    //this.uiCallMarshal.SetHostControlStatus(HostControlStatus.AccessGranted);
                }
                else if (uiActions[i] == UiActionType.StartSimBtnPressed)
                {
                    if (newColorSelected)
                    {
                        /// Set back the color in the combobox
                        this.uiCallMarshal.SelectNewHostColor(currentColor);
                    }
                    return(DssSetupResult.START_SIMULATION);
                }
                else if (uiActions[i] == UiActionType.LeaveBtnPressed)
                {
                    /// TODO: notify the UI
                    return(DssSetupResult.LEAVE_DSS);
                }
                else
                {
                    /// Otherwise ignore the action
                }
            }

            if (newColorSelected)
            {
                /// Save the selected new color
                this.simulator.GetPlayer(0).Color = newColor;
            }

            this.uiCallMarshal.SetHostControlStatus(HostControlStatus.AccessGranted);
            return(DssSetupResult.CONTINUE_SETUP);
        }
Beispiel #14
0
        /// <summary>
        /// Processes the channel events and incoming answers arrived from the guests.
        /// </summary>
        private void ProcessGuestChannels(IDssGuestChannel[] channelsToGuests)
        {
            RCSet <int> newGuests = new RCSet <int>();

            /// First collect the new guests
            for (int i = 0; i < this.previousChannelStates.Length; i++)
            {
                if (this.previousChannelStates[i] != channelsToGuests[i].ChannelState)
                {
                    /// The state of a channel has changed
                    this.previousChannelStates[i] = channelsToGuests[i].ChannelState;
                    if (channelsToGuests[i].ChannelState == DssChannelState.CHANNEL_OPENED)
                    {
                        this.uiCallMarshal.SetGuestControlStatus(i, GuestControlStatus.HostSideOpened);
                    }
                    else if (channelsToGuests[i].ChannelState == DssChannelState.CHANNEL_CLOSED)
                    {
                        this.uiCallMarshal.SetGuestControlStatus(i, GuestControlStatus.HostSideClosed);
                    }
                    else if (channelsToGuests[i].ChannelState == DssChannelState.GUEST_CONNECTED)
                    {
                        this.uiCallMarshal.SetGuestControlStatus(i, GuestControlStatus.HostSideEngaged);
                        this.simulator.GetPlayer(i + 1).Activate();
                        newGuests.Add(i);
                    }
                }
            }

            /// Then process the answers of any other guests.
            for (int i = 0; i < this.previousChannelStates.Length; i++)
            {
                if (!newGuests.Contains(i) && channelsToGuests[i].ChannelState == DssChannelState.GUEST_CONNECTED)
                {
                    /// If a guest is connected to this channel, process it's answer.
                    RCPackage[] answerFromGuest = channelsToGuests[i].AnswerFromGuest;
                    for (int j = 0; j < answerFromGuest.Length; j++)
                    {
                        if (answerFromGuest[j].PackageFormat.ID == TestClientMessages.COLOR_CHANGE_REQUEST)
                        {
                            /// Color change request arrived from the guest.
                            PlayerColor newColor = (PlayerColor)answerFromGuest[j].ReadByte(0);
                            this.simulator.GetPlayer(i + 1).Color = newColor;

                            /// Notify the other connected guests.
                            for (int k = 0; k < channelsToGuests.Length; k++)
                            {
                                if (!newGuests.Contains(k) && i != k && channelsToGuests[k].ChannelState == DssChannelState.GUEST_CONNECTED)
                                {
                                    RCPackage colorChgNotif =
                                        RCPackage.CreateNetworkControlPackage(TestClientMessages.COLOR_CHANGE_NOTIFICATION);
                                    colorChgNotif.WriteInt(0, i + 1);
                                    colorChgNotif.WriteByte(1, (byte)newColor);
                                    this.rqs[k].Add(colorChgNotif);
                                }
                            }

                            /// Notify the UI
                            this.uiCallMarshal.SelectNewGuestColor(i, newColor);
                            break;  /// Ignore the remaining messages
                        }
                    }
                }
            }

            /// Send a reset message to the new guests
            foreach (int newGuestIdx in newGuests)
            {
                byte[] colors  = new byte[this.simulator.MaxNumOfPlayers];
                int[]  xCoords = new int[this.simulator.MaxNumOfPlayers];
                int[]  yCoords = new int[this.simulator.MaxNumOfPlayers];
                for (int j = 0; j < colors.Length; j++)
                {
                    colors[j]  = (byte)this.simulator.GetPlayer(j).Color;
                    xCoords[j] = this.simulator.GetPlayer(j).Position.X;
                    yCoords[j] = this.simulator.GetPlayer(j).Position.Y;
                }
                RCPackage reset = RCPackage.CreateNetworkControlPackage(TestClientMessages.RESET);
                reset.WriteByteArray(0, colors);
                reset.WriteIntArray(1, xCoords);
                reset.WriteIntArray(2, yCoords);
                this.rqs[newGuestIdx].Add(reset);
            }
        }
Beispiel #15
0
        public static RCPackage GenerateRandomPackage()
        {
            int       rndType   = rnd.Next(0, 3);
            int       rndFormat = rnd.Next(0, 3);
            RCPackage retPack   = null;

            if (rndType == 0)
            {
                retPack = RCPackage.CreateNetworkPingPackage(); return(retPack);
            }
            else if (rndType == 1)
            {
                retPack = RCPackage.CreateCustomDataPackage(rndFormat);
            }
            else if (rndType == 2)
            {
                retPack = RCPackage.CreateNetworkCustomPackage(rndFormat);
            }

            RCPackageFormat format = RCPackageFormat.GetPackageFormat(rndFormat);

            for (int i = 0; i < format.NumOfFields; i++)
            {
                RCPackageFieldType datatype = format.GetFieldType(i);
                if (datatype == RCPackageFieldType.BYTE)
                {
                    retPack.WriteByte(i, (byte)rnd.Next(byte.MinValue, byte.MaxValue));
                }
                else if (datatype == RCPackageFieldType.SHORT)
                {
                    retPack.WriteShort(i, (short)rnd.Next(short.MinValue, short.MaxValue));
                }
                else if (datatype == RCPackageFieldType.INT)
                {
                    retPack.WriteInt(i, (int)rnd.Next(int.MinValue, int.MaxValue));
                }
                else if (datatype == RCPackageFieldType.LONG)
                {
                    retPack.WriteLong(i, (long)rnd.Next(int.MinValue, int.MaxValue));
                }
                else if (datatype == RCPackageFieldType.STRING)
                {
                    int strIdx = rnd.Next(0, 10);
                    retPack.WriteString(i, strCollection[strIdx]);
                }
                else if (datatype == RCPackageFieldType.BYTE_ARRAY)
                {
                    int    arrLen = rnd.Next(0, 10);
                    byte[] arr    = new byte[arrLen];
                    rnd.NextBytes(arr);
                    retPack.WriteByteArray(i, arr);
                }
                else if (datatype == RCPackageFieldType.SHORT_ARRAY)
                {
                    int     arrLen = rnd.Next(0, 10);
                    short[] arr    = new short[arrLen];
                    for (int j = 0; j < arrLen; ++j)
                    {
                        arr[j] = (short)rnd.Next(short.MinValue, short.MaxValue);
                    }
                    retPack.WriteShortArray(i, arr);
                }
                else if (datatype == RCPackageFieldType.INT_ARRAY)
                {
                    int   arrLen = rnd.Next(0, 10);
                    int[] arr    = new int[arrLen];
                    for (int j = 0; j < arrLen; ++j)
                    {
                        arr[j] = (int)rnd.Next(int.MinValue, int.MaxValue);
                    }
                    retPack.WriteIntArray(i, arr);
                }
                else if (datatype == RCPackageFieldType.LONG_ARRAY)
                {
                    int    arrLen = rnd.Next(0, 10);
                    long[] arr    = new long[arrLen];
                    for (int j = 0; j < arrLen; ++j)
                    {
                        arr[j] = (long)rnd.Next(int.MinValue, int.MaxValue);
                    }
                    retPack.WriteLongArray(i, arr);
                }
                else if (datatype == RCPackageFieldType.STRING_ARRAY)
                {
                    int      arrLen = rnd.Next(0, 10);
                    string[] arr    = new string[arrLen];
                    for (int j = 0; j < arrLen; ++j)
                    {
                        int strIdx = rnd.Next(0, 10);
                        arr[j] = strCollection[strIdx];
                    }
                    retPack.WriteStringArray(i, arr);
                }
                else
                {
                    throw new NetworkingSystemException("Unknown datatype");
                }
            }

            return(retPack);
        }
Beispiel #16
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;
            }
        }