Beispiel #1
0
        public static long GenerateExportID(Object asset, Func <long, bool> uniqueChecker)
        {
            if (asset == null)
            {
                throw new ArgumentNullException(nameof(asset));
            }

#warning TODO: values acording to read version (current 2017.3.0f3)
            ThreadSafeRandom random  = new ThreadSafeRandom();
            uint             classID = (uint)asset.ClassID;
#if DEBUG
            int length = BitConverterExtensions.GetDigitsCount(classID);
            if (length > 4)
            {
                throw new NotSupportedException($"Class ID {classID} with more that 4 digits isn't supported");
            }
#endif
            long  prefix          = classID * 1000000000000000L;
            ulong persistentValue = 0;
            long  exportID        = 0;
            do
            {
                ulong value = 0;
                value          += unchecked ((uint)random.Next(0, 100000)) * 10000000000UL;
                value          += unchecked ((uint)random.Next(0, 100000)) * 100000UL;
                value          += unchecked ((uint)random.Next(0, 100000)) * 1UL;
                persistentValue = unchecked (persistentValue + value);
                exportID        = prefix + (long)(persistentValue % 1000000000000000L);
            }while (uniqueChecker(exportID));
            return(exportID);
        }
Beispiel #2
0
		public static long GenerateExportID(Object asset, Func<long, bool> duplicateChecker)
		{
			if (asset == null)
			{
				throw new ArgumentNullException(nameof(asset));
			}

			ThreadSafeRandom random = new ThreadSafeRandom();
			uint classID = (uint)asset.ClassID;
#if DEBUG
			int length = BitConverterExtensions.GetDigitsCount(classID);
			if (length > 4)
			{
				throw new NotSupportedException($"Class ID {classID} with more that 4 digits isn't supported");
			}
#endif
			long prefix = classID * 1000000000000000L;
			ulong persistentValue = 0;
#warning TODO: depending on the export version exportID should has random or ordered value
			long exportID = 0;
			do
			{
				ulong value = unchecked((ulong)GenerateInternalID());
				persistentValue = unchecked(persistentValue + value);
				exportID = prefix + (long)(persistentValue % 1000000000000000L);
			}
			while (duplicateChecker(exportID));
			return exportID;
		}
        public static ulong GetMainExportID(uint classID, uint value)
        {
#if DEBUG
            int digits = BitConverterExtensions.GetDigitsCount(value);
            if (digits > 5)
            {
                throw new ArgumentException($"Value {value} for main export ID must have not more than 5 digits");
            }
#endif
            return((classID * 100000) | value);
        }
        public void SetValue(double value)
        {
#if USE_HEX_FLOAT
            // It is more precise technic but output looks vague and less readable
            ulong hex = BitConverterExtensions.ToUInt64(value);
            m_string     = $"0x{hex.ToHexString()}({value.ToString(CultureInfo.InvariantCulture)})";
            m_objectType = ScalarType.String;
#else
            m_value      = BitConverterExtensions.ToUInt64(value);
            m_objectType = ScalarType.Double;
#endif
        }
        public void SetValue(float value)
        {
#if USE_HEX_SINGLE
            // It is more precise technic but output looks vague and less readable
            uint hex = BitConverterExtensions.ToUInt32(value);
            m_string     = $"0x{hex.ToHexString()}({value.ToString(CultureInfo.InvariantCulture)})";
            m_objectType = ScalarType.String;
#else
            m_single     = value;
            m_objectType = ScalarType.Single;
#endif
        }
        public void SetValue(float value)
        {
            uint hex = BitConverterExtensions.ToUInt32(value);

#if USE_HEX_SINGLE
            // As Unity says it is more precise technic but output looks vague and less readable
            m_value = $"0x{hex.ToString("X8")}({value.ToString(CultureInfo.InvariantCulture)})";
#else
            m_value = value;
#endif
            m_objectType = ScalarType.Single;
        }
Beispiel #7
0
        public static long GetMainExportID(uint classID, uint value)
        {
            if (classID > 100100)
            {
                if (value != 0)
                {
                    throw new ArgumentException("Unique asset type with non unique modifier", nameof(value));
                }
                return(classID);
            }

#if DEBUG
            int digits = BitConverterExtensions.GetDigitsCount(value);
            if (digits > 5)
            {
                throw new ArgumentException($"Value {value} for main export ID must have no more than 5 digits");
            }
#endif
            return((classID * 100000) + value);
        }
