/// <summary> /// Creates the package that contains the description of the isometric tiles of the given map. /// </summary> /// <param name="map">Reference to the map.</param> /// <returns>The data package that contains the description of the isometric tiles of the given map.</returns> private RCPackage CreateIsoTileListPackage(IMapAccess map) { RCPackage isotileList = RCPackage.CreateCustomDataPackage(MapFileFormat.ISOTILE_LIST); /// Create the terrain type index table. List <string> terrainTypeList = new List <string>(); Dictionary <ITerrainType, int> terrainTypeIndexTable = new Dictionary <ITerrainType, int>(); int terrainTypeIndex = 0; foreach (ITerrainType terrainType in map.Tileset.TerrainTypes) { terrainTypeList.Add(terrainType.Name); terrainTypeIndexTable.Add(terrainType, terrainTypeIndex); terrainTypeIndex++; } isotileList.WriteStringArray(0, terrainTypeList.ToArray()); /// Create the packages of the isometric tiles. RCSet <IIsoTile> processedIsoTiles = new RCSet <IIsoTile>(); List <RCPackage> isotilePackages = new List <RCPackage>(); int isotileInfoLength = 0; for (int row = 0; row < map.Size.Y; row++) { for (int column = 0; column < map.Size.X; column++) { IIsoTile currIsoTile = map.GetQuadTile(new RCIntVector(column, row)).PrimaryIsoTile; if (!processedIsoTiles.Contains(currIsoTile)) { RCPackage isotilePackage = RCPackage.CreateCustomDataPackage(MapFileFormat.ISOTILE); isotilePackage.WriteShort(0, (short)column); isotilePackage.WriteShort(1, (short)row); isotilePackage.WriteByte(2, (byte)terrainTypeIndexTable[currIsoTile.Type.TerrainA]); isotilePackage.WriteByte(3, currIsoTile.Type.TerrainB != null ? (byte)terrainTypeIndexTable[currIsoTile.Type.TerrainB] : (byte)0); isotilePackage.WriteByte(4, (byte)currIsoTile.Type.Combination); isotilePackage.WriteByte(5, (byte)currIsoTile.VariantIdx); isotilePackages.Add(isotilePackage); processedIsoTiles.Add(currIsoTile); isotileInfoLength += isotilePackage.PackageLength; } } } /// Write the isometric tile packages into the final package byte[] isotileInfoBytes = new byte[isotileInfoLength]; int offset = 0; foreach (RCPackage isotilePackage in isotilePackages) { offset += isotilePackage.WritePackageToBuffer(isotileInfoBytes, offset); } isotileList.WriteByteArray(1, isotileInfoBytes); return(isotileList); }
/// <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(); }
public bool ExecuteNextFrame(out RCPackage[] outgoingCmds) { outgoingCmds = null; List <RCPackage> tmpOutgoingCmds = new List <RCPackage>(); 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.UpKeyPressed) { RCPackage upCmd = RCPackage.CreateCustomDataPackage(TestClientMessages.COMMAND); upCmd.WriteByte(0, (byte)PlayerDirection.Up); tmpOutgoingCmds.Add(upCmd); } else if (uiActions[i] == UiActionType.DownKeyPressed) { RCPackage downCmd = RCPackage.CreateCustomDataPackage(TestClientMessages.COMMAND); downCmd.WriteByte(0, (byte)PlayerDirection.Down); tmpOutgoingCmds.Add(downCmd); } else if (uiActions[i] == UiActionType.LeftKeyPressed) { RCPackage leftCmd = RCPackage.CreateCustomDataPackage(TestClientMessages.COMMAND); leftCmd.WriteByte(0, (byte)PlayerDirection.Left); tmpOutgoingCmds.Add(leftCmd); } else if (uiActions[i] == UiActionType.RightKeyPressed) { RCPackage rightCmd = RCPackage.CreateCustomDataPackage(TestClientMessages.COMMAND); rightCmd.WriteByte(0, (byte)PlayerDirection.Right); tmpOutgoingCmds.Add(rightCmd); } else if (uiActions[i] == UiActionType.LeaveBtnPressed) { return(false); } } if (tmpOutgoingCmds.Count > 0) { outgoingCmds = tmpOutgoingCmds.ToArray(); } /// Step simulations and refresh the display this.simulator.MakeStep(); Rectangle refreshedArea; Display.Instance.RenderOneFrame(out refreshedArea); this.uiCallMarshal.RefreshDisplay(); return(true); }
/// <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> /// 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); }
/// <summary> /// Creates the package that contains the description of the terrain objects of the given map. /// </summary> /// <param name="map">Reference to the map.</param> /// <returns>The data package that contains the description of the terrain objects of the given map.</returns> private RCPackage CreateTerrainObjListPackage(IMapAccess map) { RCPackage terrainObjList = RCPackage.CreateCustomDataPackage(MapFileFormat.TERRAINOBJ_LIST); /// Create the terrain object type index table. List <string> terrainObjTypeList = new List <string>(); Dictionary <ITerrainObjectType, int> terrainObjTypeIndexTable = new Dictionary <ITerrainObjectType, int>(); int terrainObjTypeIndex = 0; foreach (ITerrainObjectType terrainObjType in map.Tileset.TerrainObjectTypes) { terrainObjTypeList.Add(terrainObjType.Name); terrainObjTypeIndexTable.Add(terrainObjType, terrainObjTypeIndex); terrainObjTypeIndex++; } terrainObjList.WriteStringArray(0, terrainObjTypeList.ToArray()); /// Create the packages of the terrain objects. List <RCPackage> terrainObjPackages = new List <RCPackage>(); int terrainObjInfoLength = 0; foreach (ITerrainObject terrainObj in map.TerrainObjects) { RCPackage terrainObjPackage = RCPackage.CreateCustomDataPackage(MapFileFormat.TERRAINOBJ); terrainObjPackage.WriteShort(0, (short)terrainObj.MapCoords.X); terrainObjPackage.WriteShort(1, (short)terrainObj.MapCoords.Y); terrainObjPackage.WriteByte(2, (byte)terrainObjTypeIndexTable[terrainObj.Type]); terrainObjPackages.Add(terrainObjPackage); terrainObjInfoLength += terrainObjPackage.PackageLength; } /// Write the terrain object packages into the final package byte[] terrainObjInfoBytes = new byte[terrainObjInfoLength]; int offset = 0; foreach (RCPackage terrainObjPackage in terrainObjPackages) { offset += terrainObjPackage.WritePackageToBuffer(terrainObjInfoBytes, offset); } terrainObjList.WriteByteArray(1, terrainObjInfoBytes); return(terrainObjList); }
/// <summary> /// Processes the actions arrived from the UI. /// </summary> private bool ProcessUiActions(IDssHostChannel channelToHost) { 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.NewColorSelected) { /// Send the request to the host and register that a color selection request is in progress. int opID = firstParams[i]; if (!this.newColorSelected && opID - 1 == channelToHost.GuestIndex) { /// Send the request to the host. PlayerColor newColor = (PlayerColor)secondParams[i]; RCPackage colorChgRq = RCPackage.CreateNetworkControlPackage(TestClientMessages.COLOR_CHANGE_REQUEST); colorChgRq.WriteByte(0, (byte)newColor); this.aw.Add(colorChgRq); /// Register that a color selection request is in progress. this.newColor = newColor; this.newColorSelected = true; } } else if (uiActions[i] == UiActionType.LeaveBtnPressed) { /// TODO: notify the UI return(false); } else { /// Otherwise ignore the action } } return(true); }
/// <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); }