/// <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(); }
/// <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(); }
/// <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); }
/// <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(); }
/// <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(); }
/// <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] { }); } } }
/// <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); }
/// <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] { }); } }
/// <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); }
/// <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); } }
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); }
/// <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; } }