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); }
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; }
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); }
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)); }
public static Emitter WriteHex(this Emitter _this, double value) { return(WriteHex(_this, BitConverterExtensions.ToUInt64(value))); }
public static Emitter WriteHex(this Emitter _this, float value) { return(WriteHex(_this, BitConverterExtensions.ToUInt32(value))); }
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); } } }