Beispiel #8
0
        public static long GenerateExportID(Object asset, Func <long, bool> uniqueChecker)
        {
            if (asset == null)
            {
                throw new ArgumentNullException(nameof(asset));
            }

#warning TODO: values acording to read version (current 2017.3.0f3)
            ThreadSafeRandom random = new ThreadSafeRandom();
            long             exportID;
            do
            {
                uint classID = (uint)asset.ClassID;
#if DEBUG
                int length = BitConverterExtensions.GetDigitsCount(classID);
                if (length > 4)
                {
                    throw new NotSupportedException($"Class ID {classID} with more that 4 digits isn't supported");
                }
#endif
                exportID  = classID;
                exportID *= 1000000000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 100000000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 10000000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 1000000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 100000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 10000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 1000000000L;
                exportID |= unchecked (random.Next(0, 2)) * 100000000L;
                exportID |= unchecked (random.Next(0, 2)) * 10000000L;
                exportID |= unchecked (random.Next(0, 2)) * 1000000L;
                exportID |= unchecked (random.Next(0, 2)) * 100000L;
                exportID |= unchecked (random.Next(0, 2)) * 10000L;
                exportID |= unchecked (random.Next(0, 2)) * 1000L;
                exportID |= unchecked (random.Next(0, 2)) * 100L;
                exportID |= unchecked (random.Next(0, 2)) * 10L;
                exportID |= unchecked (random.Next(0, 2)) * 1L;
            }while (uniqueChecker(exportID));
            return(exportID);
        }
        internal Emitter ToString(Emitter emitter)
        {
            if (Style == ScalarStyle.Hex)
            {
                switch (m_objectType)
                {
                case ScalarType.Byte:
                    return(emitter.WriteHex((byte)m_value));

                case ScalarType.Int16:
                    return(emitter.WriteHex(unchecked ((short)m_value)));

                case ScalarType.UInt16:
                    return(emitter.WriteHex((ushort)m_value));

                case ScalarType.Int32:
                    return(emitter.WriteHex(unchecked ((int)m_value)));

                case ScalarType.UInt32:
                    return(emitter.WriteHex((uint)m_value));

                case ScalarType.Int64:
                    return(emitter.WriteHex(unchecked ((long)m_value)));

                case ScalarType.UInt64:
                    return(emitter.WriteHex(m_value));

                case ScalarType.Single:
                    return(emitter.WriteHex((uint)m_value));

                case ScalarType.Double:
                    return(emitter.WriteHex(m_value));

                default:
                    throw new NotImplementedException(m_objectType.ToString());
                }
            }

            switch (m_objectType)
            {
            case ScalarType.Boolean:
                return(emitter.Write(m_value));

            case ScalarType.Byte:
                return(emitter.Write(m_value));

            case ScalarType.Int16:
                return(emitter.Write(unchecked ((short)m_value)));

            case ScalarType.UInt16:
                return(emitter.Write(m_value));

            case ScalarType.Int32:
                return(emitter.Write(unchecked ((int)m_value)));

            case ScalarType.UInt32:
                return(emitter.Write(m_value));

            case ScalarType.Int64:
                return(emitter.Write(unchecked ((long)m_value)));

            case ScalarType.UInt64:
                return(emitter.Write(m_value));

            case ScalarType.Single:
                return(emitter.Write(BitConverterExtensions.ToSingle((uint)m_value)));

            case ScalarType.Double:
                return(emitter.Write(BitConverterExtensions.ToDouble(m_value)));

            case ScalarType.String:
                return(WriteString(emitter));

            default:
                throw new NotImplementedException(m_objectType.ToString());
            }
        }
        public static string ToHexString(this double _this)
        {
            ulong value = BitConverterExtensions.ToUInt64(_this);

            return(ToHexString(value));
        }
        public static string ToHexString(this float _this)
        {
            uint value = BitConverterExtensions.ToUInt32(_this);

            return(ToHexString(value));
        }
Beispiel #12
0
 public static Emitter WriteHex(this Emitter _this, double value)
 {
     return(WriteHex(_this, BitConverterExtensions.ToUInt64(value)));
 }
Beispiel #13
0
 public static Emitter WriteHex(this Emitter _this, float value)
 {
     return(WriteHex(_this, BitConverterExtensions.ToUInt32(value)));
 }
