Beispiel #1
0
        /// <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);
        }
Beispiel #2
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);
        }
Beispiel #3
0
        /// <summary>
        /// Sends reports about the given line states to all connected clients and to the listener of this server.
        /// </summary>
        private void SendLineStateReports(LobbyLineState[] lineStates)
        {
            for (int i = 0; i < this.connections.Length; i++)
            {
                if (this.connections[i].ConnectionState == LobbyConnectionState.Connected)
                {
                    RCPackage lineStateReport = RCPackage.CreateNetworkControlPackage(Network.FORMAT_LOBBY_LINE_STATE_REPORT);
                    lineStateReport.WriteShort(0, (short)(i + 1));   /// The ID of the client that receives the report.
                    byte[] lineStatesBytes = new byte[lineStates.Length];
                    for (int j = 0; j < lineStatesBytes.Length; j++)
                    {
                        lineStatesBytes[j] = (byte)lineStates[j];
                    }
                    lineStateReport.WriteByteArray(1, lineStatesBytes);     /// The list of the line states on this server.

                    /// Send the package
                    if (!this.connections[i].SendPackage(lineStateReport))
                    {
                        /// In case of error, shutdown the connection and notify the other clients again.
                        this.connections[i].Shutdown();
                        this.connections[i].LineState = LobbyLineState.Opened; /// Keep it opened for other clients.
                        SendLineStateReports();
                    }
                }
            }
            this.listener.LineStateReport(0, lineStates);
        }
        /// <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 #5
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 #6
0
        /// <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>
        /// 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 #8
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);
        }