Beispiel #1
0
        /// <summary>
        /// Gets the <see cref="StringId"/> corresponding to a string in a specific set in the list.
        /// </summary>
        /// <param name="set">The set containing the string.</param>
        /// <param name="value">The string to search for.</param>
        /// <param name = "version" > The version of the returned StringID.</param>
        /// <returns>The corresponding string_id, or <see cref="StringId.Invalid"/> if not found.</returns>
        public StringId GetStringId(int set, string value, CacheVersion version = CacheVersion.Halo3Retail)
        {
            var setOffsets = Resolver.GetSetOffsets();

            if (set < 0 || set >= setOffsets.Length)
            {
                throw new IndexOutOfRangeException($"string_id set {set}");
            }

            for (var i = 1; i < Strings.Count; i++)
            {
                if (Strings[i] != value)
                {
                    continue;
                }

                var stringId = GetStringId(i, version);

                if (stringId.Set == 0 || set == stringId.Set)
                {
                    return(stringId);
                }
            }

            return(StringId.Invalid);
        }
Beispiel #2
0
        /// <summary>
        /// Serializes a property.
        /// </summary>
        /// <param name="version"></param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="instance">The object that the property belongs to.</param>
        /// <param name="tagFieldInfo">The field enumerator.</param>
        /// <param name="baseOffset">The base offset of the structure from the start of its block.</param>
        /// <exception cref="System.InvalidOperationException">Offset for property \ + property.Name + \ is outside of its structure</exception>
        private void SerializeProperty(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object instance, TagFieldInfo tagFieldInfo, long baseOffset)
        {
            if (tagFieldInfo.Attribute.Flags.HasFlag(Runtime))
            {
                return;
            }

            object objectValue = tagFieldInfo.GetValue(instance);

            // second condition is a hack to prevent exceptions when encountering cached tags
            if (objectValue != null)
            {
                if (objectValue.GetType() == tagFieldInfo.FieldType || tagFieldInfo.FieldType == typeof(CachedTag))
                {
                    SerializeValue(version, context, tagStream, block,
                                   objectValue, tagFieldInfo.Attribute, tagFieldInfo.FieldType);
                }
                else
                {
                    throw new Exception($"TagFieldInfo.GetValue return type {objectValue.GetType().ToString()} is not the same as the FieldInfo Type {tagFieldInfo.FieldType.ToString()}!");
                }
            }
            else
            {
                SerializeValue(version, context, tagStream, block,
                               objectValue, tagFieldInfo.Attribute, tagFieldInfo.FieldType);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Adds a string to the cache.
        /// </summary>
        /// <param name="str">The string to add.</param>
        /// <param name="version">The cache version of the string id.</param>
        /// <returns>The stringID corresponding to the string that was added.</returns>
        public StringId AddString(string str, CacheVersion version = CacheVersion.Halo3Retail)
        {
            var strIndex = Strings.Count;

            Strings.Add(str);
            return(GetStringId(strIndex, version));
        }
Beispiel #4
0
        public StringTableHaloOnline(CacheVersion version, Stream stream)
        {
            Version = version;

            Resolver = null;

            if (CacheVersionDetection.Compare(Version, CacheVersion.HaloOnline700123) >= 0)
            {
                Resolver = new StringIdResolverMS30();
            }
            else if (CacheVersionDetection.Compare(Version, CacheVersion.HaloOnline498295) >= 0)
            {
                Resolver = new StringIdResolverMS28();
            }
            else
            {
                Resolver = new StringIdResolverMS23();
            }

            if (stream != null && stream.Length != 0)
            {
                Load(stream);
            }
            else
            {
                CreateFromStrings();
            }
        }
Beispiel #5
0
 public override void PostConvert(CacheVersion from, CacheVersion to)
 {
     if (from <= CacheVersion.Halo2Vista && to >= CacheVersion.Halo3Retail)
     {
         ClusterNew = (byte)ClusterOld;
     }
 }
Beispiel #6
0
        /// <summary>
        /// Constructs a new StringID from a length, a set, and an index from specified version.
        /// </summary>
        /// <param name="length">The length of the string.</param>
        /// <param name="set">The set the stringID belongs to.</param>
        /// <param name="index">The index of the stringID within the set.</param>
        /// <param name="version">The version of the cache the stringID is from.</param>
        public StringId(int length, int set, int index, CacheVersion version)
        {
            switch (version)
            {
            case CacheVersion.Halo3ODST:
            case CacheVersion.Halo3Retail:
            case CacheVersion.HaloOnline106708:
                IndexBits  = 16;
                SetBits    = 8;
                LengthBits = 8;
                break;

            case CacheVersion.HaloReach:
                IndexBits  = 17;
                SetBits    = 8;
                LengthBits = 7;
                break;

            default:
                IndexBits  = 16;
                SetBits    = 8;
                LengthBits = 8;
                break;
            }
            var indexMask  = (0x1 << IndexBits) - 1;
            var setMask    = (0x1 << SetBits) - 1;
            var lengthMask = (0x1 << LengthBits) - 1;

            var shiftedLength = ((length & lengthMask) << (IndexBits + SetBits));
            var shiftedSet    = ((set & setMask) << IndexBits);
            var shiftedIndex  = (index & indexMask);

            _value = (uint)(shiftedLength | shiftedSet | shiftedIndex);
        }
Beispiel #7
0
        /// <summary>
        /// Connects a tag index to a tag in another version.
        /// </summary>
        /// <param name="version1">The first version.</param>
        /// <param name="index1">The tag index in the first version.</param>
        /// <param name="version2">The second version.</param>
        /// <param name="index2">The tag index in the second version.</param>
        public void Add(CacheVersion version1, int index1, CacheVersion version2, int index2)
        {
            if (!_versionMaps.TryGetValue(version1, out VersionMap map1))
            {
                map1 = new VersionMap();
                _versionMaps[version1] = map1;
            }
            if (!_versionMaps.TryGetValue(version2, out VersionMap map2))
            {
                map2 = new VersionMap();
                _versionMaps[version2] = map2;
            }

            // Check if the first index is in the map for the first version.
            // If it is, then we'll get a "global index" which can be used to look it up in other versions.
            // If it isn't, then we need to make a new global index for it.
            var globalIndex = map1.GetGlobalTagIndex(index1);

            if (globalIndex < 0)
            {
                globalIndex = _nextGlobalTagIndex;
                _nextGlobalTagIndex++;
                map1.Add(globalIndex, index1);
            }

            // Connect the global index to the second index in the second version
            map2.Add(globalIndex, index2);
        }
Beispiel #8
0
        /// <summary>
        /// Serializes an inline array.
        /// </summary>
        /// <param name="version"></param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="data">The array.</param>
        /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param>
        /// <param name="valueType">The type of the value.</param>
        private void SerializeInlineArray(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, Array data, TagFieldAttribute valueInfo, Type valueType)
        {
            if (valueInfo == null || valueInfo.Length == 0)
            {
                throw new ArgumentException("Cannot serialize an inline array with no count set");
            }

            var elementType = valueType.GetElementType();

            if (data == null)
            {
                data = Array.CreateInstance(elementType, valueInfo.Length);
            }

            if (data == null || data.Length != valueInfo.Length)
            {
                throw new ArgumentException("Array length does not match the fixed count of " + valueInfo.Length);
            }

            // Serialize each element into the current block
            foreach (var element in data)
            {
                SerializeValue(version, context, tagStream, block, element, null, elementType);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Convert to specified Cache Version.
        /// </summary>
        /// <param name="targetVersion"></param>
        public void ConvertBlf(CacheVersion targetVersion)
        {
            switch (Version)
            {
            case CacheVersion.Halo3Retail:
            case CacheVersion.Halo3Beta:
                switch (targetVersion)
                {
                case CacheVersion.Halo3ODST:
                case CacheVersion.HaloOnline106708:
                    ConvertHalo3ToODSTScenarioChunk();
                    Version = targetVersion;
                    if (targetVersion == CacheVersion.HaloOnline106708)
                    {
                        Format = EndianFormat.LittleEndian;
                    }
                    break;

                default:
                    throw new NotImplementedException($"Conversion from Halo 3 to {targetVersion.ToString()} not supported");
                }
                break;

            case CacheVersion.Halo3ODST:
            case CacheVersion.HaloOnline106708:
                if (targetVersion == CacheVersion.HaloOnline106708)
                {
                    Format = EndianFormat.LittleEndian;
                }
                return;

            default:
                throw new NotImplementedException($"Conversion from {Version.ToString()} to {targetVersion.ToString()} not supported");
            }
        }
Beispiel #10
0
        public CacheFile(HaloOnlineCacheContext cacheContext, FileInfo file, CacheVersion version, bool memory)
        {
            CacheContext = cacheContext;
            File         = file;
            Version      = version;
            Deserializer = new TagDeserializer(Version);

            Stream = memory ? new MemoryStream() : (Stream)file.OpenRead();

            if (memory)
            {
                using (var fileStream = file.OpenRead())
                {
                    fileStream.Seek(0, SeekOrigin.Begin);
                    fileStream.CopyTo(Stream);
                }
            }

            Reader = new EndianReader(Stream, EndianFormat.LittleEndian);

            Reader.SeekTo(0);
            if (Reader.ReadTag() == "daeh")
            {
                Reader.Format = EndianFormat.BigEndian;
            }

            Reader.SeekTo(0);
            Header = Deserializer.Deserialize <CacheFileHeader>(new DataSerializationContext(Reader));
        }
Beispiel #11
0
        /// <summary>
        /// Constructs a new StringID from a 32-bit value from specified version.
        /// </summary>
        /// <param name="value">The 32-bit value of the string id.</param>
        /// <param name="version">The cache version of the string id.</param>
        public StringId(uint value, CacheVersion version)
        {
            switch (version)
            {
            case CacheVersion.Halo3ODST:
            case CacheVersion.Halo3Retail:
            case CacheVersion.HaloOnline106708:
                IndexBits  = 16;
                SetBits    = 8;
                LengthBits = 8;
                break;

            case CacheVersion.HaloReach:
                IndexBits  = 17;
                SetBits    = 8;
                LengthBits = 7;
                break;

            default:
                IndexBits  = 16;
                SetBits    = 8;
                LengthBits = 8;
                break;
            }

            _value = value;
        }
Beispiel #12
0
            public TagStructureAttribute GetTagStructureAttribute(Type type, CacheVersion version = CacheVersion.Unknown)
            {
                if (!TagStructureAttributes.TryGetValue(type, out TagStructureAttribute attribute))
                {
                    lock (TagStructureAttributes)
                    {
                        if (!TagStructureAttributes.TryGetValue(type, out attribute))
                        {
                            TagStructureAttributes[type] = attribute = GetStructureAttribute();
                        }
                    }
                }
                return(attribute);

                TagStructureAttribute GetStructureAttribute()
                {
                    // First match against any TagStructureAttributes that have version restrictions
                    var attrib = type.GetCustomAttributes(typeof(TagStructureAttribute), false)
                                 .Cast <TagStructureAttribute>()
                                 .Where(a => a.MinVersion != CacheVersion.Unknown || a.MaxVersion != CacheVersion.Unknown)
                                 .FirstOrDefault(a => CacheVersionDetection.IsBetween(version, a.MinVersion, a.MaxVersion));

                    // If nothing was found, find the first attribute without any version restrictions
                    return(attrib ?? type.GetCustomAttributes(typeof(TagStructureAttribute), false)
                           .Cast <TagStructureAttribute>()
                           .FirstOrDefault(a => a.MinVersion == CacheVersion.Unknown && a.MaxVersion == CacheVersion.Unknown));
                }
            }
Beispiel #13
0
        /// <summary>
        /// Checks if a <see cref="CacheVersion"/> is in Little-Endian or Big-Endian.
        /// </summary>
        /// <param name="version">The <see cref="CacheVersion"/> to check the endianness of.</param>
        /// <returns>True if the <see cref="CacheVersion"/> is Little-Endian, false otherwise.</returns>
        public static bool IsLittleEndian(CacheVersion version)
        {
            switch (version)
            {
            case CacheVersion.Halo3Retail:
            case CacheVersion.Halo3ODST:
            case CacheVersion.HaloReach:
                return(false);

            case CacheVersion.Halo2Xbox:
            case CacheVersion.Halo2Vista:
            case CacheVersion.HaloOnline106708:
            case CacheVersion.HaloOnline235640:
            case CacheVersion.HaloOnline301003:
            case CacheVersion.HaloOnline327043:
            case CacheVersion.HaloOnline372731:
            case CacheVersion.HaloOnline416097:
            case CacheVersion.HaloOnline430475:
            case CacheVersion.HaloOnline454665:
            case CacheVersion.HaloOnline449175:
            case CacheVersion.HaloOnline498295:
            case CacheVersion.HaloOnline530605:
            case CacheVersion.HaloOnline532911:
            case CacheVersion.HaloOnline554482:
            case CacheVersion.HaloOnline571627:
            case CacheVersion.HaloOnline700123:
            case CacheVersion.HaloReachMCCInsiderM35:
                return(true);

            default:
                throw new NotImplementedException(version.ToString());
            }
        }
Beispiel #14
0
        /// <summary>
        /// Checks if a <see cref="CacheVersion"/> is for a 64-bit (true) or 32-bit (false) game;
        /// </summary>
        /// <param name="version">The <see cref="CacheVersion"/> to check the address size of.</param>
        /// <returns>True if the <see cref="CacheVersion"/> is for a 64-bit game; false otherwise.</returns>
        public static bool Is64Bit(CacheVersion version)
        {
            switch (version)
            {
            case CacheVersion.Halo2Xbox:
            case CacheVersion.Halo2Vista:
            case CacheVersion.Halo3Retail:
            case CacheVersion.Halo3ODST:
            case CacheVersion.HaloOnline106708:
            case CacheVersion.HaloOnline235640:
            case CacheVersion.HaloOnline301003:
            case CacheVersion.HaloOnline327043:
            case CacheVersion.HaloOnline372731:
            case CacheVersion.HaloOnline416097:
            case CacheVersion.HaloOnline430475:
            case CacheVersion.HaloOnline454665:
            case CacheVersion.HaloOnline449175:
            case CacheVersion.HaloOnline498295:
            case CacheVersion.HaloOnline530605:
            case CacheVersion.HaloOnline532911:
            case CacheVersion.HaloOnline554482:
            case CacheVersion.HaloOnline571627:
            case CacheVersion.HaloOnline700123:
            case CacheVersion.HaloReach:
                return(false);

            case CacheVersion.HaloReachMCCInsiderM35:
                return(true);

            default:
                return(false);
            }
        }
 /// <summary>
 /// Constructs a <see cref="TagStructureInfo"/> object which contains info about a tag structure type.
 /// </summary>
 /// <param name="structureType">The tag structure type to analyze.</param>
 /// <param name="version">The engine version to compare attributes against.</param>
 public TagStructureInfo(Type structureType, CacheVersion version)
 {
     Version             = version;
     GroupTag            = new Tag(-1);
     ParentGroupTag      = new Tag(-1);
     GrandparentGroupTag = new Tag(-1);
     Analyze(structureType, version);
 }
Beispiel #16
0
        /// <summary>
        /// Gets the stringID corresponding to a string list index from the cache version.
        /// </summary>
        /// <param name="index">The string list index to convert.</param>
        /// <param name="version">The version of the returned StringID.</param>
        /// <returns>The corresponding stringID.</returns>
        public StringId GetStringId(int index, CacheVersion version)
        {
            if (index < 0 || index >= Strings.Count)
            {
                return(StringId.Invalid);
            }

            return(Resolver.IndexToStringID(index, version));
        }
Beispiel #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MeshReader"/> class.
 /// </summary>
 /// <param name="version">The engine version to target.</param>
 /// <param name="mesh">The mesh.</param>
 public MeshReader(CacheVersion version, Mesh mesh)
 {
     _version      = version;
     Mesh          = mesh;
     VertexStreams = new VertexBufferDefinition[StreamCount];
     IndexBuffers  = new IndexBufferDefinition[IndexBufferCount];
     BindVertexStreams();
     BindIndexBuffers();
 }
Beispiel #18
0
        /// <summary>
        /// Gets the timestamp for a version.
        /// </summary>
        /// <param name="version">The version.</param>
        /// <returns>The timestamp, or -1 for <see cref="CacheVersion.Unknown"/>.</returns>
        public static long GetTimestamp(CacheVersion version)
        {
            if (version == CacheVersion.Unknown)
            {
                return(-1);
            }

            return(VersionTimestamps[(int)version]);
        }
Beispiel #19
0
        public CacheFileGen3(HaloOnlineCacheContext cacheContext, FileInfo file, CacheVersion version, bool memory)
            : base(cacheContext, file, version, memory)
        {
            if (Header.Interop.ResourceBaseAddress == 0)
            {
                Magic = (int)(Header.Interop.RuntimeBaseAddress - Header.MemoryBufferSize);
            }
            else
            {
                Header.Magic = Header.StringIDsIndicesOffset - (int)TagStructure.GetTagStructureInfo(typeof(CacheFileHeader), version).TotalSize;

                Header.TagNamesBufferOffset   -= Header.Magic;
                Header.TagNamesIndicesOffset  -= Header.Magic;
                Header.StringIDsIndicesOffset -= Header.Magic;
                Header.StringIDsBufferOffset  -= Header.Magic;

                var resourcePartition = Header.Partitions[(int)CacheFilePartitionType.Resources];
                var resourceSection   = Header.Interop.Sections[(int)CacheFileSectionType.Resource];
                Magic = BitConverter.ToInt32(BitConverter.GetBytes(resourcePartition.BaseAddress), 0) - (Header.Interop.DebugSectionSize + resourceSection.Size);
            }

            if (Header.TagIndexAddress == 0)
            {
                return;
            }

            Header.TagIndexAddress = BitConverter.ToUInt32(BitConverter.GetBytes(Header.TagIndexAddress - Magic), 0);

            IndexHeader  = new CacheIndexHeader(this);
            IndexItems   = new IndexTable(this);
            Strings      = new StringTable(this);
            LocaleTables = new List <LocaleTable>();

            switch (version)
            {
            case CacheVersion.Halo3Retail:
                Resolver = new StringIdResolverHalo3();
                break;

            case CacheVersion.Halo3ODST:
                Resolver = new StringIdResolverHalo3ODST();
                break;

            case CacheVersion.HaloReach:
                Resolver = new StringIdResolverHaloReach();
                break;

            default:
                throw new NotSupportedException(CacheVersionDetection.GetBuildName(version));
            }

            foreach (var language in Enum.GetValues(typeof(GameLanguage)))
            {
                LocaleTables.Add(new LocaleTable(this, (GameLanguage)language));
            }
        }
Beispiel #20
0
        private void SerializeRange(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object val)
        {
            var type       = val.GetType();
            var boundsType = type.GenericTypeArguments[0];
            var lower      = type.GetProperty("Lower").GetValue(val);
            var upper      = type.GetProperty("Upper").GetValue(val);

            SerializeValue(version, context, tagStream, block, lower, null, boundsType);
            SerializeValue(version, context, tagStream, block, upper, null, boundsType);
        }
Beispiel #21
0
 public ResourceCacheHaloOnline(CacheVersion version)
 {
     Version   = version;
     Resources = new List <Resource>();
     Header    = new ResourceCacheHaloOnlineHeader
     {
         ResourceTableOffset = 0x20,
         CreationTime        = 0x01D0631BCC92931B
     };
 }
Beispiel #22
0
        /// <summary>
        /// Serializes a property.
        /// </summary>
        /// <param name="version"></param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="instance">The object that the property belongs to.</param>
        /// <param name="tagFieldInfo">The field enumerator.</param>
        /// <param name="baseOffset">The base offset of the structure from the start of its block.</param>
        /// <exception cref="System.InvalidOperationException">Offset for property \ + property.Name + \ is outside of its structure</exception>
        private void SerializeProperty(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object instance, TagFieldInfo tagFieldInfo, long baseOffset)
        {
            if (tagFieldInfo.Attribute.Flags.HasFlag(TagFieldFlags.Runtime))
            {
                return;
            }

            SerializeValue(version, context, tagStream, block,
                           tagFieldInfo.GetValue(instance), tagFieldInfo.Attribute, tagFieldInfo.FieldType);
        }
Beispiel #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MeshReader"/> class.
 /// </summary>
 /// <param name="version">The engine version to target.</param>
 /// <param name="mesh">The mesh.</param>
 /// <param name="definition">The mesh's definition data.</param>
 public MeshReader(CacheVersion version, Mesh mesh, RenderGeometryApiResourceDefinition definition)
 {
     _version      = version;
     Mesh          = mesh;
     Definition    = definition;
     VertexStreams = new VertexBufferDefinition[StreamCount];
     IndexBuffers  = new IndexBufferDefinition[IndexBufferCount];
     BindVertexStreams();
     BindIndexBuffers();
 }
Beispiel #24
0
 /// <summary>
 /// Creates a vertex stream for a given engine version.
 /// </summary>
 /// <param name="version">The engine version.</param>
 /// <param name="stream">The base stream.</param>
 /// <returns>The created vertex stream.</returns>
 public static IVertexStream Create(CacheVersion version, Stream stream)
 {
     if (CacheVersionDetection.Compare(version, CacheVersion.Halo3ODST) <= 0)
     {
         return(new VertexStreamXbox(stream));
     }
     if (CacheVersionDetection.Compare(version, CacheVersion.HaloOnline235640) >= 0)
     {
         return(new VertexStreamMS25(stream));
     }
     return(new VertexStreamMS23(stream));
 }
Beispiel #25
0
 /// <summary>
 /// Determines whether a version number is between two other version numbers (inclusive).
 /// </summary>
 /// <param name="compare">The version number to compare. If this is <see cref="CacheVersion.Unknown"/>, this function will always return <c>true</c>.</param>
 /// <param name="min">The minimum version number. If this is <see cref="CacheVersion.Unknown"/>, then the lower bound will be ignored.</param>
 /// <param name="max">The maximum version number. If this is <see cref="CacheVersion.Unknown"/>, then the upper bound will be ignored.</param>
 /// <returns></returns>
 public static bool IsBetween(CacheVersion compare, CacheVersion min, CacheVersion max)
 {
     if (compare == CacheVersion.Unknown)
     {
         return(true);
     }
     if (min != CacheVersion.Unknown && Compare(compare, min) < 0)
     {
         return(false);
     }
     return(max == CacheVersion.Unknown || Compare(compare, max) <= 0);
 }
Beispiel #26
0
 public ResourceCacheHaloOnline(CacheVersion version, Stream stream)
 {
     Version   = version;
     Resources = new List <Resource>();
     if (stream.Length == 0)
     {
         CreateEmptyResourceCache(stream);
     }
     else
     {
         Read(stream);
     }
 }
Beispiel #27
0
 public TagStructureInfo GetTagStructureInfo(Type type, CacheVersion version = CacheVersion.Unknown)
 {
     if (!TagStructureInfos.TryGetValue(type, out TagStructureInfo info))
     {
         lock (TagStructureInfos)
         {
             if (!TagStructureInfos.TryGetValue(type, out info))
             {
                 TagStructureInfos[type] = info = new TagStructureInfo(type, version);
             }
         }
     }
     return(info);
 }
Beispiel #28
0
        public static bool IsInPlatform(CachePlatform platform, CacheVersion version)
        {
            if (version == CacheVersion.Unknown || platform == CachePlatform.All)
            {
                return(true);
            }

            switch (version)
            {
            case CacheVersion.HaloXbox:
            case CacheVersion.Halo2Xbox:
                return(platform.HasFlag(CachePlatform.Xbox));

            case CacheVersion.Halo3Beta:
            case CacheVersion.Halo3Retail:
            case CacheVersion.Halo3ODST:
            case CacheVersion.HaloReach:
                return(platform.HasFlag(CachePlatform.Xbox360));

            case CacheVersion.HaloPC:
            case CacheVersion.HaloCustomEdition:
            case CacheVersion.Halo2Vista:
            case CacheVersion.HaloOnline106708:
            case CacheVersion.HaloOnline235640:
            case CacheVersion.HaloOnline301003:
            case CacheVersion.HaloOnline327043:
            case CacheVersion.HaloOnline372731:
            case CacheVersion.HaloOnline416097:
            case CacheVersion.HaloOnline430475:
            case CacheVersion.HaloOnline454665:
            case CacheVersion.HaloOnline449175:
            case CacheVersion.HaloOnline498295:
            case CacheVersion.HaloOnline530605:
            case CacheVersion.HaloOnline532911:
            case CacheVersion.HaloOnline554482:
            case CacheVersion.HaloOnline571627:
            case CacheVersion.HaloOnline700123:
                return(platform.HasFlag(CachePlatform.PC32Bit));

            case CacheVersion.HaloReachMCC0824:
            case CacheVersion.HaloReachMCC0887:
            case CacheVersion.HaloReachMCC1035:
            case CacheVersion.HaloReachMCC1211:
                var result = platform.HasFlag(CachePlatform.PC64Bit);
                return(result);

            default:
                return(false);
            }
        }
Beispiel #29
0
        /// <summary>
        /// Serializes a tag block.
        /// </summary>
        /// <param name="version"></param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="list">The list of values in the tag block.</param>
        /// <param name="listType">Type of the list.</param>
        /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param>
        private void SerializeTagBlock(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object list, Type listType, TagFieldAttribute valueInfo)
        {
            var writer = block.Writer;
            var count  = 0;

            if (list != null)
            {
                // Use reflection to get the number of elements in the list
                var countProperty = listType.GetProperty("Count");
                count = (int)countProperty.GetValue(list);
            }
            if (count == 0)
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                return;
            }

            var elementType = listType.GenericTypeArguments[0];
            TagStructureAttribute structure;

            try
            {
                structure = TagStructure.GetTagStructureInfo(elementType, Version).Structure;
            }
            catch
            {
                structure = null;
            }

            // Serialize each value in the list to a data block
            var tagBlock       = context.CreateBlock();
            var enumerableList = (System.Collections.IEnumerable)list;

            foreach (var val in enumerableList)
            {
                SerializeValue(version, context, tagStream, tagBlock, val, null, elementType);
            }

            // Ensure the block is aligned correctly
            var align = Math.Max(DefaultBlockAlign, (valueInfo != null) ? valueInfo.Align : 0);

            StreamUtil.Align(tagStream, (int)align);

            // Finalize the block and write the tag block reference
            writer.Write(count);
            block.WritePointer(tagBlock.Finalize(tagStream), listType);
            writer.Write(0);
        }
Beispiel #30
0
        public BlamSound(Sound sound, int permutationGestaltIndex, byte[] data, CacheVersion version, SoundCacheFileGestalt soundGestalt = null)
        {
            switch (version)
            {
            case CacheVersion.Halo3Retail:
            case CacheVersion.Halo3ODST:
            case CacheVersion.HaloReach:
                InitGen3Sound(sound, soundGestalt, permutationGestaltIndex, data);
                break;

            default:
                throw new Exception($"Unsupported cache version {version}");
            }
        }