Beispiel #14
0
        public void Parse(Stream baseStream)
        {
            Reset();
            using (EndianStream stream = new EndianStream(baseStream, EndianType.BigEndian))
            {
                long startPosition = baseStream.Position;
                stream.AlignPosition = startPosition;
                int tableSize = stream.ReadInt32();
                if (tableSize <= 0)
                {
                    throw new Exception($"Invalid table size {tableSize} for asset file {Name}");
                }
                int dataEnd = stream.ReadInt32();
                if (dataEnd <= 0)
                {
                    throw new Exception($"Invalid data end {dataEnd} for asset file {Name}");
                }
                Generation = (FileGeneration)stream.ReadInt32();
                if (!Enum.IsDefined(typeof(FileGeneration), Generation))
                {
                    throw new Exception($"Unsuported file generation {Generation} for asset file '{Name}'");
                }
                long dataOffset = startPosition + stream.ReadUInt32();

                //reference itself because sharedFileIDs start from 1
                AssetsFilePtr dependency = new AssetsFilePtr(Name, string.Empty);
                m_dependencies.Add(dependency);

                if (IsTableAtTheEnd)
                {
                    stream.BaseStream.Position = dataEnd - tableSize;
                    stream.BaseStream.Position++;
                }
                else
                {
                    stream.BaseStream.Position += 4;
                }

                if (IsReadVersion)
                {
                    string version = stream.ReadStringZeroTerm();
                    Version.Parse(version);
                }
                if (IsReadPlatform)
                {
                    Platform = (Platform)stream.ReadUInt32();

                    // reverse stream endian
                    if ((uint)Platform > byte.MaxValue)
                    {
                        Platform          = (Platform)BitConverterExtensions.Reverse((uint)Platform);
                        stream.EndianType = EndianType.LittleEndian;
                    }

                    if (!Enum.IsDefined(typeof(Platform), Platform))
                    {
                        throw new Exception($"Unsuported platform {Platform} for asset file '{Name}'");
                    }
                }
                if (IsReadBaseDefinitions)
                {
                    BaseDefinitions = stream.ReadBoolean();
                }

                int baseCount = stream.ReadInt32();
                for (int i = 0; i < baseCount; i++)
                {
                    if (IsBase5)
                    {
                        ReadBase5(stream);
                    }
                    else
                    {
                        ReadBase(stream);
                    }
                }

                if (IsSkipZero)
                {
                    stream.BaseStream.Position += 4;
                }

                int assetCount = stream.ReadInt32();
                if (assetCount < 0)
                {
                    throw new Exception($"Invalid asset count {assetCount} for asset file {Name}");
                }

                for (int i = 0; i < assetCount; i++)
                {
                    if (IsNeedAlign)
                    {
                        stream.AlignStream(AlignType.Align4);
                    }

                    long pathID;
                    if (IsLongPathID)
                    {
                        pathID = stream.ReadInt64();
                    }
                    else
                    {
                        pathID = stream.ReadInt32();
                    }
                    long offset = dataOffset + stream.ReadUInt32();
                    int  size   = stream.ReadInt32();

                    ClassIDMap classMap;
                    if (IsReadSubClass)
                    {
                        int index = stream.ReadInt32();
                        classMap = m_classIDs[index];
                    }
                    else
                    {
                        int uniqueID = stream.ReadInt32();
                        int classID  = stream.ReadUInt16();
                        classMap = new ClassIDMap(uniqueID, classID);
                        stream.BaseStream.Position += 2;
                    }

                    if (IsSkipUnknown)
                    {
                        //this is a single byte, not an int32
                        //the next entry is aligned after this
                        //but not the last!
                        stream.BaseStream.Position++;
                    }

                    AssetInfo        assetInfo = new AssetInfo(this, pathID, classMap);
                    AssetPreloadData asset     = new AssetPreloadData(assetInfo, offset, size);
                    m_assetPreloads.Add(pathID, asset);
                }

                if (IsReadPreload)
                {
                    //this looks like a list of assets that need to be preloaded in memory before anytihng else
                    int count = stream.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        int num1 = stream.ReadInt32();
                        stream.AlignStream(AlignType.Align4);
                        long pathID = stream.ReadInt64();
                    }
                }

                int dependenciesCount = stream.ReadInt32();
                for (int i = 0; i < dependenciesCount; i++)
                {
                    string name = stream.ReadStringZeroTerm();
                    stream.BaseStream.Position += 20;
                    string fileName = stream.ReadStringZeroTerm();
                    dependency = new AssetsFilePtr(fileName, name);
                    m_dependencies.Add(dependency);
                }

                foreach (AssetPreloadData preload in m_assetPreloads.Values)
                {
                    preload.Parse(stream);
                }
            }
        }