Improved file reading
This commit is contained in:
parent
067517740f
commit
98c9eea58a
|
@ -13,7 +13,7 @@ namespace AssetStudio
|
|||
|
||||
private List<string> importFiles = new List<string>();
|
||||
private HashSet<string> importFilesHash = new HashSet<string>();
|
||||
private HashSet<string> assetsfileListHash = new HashSet<string>();
|
||||
private HashSet<string> assetsFileListHash = new HashSet<string>();
|
||||
|
||||
public void LoadFiles(string[] files)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace AssetStudio
|
|||
|
||||
importFiles.Clear();
|
||||
importFilesHash.Clear();
|
||||
assetsfileListHash.Clear();
|
||||
assetsFileListHash.Clear();
|
||||
|
||||
ReadAssets();
|
||||
ProcessGameObject();
|
||||
|
@ -74,14 +74,14 @@ namespace AssetStudio
|
|||
private void LoadAssetsFile(string fullName, EndianBinaryReader reader)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
if (!assetsfileListHash.Contains(fileName.ToUpper()))
|
||||
if (!assetsFileListHash.Contains(fileName.ToUpper()))
|
||||
{
|
||||
Logger.Info($"Loading {fileName}");
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
if (assetsFile.valid)
|
||||
try
|
||||
{
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsfileListHash.Add(assetsFile.upperFileName);
|
||||
assetsFileListHash.Add(assetsFile.upperFileName);
|
||||
|
||||
foreach (var sharedFile in assetsFile.m_Externals)
|
||||
{
|
||||
|
@ -107,9 +107,10 @@ namespace AssetStudio
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
reader.Dispose();
|
||||
//Logger.Error($"Unable to load assets file {fileName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -120,24 +121,28 @@ namespace AssetStudio
|
|||
|
||||
private void LoadAssetsFromMemory(string fullName, EndianBinaryReader reader, string originalPath, string unityVersion = null)
|
||||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
if (!assetsfileListHash.Contains(fileName.ToUpper()))
|
||||
var upperFileName = Path.GetFileName(fullName).ToUpper();
|
||||
if (!assetsFileListHash.Contains(upperFileName))
|
||||
{
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
if (assetsFile.valid)
|
||||
try
|
||||
{
|
||||
var assetsFile = new SerializedFile(this, fullName, reader);
|
||||
assetsFile.originalPath = originalPath;
|
||||
if (assetsFile.header.m_Version < 7)
|
||||
{
|
||||
assetsFile.SetVersion(unityVersion);
|
||||
}
|
||||
|
||||
assetsFileList.Add(assetsFile);
|
||||
assetsfileListHash.Add(assetsFile.upperFileName);
|
||||
assetsFileListHash.Add(assetsFile.upperFileName);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Logger.Error($"Unable to load assets file {fileName} from {Path.GetFileName(originalPath)}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
resourceFileReaders.Add(upperFileName, reader);
|
||||
}
|
||||
|
||||
resourceFileReaders.Add(assetsFile.upperFileName, assetsFile.reader);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,12 +150,27 @@ namespace AssetStudio
|
|||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
Logger.Info("Loading " + fileName);
|
||||
var bundleFile = new BundleFile(reader, fullName);
|
||||
reader.Dispose();
|
||||
foreach (var file in bundleFile.fileList)
|
||||
try
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
|
||||
var bundleFile = new BundleFile(reader, fullName);
|
||||
foreach (var file in bundleFile.fileList)
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||
LoadAssetsFromMemory(dummyPath, new EndianBinaryReader(file.stream), parentPath ?? fullName, bundleFile.versionEngine);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
/*var str = $"Unable to load bundle file {fileName}";
|
||||
if (parentPath != null)
|
||||
{
|
||||
str += $" from {Path.GetFileName(parentPath)}";
|
||||
}
|
||||
Logger.Error(str);*/
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,24 +178,34 @@ namespace AssetStudio
|
|||
{
|
||||
var fileName = Path.GetFileName(fullName);
|
||||
Logger.Info("Loading " + fileName);
|
||||
var webFile = new WebFile(reader);
|
||||
reader.Dispose();
|
||||
foreach (var file in webFile.fileList)
|
||||
try
|
||||
{
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||
switch (CheckFileType(file.stream, out reader))
|
||||
var webFile = new WebFile(reader);
|
||||
foreach (var file in webFile.fileList)
|
||||
{
|
||||
case FileType.AssetsFile:
|
||||
LoadAssetsFromMemory(dummyPath, reader, fullName);
|
||||
break;
|
||||
case FileType.BundleFile:
|
||||
LoadBundleFile(dummyPath, reader, fullName);
|
||||
break;
|
||||
case FileType.WebFile:
|
||||
LoadWebFile(dummyPath, reader);
|
||||
break;
|
||||
var dummyPath = Path.GetDirectoryName(fullName) + "\\" + file.fileName;
|
||||
switch (CheckFileType(file.stream, out reader))
|
||||
{
|
||||
case FileType.AssetsFile:
|
||||
LoadAssetsFromMemory(dummyPath, reader, fullName);
|
||||
break;
|
||||
case FileType.BundleFile:
|
||||
LoadBundleFile(dummyPath, reader, fullName);
|
||||
break;
|
||||
case FileType.WebFile:
|
||||
LoadWebFile(dummyPath, reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Logger.Error($"Unable to load web file {fileName}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
|
|
|
@ -85,10 +85,10 @@ namespace AssetStudio
|
|||
|
||||
int numData = reader.ReadInt32();
|
||||
m_Data = reader.ReadBytes(numData);
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
m_BitSize = reader.ReadByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
public float[] UnpackFloats(int itemCountInChunk, int chunkStride, int start = 0, int numChunks = -1)
|
||||
|
@ -142,10 +142,10 @@ namespace AssetStudio
|
|||
|
||||
int numData = reader.ReadInt32();
|
||||
m_Data = reader.ReadBytes(numData);
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
m_BitSize = reader.ReadByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
public int[] UnpackInts()
|
||||
|
@ -187,7 +187,7 @@ namespace AssetStudio
|
|||
int numData = reader.ReadInt32();
|
||||
m_Data = reader.ReadBytes(numData);
|
||||
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
public Quaternion[] UnpackQuats()
|
||||
|
@ -383,10 +383,7 @@ namespace AssetStudio
|
|||
public HandPose(ObjectReader reader)
|
||||
{
|
||||
m_GrabX = new xform(reader);
|
||||
|
||||
int numDoFs = reader.ReadInt32();
|
||||
m_DoFArray = reader.ReadSingleArray(numDoFs);
|
||||
|
||||
m_DoFArray = reader.ReadSingleArray();
|
||||
m_Override = reader.ReadSingle();
|
||||
m_CloseOpen = reader.ReadSingle();
|
||||
m_InOut = reader.ReadSingle();
|
||||
|
@ -444,8 +441,7 @@ namespace AssetStudio
|
|||
m_LeftHandPose = new HandPose(reader);
|
||||
m_RightHandPose = new HandPose(reader);
|
||||
|
||||
int numDoFs = reader.ReadInt32();
|
||||
m_DoFArray = reader.ReadSingleArray(numDoFs);
|
||||
m_DoFArray = reader.ReadSingleArray();
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 2))//5.2 and up
|
||||
{
|
||||
|
@ -466,8 +462,7 @@ namespace AssetStudio
|
|||
|
||||
public StreamedClip(ObjectReader reader)
|
||||
{
|
||||
int numData = reader.ReadInt32();
|
||||
data = reader.ReadUInt32Array(numData);
|
||||
data = reader.ReadUInt32Array();
|
||||
curveCount = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
|
@ -572,9 +567,7 @@ namespace AssetStudio
|
|||
m_CurveCount = reader.ReadUInt32();
|
||||
m_SampleRate = reader.ReadSingle();
|
||||
m_BeginTime = reader.ReadSingle();
|
||||
|
||||
int numSamples = reader.ReadInt32();
|
||||
m_SampleArray = reader.ReadSingleArray(numSamples);
|
||||
m_SampleArray = reader.ReadSingleArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,8 +577,7 @@ namespace AssetStudio
|
|||
|
||||
public ConstantClip(ObjectReader reader)
|
||||
{
|
||||
int numData = reader.ReadInt32();
|
||||
data = reader.ReadSingleArray(numData);
|
||||
data = reader.ReadSingleArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -713,16 +705,10 @@ namespace AssetStudio
|
|||
m_CycleOffset = reader.ReadSingle();
|
||||
m_AverageAngularSpeed = reader.ReadSingle();
|
||||
|
||||
int numIndices = reader.ReadInt32();
|
||||
m_IndexArray = reader.ReadInt32Array(numIndices);
|
||||
m_IndexArray = reader.ReadInt32Array();
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] < 3)) //4.3 down
|
||||
{
|
||||
int numAdditionalCurveIndexs = reader.ReadInt32();
|
||||
var m_AdditionalCurveIndexArray = new List<int>(numAdditionalCurveIndexs);
|
||||
for (int i = 0; i < numAdditionalCurveIndexs; i++)
|
||||
{
|
||||
m_AdditionalCurveIndexArray.Add(reader.ReadInt32());
|
||||
}
|
||||
var m_AdditionalCurveIndexArray = reader.ReadInt32Array();
|
||||
}
|
||||
int numDeltas = reader.ReadInt32();
|
||||
m_ValueArrayDelta = new List<ValueDelta>(numDeltas);
|
||||
|
@ -732,7 +718,7 @@ namespace AssetStudio
|
|||
}
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3))//5.3 and up
|
||||
{
|
||||
m_ValueArrayReferencePose = reader.ReadSingleArray(reader.ReadInt32());
|
||||
m_ValueArrayReferencePose = reader.ReadSingleArray();
|
||||
}
|
||||
|
||||
m_Mirror = reader.ReadBoolean();
|
||||
|
@ -749,7 +735,7 @@ namespace AssetStudio
|
|||
m_KeepOriginalPositionY = reader.ReadBoolean();
|
||||
m_KeepOriginalPositionXZ = reader.ReadBoolean();
|
||||
m_HeightFromFeet = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -778,7 +764,7 @@ namespace AssetStudio
|
|||
}
|
||||
customType = reader.ReadByte();
|
||||
isPPtrCurve = reader.ReadByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -890,7 +876,7 @@ namespace AssetStudio
|
|||
{
|
||||
m_UseHighQualityCurve = reader.ReadBoolean();
|
||||
}
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
int numRCurves = reader.ReadInt32();
|
||||
m_RotationCurves = new List<QuaternionCurve>(numRCurves);
|
||||
for (int i = 0; i < numRCurves; i++)
|
||||
|
@ -965,7 +951,7 @@ namespace AssetStudio
|
|||
m_Events = new List<AnimationEvent>(numEvents);
|
||||
for (int i = 0; i < numEvents; i++)
|
||||
{
|
||||
m_Events.Add(new AnimationEvent(stream, file.Version[0] - '0'));
|
||||
m_Events.Add(new AnimationEvent(reader));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,13 @@ namespace AssetStudio
|
|||
var m_ApplyRootMotion = reader.ReadBoolean();
|
||||
if (version[0] == 4 && version[1] >= 5) //4.5 and up - 5.0 down
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
var m_LinearVelocityBlending = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] < 4 || (version[0] == 4 && version[1] < 5)) //4.5 down
|
||||
|
@ -50,13 +50,13 @@ namespace AssetStudio
|
|||
}
|
||||
if (version[0] >= 5 && version[0] < 2018) //5.0 and up - 2018 down
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
{
|
||||
var m_KeepAnimatorControllerStateOnDisable = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace AssetStudio
|
|||
m_DefaultWeight = reader.ReadSingle();
|
||||
m_IKPass = reader.ReadBoolean();
|
||||
m_SyncedLayerAffectsTiming = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ namespace AssetStudio
|
|||
m_ExitTime = reader.ReadSingle();
|
||||
m_HasExitTime = reader.ReadBoolean();
|
||||
m_HasFixedDuration = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
m_InterruptionSource = reader.ReadInt32();
|
||||
m_OrderedInterruption = reader.ReadBoolean();
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ namespace AssetStudio
|
|||
}
|
||||
|
||||
m_CanTransitionToSelf = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ namespace AssetStudio
|
|||
|
||||
public LeafInfoConstant(ObjectReader reader)
|
||||
{
|
||||
m_IDArray = reader.ReadUInt32Array(reader.ReadInt32());
|
||||
m_IDArray = reader.ReadUInt32Array();
|
||||
m_IndexOffset = reader.ReadUInt32();
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ namespace AssetStudio
|
|||
|
||||
public MotionNeighborList(ObjectReader reader)
|
||||
{
|
||||
m_NeighborArray = reader.ReadUInt32Array(reader.ReadInt32());
|
||||
m_NeighborArray = reader.ReadUInt32Array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,10 +181,10 @@ namespace AssetStudio
|
|||
|
||||
public Blend2dDataConstant(ObjectReader reader)
|
||||
{
|
||||
m_ChildPositionArray = reader.ReadVector2Array(reader.ReadInt32());
|
||||
m_ChildMagnitudeArray = reader.ReadSingleArray(reader.ReadInt32());
|
||||
m_ChildPairVectorArray = reader.ReadVector2Array(reader.ReadInt32());
|
||||
m_ChildPairAvgMagInvArray = reader.ReadSingleArray(reader.ReadInt32());
|
||||
m_ChildPositionArray = reader.ReadVector2Array();
|
||||
m_ChildMagnitudeArray = reader.ReadSingleArray();
|
||||
m_ChildPairVectorArray = reader.ReadVector2Array();
|
||||
m_ChildPairAvgMagInvArray = reader.ReadSingleArray();
|
||||
|
||||
int numNeighbours = reader.ReadInt32();
|
||||
m_ChildNeighborListArray = new MotionNeighborList[numNeighbours];
|
||||
|
@ -201,7 +201,7 @@ namespace AssetStudio
|
|||
|
||||
public Blend1dDataConstant(ObjectReader reader)
|
||||
{
|
||||
m_ChildThresholdArray = reader.ReadSingleArray(reader.ReadInt32());
|
||||
m_ChildThresholdArray = reader.ReadSingleArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,9 +212,9 @@ namespace AssetStudio
|
|||
|
||||
public BlendDirectDataConstant(ObjectReader reader)
|
||||
{
|
||||
m_ChildBlendEventIDArray = reader.ReadUInt32Array(reader.ReadInt32());
|
||||
m_ChildBlendEventIDArray = reader.ReadUInt32Array();
|
||||
m_NormalizedBlendValues = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ namespace AssetStudio
|
|||
m_BlendType = reader.ReadUInt32();
|
||||
m_BlendEventID = reader.ReadUInt32();
|
||||
m_BlendEventYID = reader.ReadUInt32();
|
||||
m_ChildIndices = reader.ReadUInt32Array(reader.ReadInt32());
|
||||
m_ChildIndices = reader.ReadUInt32Array();
|
||||
m_Blend1dData = new Blend1dDataConstant(reader);
|
||||
m_Blend2dData = new Blend2dDataConstant(reader);
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
|
@ -256,7 +256,7 @@ namespace AssetStudio
|
|||
m_Duration = reader.ReadSingle();
|
||||
m_CycleOffset = reader.ReadSingle();
|
||||
m_Mirror = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,12 +306,7 @@ namespace AssetStudio
|
|||
m_TransitionConstantArray[i] = new TransitionConstant(reader);
|
||||
}
|
||||
|
||||
int numBlendIndices = reader.ReadInt32();
|
||||
m_BlendTreeConstantIndexArray = new int[numBlendIndices];
|
||||
for (int i = 0; i < numBlendIndices; i++)
|
||||
{
|
||||
m_BlendTreeConstantIndexArray[i] = reader.ReadInt32();
|
||||
}
|
||||
m_BlendTreeConstantIndexArray = reader.ReadInt32Array();
|
||||
|
||||
if (version[0] < 5) //5.0 down
|
||||
{
|
||||
|
@ -360,7 +355,7 @@ namespace AssetStudio
|
|||
|
||||
m_Loop = reader.ReadBoolean();
|
||||
m_Mirror = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,7 +394,7 @@ namespace AssetStudio
|
|||
|
||||
m_FullPathID = reader.ReadUInt32();
|
||||
m_isEntry = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,17 +452,12 @@ namespace AssetStudio
|
|||
var version = reader.version;
|
||||
if (version[0] < 5 || (version[0] == 5 && version[1] < 5)) //5.5 down
|
||||
{
|
||||
int numBools = reader.ReadInt32();
|
||||
m_BoolValues = new bool[numBools];
|
||||
for (int i = 0; i < numBools; i++)
|
||||
{
|
||||
m_BoolValues[i] = reader.ReadBoolean();
|
||||
}
|
||||
m_BoolValues = reader.ReadBooleanArray();
|
||||
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
m_IntValues = reader.ReadInt32Array(reader.ReadInt32());
|
||||
m_FloatValues = reader.ReadSingleArray(reader.ReadInt32());
|
||||
m_IntValues = reader.ReadInt32Array();
|
||||
m_FloatValues = reader.ReadSingleArray();
|
||||
}
|
||||
|
||||
int numPosValues = reader.ReadInt32();
|
||||
|
@ -477,28 +467,23 @@ namespace AssetStudio
|
|||
m_PositionValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
||||
}
|
||||
|
||||
m_QuaternionValues = reader.ReadVector4Array(reader.ReadInt32());
|
||||
m_QuaternionValues = reader.ReadVector4Array();
|
||||
|
||||
int numScaleValues = reader.ReadInt32();
|
||||
m_ScaleValues = new Vector3[numScaleValues];
|
||||
for (int i = 0; i < numScaleValues; i++)
|
||||
{
|
||||
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 adn up
|
||||
m_ScaleValues[i] = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4(); //5.4 and up
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||
{
|
||||
m_FloatValues = reader.ReadSingleArray(reader.ReadInt32());
|
||||
m_IntValues = reader.ReadInt32Array(reader.ReadInt32());
|
||||
m_FloatValues = reader.ReadSingleArray();
|
||||
m_IntValues = reader.ReadInt32Array();
|
||||
|
||||
int numBools = reader.ReadInt32();
|
||||
m_BoolValues = new bool[numBools];
|
||||
for (int i = 0; i < numBools; i++)
|
||||
{
|
||||
m_BoolValues[i] = reader.ReadBoolean();
|
||||
}
|
||||
m_BoolValues = reader.ReadBooleanArray();
|
||||
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace AssetStudio
|
|||
m_Type = (AudioType)reader.ReadInt32();
|
||||
m_3D = reader.ReadBoolean();
|
||||
m_UseHardware = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
if (version[0] >= 4 || (version[0] == 3 && version[1] >= 2)) //3.2.0 to 5
|
||||
{
|
||||
|
@ -65,13 +65,12 @@ namespace AssetStudio
|
|||
m_BitsPerSample = reader.ReadInt32();
|
||||
m_Length = reader.ReadSingle();
|
||||
m_IsTrackerFormat = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
m_SubsoundIndex = reader.ReadInt32();
|
||||
m_PreloadAudioData = reader.ReadBoolean();
|
||||
m_LoadInBackground = reader.ReadBoolean();
|
||||
m_Legacy3D = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
m_3D = m_Legacy3D;
|
||||
reader.AlignStream();
|
||||
|
||||
m_Source = reader.ReadAlignedString();
|
||||
m_Offset = reader.ReadInt64();
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace AssetStudio
|
|||
public class Skeleton
|
||||
{
|
||||
public List<Node> m_Node;
|
||||
public List<uint> m_ID;
|
||||
public uint[] m_ID;
|
||||
public List<Axes> m_AxesArray;
|
||||
|
||||
|
||||
|
@ -80,12 +80,7 @@ namespace AssetStudio
|
|||
m_Node.Add(new Node(reader));
|
||||
}
|
||||
|
||||
int numIDs = reader.ReadInt32();
|
||||
m_ID = new List<uint>(numIDs);
|
||||
for (int i = 0; i < numIDs; i++)
|
||||
{
|
||||
m_ID.Add(reader.ReadUInt32());
|
||||
}
|
||||
m_ID = reader.ReadUInt32Array();
|
||||
|
||||
int numAxes = reader.ReadInt32();
|
||||
m_AxesArray = new List<Axes>(numAxes);
|
||||
|
@ -118,16 +113,11 @@ namespace AssetStudio
|
|||
|
||||
public class Hand
|
||||
{
|
||||
public List<int> m_HandBoneIndex;
|
||||
public int[] m_HandBoneIndex;
|
||||
|
||||
public Hand(ObjectReader reader)
|
||||
{
|
||||
int numIndexes = reader.ReadInt32();
|
||||
m_HandBoneIndex = new List<int>(numIndexes);
|
||||
for (int i = 0; i < numIndexes; i++)
|
||||
{
|
||||
m_HandBoneIndex.Add(reader.ReadInt32());
|
||||
}
|
||||
m_HandBoneIndex = reader.ReadInt32Array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,9 +170,9 @@ namespace AssetStudio
|
|||
public Hand m_RightHand;
|
||||
public List<Handle> m_Handles;
|
||||
public List<Collider> m_ColliderArray;
|
||||
public List<int> m_HumanBoneIndex;
|
||||
public List<float> m_HumanBoneMass;
|
||||
public List<int> m_ColliderIndex;
|
||||
public int[] m_HumanBoneIndex;
|
||||
public float[] m_HumanBoneMass;
|
||||
public int[] m_ColliderIndex;
|
||||
public float m_Scale;
|
||||
public float m_ArmTwist;
|
||||
public float m_ForeArmTwist;
|
||||
|
@ -221,28 +211,13 @@ namespace AssetStudio
|
|||
}
|
||||
}
|
||||
|
||||
int numIndexes = reader.ReadInt32();
|
||||
m_HumanBoneIndex = new List<int>(numIndexes);
|
||||
for (int i = 0; i < numIndexes; i++)
|
||||
{
|
||||
m_HumanBoneIndex.Add(reader.ReadInt32());
|
||||
}
|
||||
m_HumanBoneIndex = reader.ReadInt32Array();
|
||||
|
||||
int numMasses = reader.ReadInt32();
|
||||
m_HumanBoneMass = new List<float>(numMasses);
|
||||
for (int i = 0; i < numMasses; i++)
|
||||
{
|
||||
m_HumanBoneMass.Add(reader.ReadSingle());
|
||||
}
|
||||
m_HumanBoneMass = reader.ReadSingleArray();
|
||||
|
||||
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 2)) //2018.2 down
|
||||
{
|
||||
int numColliderIndexes = reader.ReadInt32();
|
||||
m_ColliderIndex = new List<int>(numColliderIndexes);
|
||||
for (int i = 0; i < numColliderIndexes; i++)
|
||||
{
|
||||
m_ColliderIndex.Add(reader.ReadInt32());
|
||||
}
|
||||
m_ColliderIndex = reader.ReadInt32Array();
|
||||
}
|
||||
|
||||
m_Scale = reader.ReadSingle();
|
||||
|
@ -256,7 +231,7 @@ namespace AssetStudio
|
|||
m_HasLeftHand = reader.ReadBoolean();
|
||||
m_HasRightHand = reader.ReadBoolean();
|
||||
m_HasTDoF = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,15 +240,15 @@ namespace AssetStudio
|
|||
public Skeleton m_AvatarSkeleton;
|
||||
public SkeletonPose m_AvatarSkeletonPose;
|
||||
public SkeletonPose m_DefaultPose;
|
||||
public List<uint> m_SkeletonNameIDArray;
|
||||
public uint[] m_SkeletonNameIDArray;
|
||||
public Human m_Human;
|
||||
public List<int> m_HumanSkeletonIndexArray;
|
||||
public List<int> m_HumanSkeletonReverseIndexArray;
|
||||
public int[] m_HumanSkeletonIndexArray;
|
||||
public int[] m_HumanSkeletonReverseIndexArray;
|
||||
public int m_RootMotionBoneIndex;
|
||||
public xform m_RootMotionBoneX;
|
||||
public Skeleton m_RootMotionSkeleton;
|
||||
public SkeletonPose m_RootMotionSkeletonPose;
|
||||
public List<int> m_RootMotionSkeletonIndexArray;
|
||||
public int[] m_RootMotionSkeletonIndexArray;
|
||||
|
||||
public AvatarConstant(ObjectReader reader)
|
||||
{
|
||||
|
@ -284,31 +259,17 @@ namespace AssetStudio
|
|||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
{
|
||||
m_DefaultPose = new SkeletonPose(reader);
|
||||
int numIDs = reader.ReadInt32();
|
||||
m_SkeletonNameIDArray = new List<uint>(numIDs);
|
||||
for (int i = 0; i < numIDs; i++)
|
||||
{
|
||||
m_SkeletonNameIDArray.Add(reader.ReadUInt32());
|
||||
}
|
||||
|
||||
m_SkeletonNameIDArray = reader.ReadUInt32Array();
|
||||
}
|
||||
|
||||
m_Human = new Human(reader);
|
||||
|
||||
int numIndexes = reader.ReadInt32();
|
||||
m_HumanSkeletonIndexArray = new List<int>(numIndexes);
|
||||
for (int i = 0; i < numIndexes; i++)
|
||||
{
|
||||
m_HumanSkeletonIndexArray.Add(reader.ReadInt32());
|
||||
}
|
||||
m_HumanSkeletonIndexArray = reader.ReadInt32Array();
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
{
|
||||
int numReverseIndexes = reader.ReadInt32();
|
||||
m_HumanSkeletonReverseIndexArray = new List<int>(numReverseIndexes);
|
||||
for (int i = 0; i < numReverseIndexes; i++)
|
||||
{
|
||||
m_HumanSkeletonReverseIndexArray.Add(reader.ReadInt32());
|
||||
}
|
||||
m_HumanSkeletonReverseIndexArray = reader.ReadInt32Array();
|
||||
}
|
||||
|
||||
m_RootMotionBoneIndex = reader.ReadInt32();
|
||||
|
@ -319,12 +280,7 @@ namespace AssetStudio
|
|||
m_RootMotionSkeleton = new Skeleton(reader);
|
||||
m_RootMotionSkeletonPose = new SkeletonPose(reader);
|
||||
|
||||
int numMotionIndexes = reader.ReadInt32();
|
||||
m_RootMotionSkeletonIndexArray = new List<int>(numMotionIndexes);
|
||||
for (int i = 0; i < numMotionIndexes; i++)
|
||||
{
|
||||
m_RootMotionSkeletonIndexArray.Add(reader.ReadInt32());
|
||||
}
|
||||
m_RootMotionSkeletonIndexArray = reader.ReadInt32Array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace AssetStudio
|
|||
protected Behaviour(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Enabled = reader.ReadByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,7 @@ namespace AssetStudio
|
|||
|
||||
public BuildSettings(ObjectReader reader) : base(reader)
|
||||
{
|
||||
int levelsNum = reader.ReadInt32();
|
||||
for (int i = 0; i < levelsNum; i++)
|
||||
{
|
||||
var level = reader.ReadAlignedString();
|
||||
}
|
||||
var levels = reader.ReadStringArray();
|
||||
|
||||
var hasRenderTexture = reader.ReadBoolean();
|
||||
var hasPROVersion = reader.ReadBoolean();
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace AssetStudio
|
|||
if (version[0] >= 4)
|
||||
{
|
||||
var flipped = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ namespace AssetStudio
|
|||
if (version[0] <= 3)
|
||||
{
|
||||
var m_GridFont = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
else { float m_PixelScale = reader.ReadSingle(); }
|
||||
|
||||
|
|
|
@ -1,117 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using SharpDX;
|
||||
|
||||
namespace AssetStudio
|
||||
{
|
||||
public class TexEnv
|
||||
public class UnityTexEnv
|
||||
{
|
||||
public string name;
|
||||
public PPtr<Texture> m_Texture;
|
||||
public float[] m_Scale;
|
||||
public float[] m_Offset;
|
||||
public Vector2 m_Scale;
|
||||
public Vector2 m_Offset;
|
||||
|
||||
public UnityTexEnv(ObjectReader reader)
|
||||
{
|
||||
m_Texture = new PPtr<Texture>(reader);
|
||||
m_Scale = reader.ReadVector2();
|
||||
m_Offset = reader.ReadVector2();
|
||||
}
|
||||
}
|
||||
|
||||
public class strFloatPair
|
||||
public class UnityPropertySheet
|
||||
{
|
||||
public string first;
|
||||
public float second;
|
||||
}
|
||||
public List<KeyValuePair<string, UnityTexEnv>> m_TexEnvs;
|
||||
public List<KeyValuePair<string, float>> m_Floats;
|
||||
public List<KeyValuePair<string, Color4>> m_Colors;
|
||||
|
||||
public class strColorPair
|
||||
{
|
||||
public string first;
|
||||
public float[] second;
|
||||
public UnityPropertySheet(ObjectReader reader)
|
||||
{
|
||||
int m_TexEnvsSize = reader.ReadInt32();
|
||||
m_TexEnvs = new List<KeyValuePair<string, UnityTexEnv>>(m_TexEnvsSize);
|
||||
for (int i = 0; i < m_TexEnvsSize; i++)
|
||||
{
|
||||
m_TexEnvs.Add(new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader)));
|
||||
}
|
||||
|
||||
int m_FloatsSize = reader.ReadInt32();
|
||||
m_Floats = new List<KeyValuePair<string, float>>(m_FloatsSize);
|
||||
for (int i = 0; i < m_FloatsSize; i++)
|
||||
{
|
||||
m_Floats.Add(new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle()));
|
||||
}
|
||||
|
||||
int m_ColorsSize = reader.ReadInt32();
|
||||
m_Colors = new List<KeyValuePair<string, Color4>>(m_ColorsSize);
|
||||
for (int i = 0; i < m_ColorsSize; i++)
|
||||
{
|
||||
m_Colors.Add(new KeyValuePair<string, Color4>(reader.ReadAlignedString(), reader.ReadColor4()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Material : NamedObject
|
||||
{
|
||||
public PPtr<Shader> m_Shader;
|
||||
public string[] m_ShaderKeywords;
|
||||
public int m_CustomRenderQueue;
|
||||
public TexEnv[] m_TexEnvs;
|
||||
public strFloatPair[] m_Floats;
|
||||
public strColorPair[] m_Colors;
|
||||
public UnityPropertySheet m_SavedProperties;
|
||||
|
||||
public Material(ObjectReader reader) : base(reader)
|
||||
{
|
||||
m_Shader = new PPtr<Shader>(reader);
|
||||
|
||||
if (version[0] == 4 && (version[1] >= 2 || (version[1] == 1 && !buildType.IsAlpha)))
|
||||
if (version[0] == 4 && version[1] >= 1) //4.x
|
||||
{
|
||||
m_ShaderKeywords = new string[reader.ReadInt32()];
|
||||
for (int i = 0; i < m_ShaderKeywords.Length; i++)
|
||||
{
|
||||
m_ShaderKeywords[i] = reader.ReadAlignedString();
|
||||
}
|
||||
var m_ShaderKeywords = reader.ReadStringArray();
|
||||
}
|
||||
else if (version[0] >= 5)//5.0 and up
|
||||
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
m_ShaderKeywords = new[] { reader.ReadAlignedString() };
|
||||
uint m_LightmapFlags = reader.ReadUInt32();
|
||||
if (version[0] == 5 && version[1] >= 6 || version[0] > 5)//5.6.0 and up
|
||||
var m_ShaderKeywords = reader.ReadAlignedString();
|
||||
var m_LightmapFlags = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||
{
|
||||
var m_EnableInstancingVariants = reader.ReadBoolean();
|
||||
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
{
|
||||
var m_CustomRenderQueue = reader.ReadInt32();
|
||||
}
|
||||
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
|
||||
{
|
||||
var stringTagMapSize = reader.ReadInt32();
|
||||
for (int i = 0; i < stringTagMapSize; i++)
|
||||
{
|
||||
var m_EnableInstancingVariants = reader.ReadBoolean();
|
||||
//var m_DoubleSidedGI = a_Stream.ReadBoolean();//2017.x
|
||||
reader.AlignStream(4);
|
||||
var first = reader.ReadAlignedString();
|
||||
var second = reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
|
||||
if (version[0] > 4 || version[0] == 4 && version[1] >= 3) { m_CustomRenderQueue = reader.ReadInt32(); }
|
||||
|
||||
if (version[0] == 5 && version[1] >= 1 || version[0] > 5)//5.1 and up
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
|
||||
{
|
||||
string[][] stringTagMap = new string[reader.ReadInt32()][];
|
||||
for (int i = 0; i < stringTagMap.Length; i++)
|
||||
{
|
||||
stringTagMap[i] = new[] { reader.ReadAlignedString(), reader.ReadAlignedString() };
|
||||
}
|
||||
}
|
||||
//disabledShaderPasses
|
||||
if ((version[0] == 5 && version[1] >= 6) || version[0] > 5)//5.6.0 and up
|
||||
{
|
||||
var size = reader.ReadInt32();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
reader.ReadAlignedString();
|
||||
}
|
||||
}
|
||||
//m_SavedProperties
|
||||
m_TexEnvs = new TexEnv[reader.ReadInt32()];
|
||||
for (int i = 0; i < m_TexEnvs.Length; i++)
|
||||
{
|
||||
TexEnv m_TexEnv = new TexEnv()
|
||||
{
|
||||
name = reader.ReadAlignedString(),
|
||||
m_Texture = new PPtr<Texture>(reader),
|
||||
m_Scale = new[] { reader.ReadSingle(), reader.ReadSingle() },
|
||||
m_Offset = new[] { reader.ReadSingle(), reader.ReadSingle() }
|
||||
};
|
||||
m_TexEnvs[i] = m_TexEnv;
|
||||
var disabledShaderPasses = reader.ReadStringArray();
|
||||
}
|
||||
|
||||
m_Floats = new strFloatPair[reader.ReadInt32()];
|
||||
for (int i = 0; i < m_Floats.Length; i++)
|
||||
{
|
||||
strFloatPair m_Float = new strFloatPair()
|
||||
{
|
||||
first = reader.ReadAlignedString(),
|
||||
second = reader.ReadSingle()
|
||||
};
|
||||
m_Floats[i] = m_Float;
|
||||
}
|
||||
|
||||
m_Colors = new strColorPair[reader.ReadInt32()];
|
||||
for (int i = 0; i < m_Colors.Length; i++)
|
||||
{
|
||||
strColorPair m_Color = new strColorPair()
|
||||
{
|
||||
first = reader.ReadAlignedString(),
|
||||
second = new[] { reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle() }
|
||||
};
|
||||
m_Colors[i] = m_Color;
|
||||
}
|
||||
m_SavedProperties = new UnityPropertySheet(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace AssetStudio
|
|||
{
|
||||
public List<SubMesh> m_SubMeshes = new List<SubMesh>();
|
||||
public List<uint> m_Indices = new List<uint>(); //use a list because I don't always know the facecount for triangle strips
|
||||
public List<int> m_materialIDs = new List<int>();
|
||||
private uint[] m_IndexBuffer;
|
||||
private ChannelInfo[] m_Channels;
|
||||
private StreamInfo[] m_Streams;
|
||||
|
@ -93,7 +92,7 @@ namespace AssetStudio
|
|||
vertexCount = reader.ReadUInt32();
|
||||
hasNormals = reader.ReadBoolean();
|
||||
hasTangents = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +258,7 @@ namespace AssetStudio
|
|||
{
|
||||
m_IndexBuffer = new uint[m_IndexBuffer_size / 2];
|
||||
for (int i = 0; i < m_IndexBuffer_size / 2; i++) { m_IndexBuffer[i] = reader.ReadUInt16(); }
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -356,7 +355,7 @@ namespace AssetStudio
|
|||
var m_UsedForStaticMeshColliderOnly = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
//This is a bug fixed in 2017.3.1p1 and later versions
|
||||
if ((version[0] > 2017 || (version[0] == 2017 && version[1] >= 4)) || //2017.4
|
||||
((version[0] == 2017 && version[1] == 3 && version[2] == 1) && buildType.IsPatch) || //fixed after 2017.3.1px
|
||||
|
@ -370,13 +369,13 @@ namespace AssetStudio
|
|||
{
|
||||
m_IndexBuffer = new uint[m_IndexBuffer_size / 2];
|
||||
for (int i = 0; i < m_IndexBuffer_size / 2; i++) { m_IndexBuffer[i] = reader.ReadUInt16(); }
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_IndexBuffer = new uint[m_IndexBuffer_size / 4];
|
||||
for (int i = 0; i < m_IndexBuffer_size / 4; i++) { m_IndexBuffer[i] = reader.ReadUInt32(); }
|
||||
reader.AlignStream(4);//untested
|
||||
reader.AlignStream();//untested
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -568,7 +567,7 @@ namespace AssetStudio
|
|||
|
||||
//actual Vertex Buffer
|
||||
var m_DataSize = reader.ReadBytes(reader.ReadInt32());
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
#endregion
|
||||
|
||||
#region compute FvF
|
||||
|
@ -1099,7 +1098,6 @@ namespace AssetStudio
|
|||
m_Indices.Add(m_IndexBuffer[firstIndex + i * 3]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 1]);
|
||||
m_Indices.Add(m_IndexBuffer[firstIndex + i * 3 + 2]);
|
||||
m_materialIDs.Add(s);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1124,7 +1122,6 @@ namespace AssetStudio
|
|||
m_Indices.Add(fc);
|
||||
m_Indices.Add(fb);
|
||||
}
|
||||
m_materialIDs.Add(s);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ namespace AssetStudio
|
|||
{
|
||||
public sealed class MeshFilter : Component
|
||||
{
|
||||
public long preloadIndex;
|
||||
public PPtr<Mesh> m_Mesh;
|
||||
|
||||
public MeshFilter(ObjectReader reader) : base(reader)
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace AssetStudio
|
|||
public MovieTexture(ObjectReader reader) : base(reader)
|
||||
{
|
||||
var m_Loop = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
m_AudioClip = new PPtr<AudioClip>(reader);
|
||||
m_MovieData = reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace AssetStudio
|
|||
var AndroidProfiler = reader.ReadBoolean();
|
||||
//bool AndroidFilterTouchesWhenObscured 2017.2 and up
|
||||
//bool AndroidEnableSustainedPerformanceMode 2018 and up
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
int defaultScreenOrientation = reader.ReadInt32();
|
||||
int targetDevice = reader.ReadInt32();
|
||||
if (version[0] < 5 || (version[0] == 5 && version[1] < 3)) //5.3 down
|
||||
|
@ -38,7 +38,7 @@ namespace AssetStudio
|
|||
else
|
||||
{
|
||||
var useOnDemandResources = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up
|
||||
{
|
||||
|
|
|
@ -9,6 +9,12 @@ namespace AssetStudio
|
|||
{
|
||||
public ushort firstSubMesh;
|
||||
public ushort subMeshCount;
|
||||
|
||||
public StaticBatchInfo(ObjectReader reader)
|
||||
{
|
||||
firstSubMesh = reader.ReadUInt16();
|
||||
subMeshCount = reader.ReadUInt16();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class Renderer : Component
|
||||
|
@ -19,97 +25,114 @@ namespace AssetStudio
|
|||
|
||||
protected Renderer(ObjectReader reader) : base(reader)
|
||||
{
|
||||
if (version[0] < 5)
|
||||
if (version[0] < 5) //5.0 down
|
||||
{
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
var m_CastShadows = reader.ReadByte();
|
||||
var m_CastShadows = reader.ReadBoolean();
|
||||
var m_ReceiveShadows = reader.ReadBoolean();
|
||||
var m_LightmapIndex = reader.ReadByte();
|
||||
}
|
||||
else
|
||||
else //5.0 and up
|
||||
{
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
var m_CastShadows = reader.ReadByte();
|
||||
var m_ReceiveShadows = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
if (version[0] >= 2018)//2018 and up
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||
{
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
var m_CastShadows = reader.ReadByte();
|
||||
var m_ReceiveShadows = reader.ReadByte();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[0] >= 2)) //2017.2 and up
|
||||
{
|
||||
var m_DynamicOccludee = reader.ReadByte();
|
||||
}
|
||||
var m_MotionVectors = reader.ReadByte();
|
||||
var m_LightProbeUsage = reader.ReadByte();
|
||||
var m_ReflectionProbeUsage = reader.ReadByte();
|
||||
reader.AlignStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
var m_Enabled = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
var m_CastShadows = reader.ReadByte();
|
||||
var m_ReceiveShadows = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
{
|
||||
var m_RenderingLayerMask = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
var m_LightmapIndex = reader.ReadUInt16();
|
||||
var m_LightmapIndexDynamic = reader.ReadUInt16();
|
||||
}
|
||||
|
||||
if (version[0] >= 3)
|
||||
if (version[0] >= 3) //3.0 and up
|
||||
{
|
||||
reader.Position += 16;//Vector4f m_LightmapTilingOffset
|
||||
var m_LightmapTilingOffset = reader.ReadVector4();
|
||||
}
|
||||
|
||||
if (version[0] >= 5)
|
||||
if (version[0] >= 5) //5.0 and up
|
||||
{
|
||||
reader.Position += 16;//Vector4f m_LightmapTilingOffsetDynamic
|
||||
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
|
||||
}
|
||||
|
||||
m_Materials = new PPtr<Material>[reader.ReadInt32()];
|
||||
for (int m = 0; m < m_Materials.Length; m++)
|
||||
var m_MaterialsSize = reader.ReadInt32();
|
||||
m_Materials = new PPtr<Material>[m_MaterialsSize];
|
||||
for (int i = 0; i < m_MaterialsSize; i++)
|
||||
{
|
||||
m_Materials[m] = new PPtr<Material>(reader);
|
||||
m_Materials[i] = new PPtr<Material>(reader);
|
||||
}
|
||||
|
||||
if (version[0] < 3)
|
||||
if (version[0] < 3) //3.0 down
|
||||
{
|
||||
reader.Position += 16;//m_LightmapTilingOffset vector4d
|
||||
var m_LightmapTilingOffset = reader.ReadVector4();
|
||||
}
|
||||
else
|
||||
else //3.0 and up
|
||||
{
|
||||
if ((version[0] == 5 && version[1] >= 5) || version[0] > 5)//5.5.0 and up
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 5)) //5.5 and up
|
||||
{
|
||||
m_StaticBatchInfo = new StaticBatchInfo
|
||||
{
|
||||
firstSubMesh = reader.ReadUInt16(),
|
||||
subMeshCount = reader.ReadUInt16()
|
||||
};
|
||||
m_StaticBatchInfo = new StaticBatchInfo(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
int numSubsetIndices = reader.ReadInt32();
|
||||
m_SubsetIndices = reader.ReadUInt32Array(numSubsetIndices);
|
||||
m_SubsetIndices = reader.ReadUInt32Array();
|
||||
}
|
||||
|
||||
var m_StaticBatchRoot = new PPtr<Transform>(reader);
|
||||
}
|
||||
|
||||
if ((version[0] == 5 && version[1] >= 4) || version[0] > 5)//5.4.0 and up
|
||||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
|
||||
{
|
||||
var m_ProbeAnchor = new PPtr<Transform>(reader);
|
||||
var m_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
|
||||
}
|
||||
else if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 - 5.3
|
||||
{
|
||||
var m_UseLightProbes = reader.ReadBoolean();
|
||||
reader.AlignStream();
|
||||
|
||||
if (version[0] >= 5)//5.0 and up
|
||||
{
|
||||
var m_ProbeAnchor = new PPtr<Transform>(reader);
|
||||
var m_LightProbeVolumeOverride = new PPtr<GameObject>(reader);
|
||||
}
|
||||
else if (version[0] >= 4 || (version[0] == 3 && version[1] >= 5))//3.5 - 5.3
|
||||
{
|
||||
var m_UseLightProbes = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
if (version[0] == 5)//5.0 and up
|
||||
{
|
||||
int m_ReflectionProbeUsage = reader.ReadInt32();
|
||||
}
|
||||
var m_LightProbeAnchor = new PPtr<Transform>(reader);
|
||||
var m_ReflectionProbeUsage = reader.ReadInt32();
|
||||
}
|
||||
|
||||
if (version[0] >= 5 || (version[0] == 4 && version[1] >= 3))//4.3 and up
|
||||
{
|
||||
if (version[0] == 4 && version[1] == 3)//4.3
|
||||
{
|
||||
int m_SortingLayer = reader.ReadInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
int m_SortingLayerID = reader.ReadInt32();
|
||||
//SInt16 m_SortingOrder 5.6 and up
|
||||
}
|
||||
var m_LightProbeAnchor = new PPtr<Transform>(reader); //5.0 and up m_ProbeAnchor
|
||||
}
|
||||
|
||||
int m_SortingOrder = reader.ReadInt16();
|
||||
reader.AlignStream(4);
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
{
|
||||
if (version[0] == 4 && version[1] == 3) //4.3
|
||||
{
|
||||
var m_SortingLayer = reader.ReadInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
var m_SortingLayerID = reader.ReadUInt32();
|
||||
}
|
||||
|
||||
//SInt16 m_SortingLayer 5.6 and up
|
||||
var m_SortingOrder = reader.ReadInt16();
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,34 +81,20 @@ namespace AssetStudio
|
|||
{
|
||||
public string m_Name;
|
||||
public string m_Description;
|
||||
public List<string> m_Attributes;
|
||||
public string[] m_Attributes;
|
||||
public SerializedPropertyType m_Type;
|
||||
public uint m_Flags;
|
||||
public List<float> m_DefValue;
|
||||
public float[] m_DefValue;
|
||||
public SerializedTextureProperty m_DefTexture;
|
||||
|
||||
public SerializedProperty(BinaryReader reader)
|
||||
{
|
||||
m_Name = reader.ReadAlignedString();
|
||||
m_Description = reader.ReadAlignedString();
|
||||
|
||||
int numAttributes = reader.ReadInt32();
|
||||
m_Attributes = new List<string>(numAttributes);
|
||||
for (int i = 0; i < numAttributes; i++)
|
||||
{
|
||||
m_Attributes.Add(reader.ReadAlignedString());
|
||||
}
|
||||
|
||||
m_Attributes = reader.ReadStringArray();
|
||||
m_Type = (SerializedPropertyType)reader.ReadInt32();
|
||||
m_Flags = reader.ReadUInt32();
|
||||
|
||||
int numValues = 4;
|
||||
m_DefValue = new List<float>(numValues);
|
||||
for (int i = 0; i < numValues; i++)
|
||||
{
|
||||
m_DefValue.Add(reader.ReadSingle());
|
||||
}
|
||||
|
||||
m_DefValue = reader.ReadSingleArray(4);
|
||||
m_DefTexture = new SerializedTextureProperty(reader);
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +241,7 @@ namespace AssetStudio
|
|||
rtBlend6 = new SerializedShaderRTBlendState(reader);
|
||||
rtBlend7 = new SerializedShaderRTBlendState(reader);
|
||||
rtSeparateBlend = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
|
||||
{
|
||||
zClip = new SerializedShaderFloatValue(reader);
|
||||
|
@ -281,7 +267,7 @@ namespace AssetStudio
|
|||
m_Tags = new SerializedTagMap(reader);
|
||||
m_LOD = reader.ReadInt32();
|
||||
lighting = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +296,7 @@ namespace AssetStudio
|
|||
{
|
||||
m_Channels.Add(new ShaderBindChannel(reader));
|
||||
}
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
m_SourceMap = reader.ReadUInt32();
|
||||
}
|
||||
|
@ -331,7 +317,7 @@ namespace AssetStudio
|
|||
m_ArraySize = reader.ReadInt32();
|
||||
m_Type = reader.ReadSByte();
|
||||
m_Dim = reader.ReadSByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,7 +336,7 @@ namespace AssetStudio
|
|||
m_ArraySize = reader.ReadInt32();
|
||||
m_Type = reader.ReadSByte();
|
||||
m_RowCount = reader.ReadSByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -373,7 +359,7 @@ namespace AssetStudio
|
|||
var m_MultiSampled = reader.ReadBoolean();
|
||||
}
|
||||
m_Dim = reader.ReadSByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,7 +464,7 @@ namespace AssetStudio
|
|||
{
|
||||
public uint m_BlobIndex;
|
||||
public ParserBindChannels m_Channels;
|
||||
public List<ushort> m_KeywordIndices;
|
||||
public ushort[] m_KeywordIndices;
|
||||
public sbyte m_ShaderHardwareTier;
|
||||
public ShaderGpuProgramType m_GpuProgramType;
|
||||
public List<VectorParameter> m_VectorParams;
|
||||
|
@ -497,19 +483,14 @@ namespace AssetStudio
|
|||
m_BlobIndex = reader.ReadUInt32();
|
||||
m_Channels = new ParserBindChannels(reader);
|
||||
|
||||
int numIndices = reader.ReadInt32();
|
||||
m_KeywordIndices = new List<ushort>(numIndices);
|
||||
for (int i = 0; i < numIndices; i++)
|
||||
{
|
||||
m_KeywordIndices.Add(reader.ReadUInt16());
|
||||
}
|
||||
m_KeywordIndices = reader.ReadUInt16Array();
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
m_ShaderHardwareTier = reader.ReadSByte();
|
||||
m_GpuProgramType = (ShaderGpuProgramType)reader.ReadSByte();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
int numVectorParams = reader.ReadInt32();
|
||||
m_VectorParams = new List<VectorParameter>(numVectorParams);
|
||||
|
@ -639,7 +620,7 @@ namespace AssetStudio
|
|||
{
|
||||
var m_HasProceduralInstancingVariant = reader.ReadBoolean();
|
||||
}
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
m_UseName = reader.ReadAlignedString();
|
||||
m_Name = reader.ReadAlignedString();
|
||||
m_TextureName = reader.ReadAlignedString();
|
||||
|
@ -727,7 +708,7 @@ namespace AssetStudio
|
|||
}
|
||||
|
||||
m_DisableNoSubshadersMessage = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -739,10 +720,10 @@ namespace AssetStudio
|
|||
public byte[] m_SubProgramBlob;
|
||||
//5.5 and up
|
||||
public SerializedShader m_ParsedForm;
|
||||
public List<uint> platforms;
|
||||
public List<uint> offsets;
|
||||
public List<uint> compressedLengths;
|
||||
public List<uint> decompressedLengths;
|
||||
public uint[] platforms;
|
||||
public uint[] offsets;
|
||||
public uint[] compressedLengths;
|
||||
public uint[] decompressedLengths;
|
||||
public byte[] compressedBlob;
|
||||
|
||||
public Shader(ObjectReader reader) : base(reader)
|
||||
|
@ -750,40 +731,16 @@ namespace AssetStudio
|
|||
if (version[0] == 5 && version[1] >= 5 || version[0] > 5) //5.5 and up
|
||||
{
|
||||
m_ParsedForm = new SerializedShader(reader);
|
||||
int numPlatforms = reader.ReadInt32();
|
||||
platforms = new List<uint>(numPlatforms);
|
||||
for (int i = 0; i < numPlatforms; i++)
|
||||
{
|
||||
platforms.Add(reader.ReadUInt32());
|
||||
}
|
||||
|
||||
int numOffsets = reader.ReadInt32();
|
||||
offsets = new List<uint>(numOffsets);
|
||||
for (int i = 0; i < numOffsets; i++)
|
||||
{
|
||||
offsets.Add(reader.ReadUInt32());
|
||||
}
|
||||
|
||||
int numCompressedLengths = reader.ReadInt32();
|
||||
compressedLengths = new List<uint>(numCompressedLengths);
|
||||
for (int i = 0; i < numCompressedLengths; i++)
|
||||
{
|
||||
compressedLengths.Add(reader.ReadUInt32());
|
||||
}
|
||||
|
||||
int numDecompressedLengths = reader.ReadInt32();
|
||||
decompressedLengths = new List<uint>(numDecompressedLengths);
|
||||
for (int i = 0; i < numDecompressedLengths; i++)
|
||||
{
|
||||
decompressedLengths.Add(reader.ReadUInt32());
|
||||
}
|
||||
|
||||
platforms = reader.ReadUInt32Array();
|
||||
offsets = reader.ReadUInt32Array();
|
||||
compressedLengths = reader.ReadUInt32Array();
|
||||
decompressedLengths = reader.ReadUInt32Array();
|
||||
compressedBlob = reader.ReadBytes(reader.ReadInt32());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Script = reader.ReadBytes(reader.ReadInt32());
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
var m_PathName = reader.ReadAlignedString();
|
||||
if (version[0] == 5 && version[1] >= 3) //5.3 - 5.4
|
||||
{
|
||||
|
|
|
@ -9,16 +9,16 @@ namespace AssetStudio
|
|||
{
|
||||
public PPtr<Mesh> m_Mesh;
|
||||
public PPtr<Transform>[] m_Bones;
|
||||
public List<float> m_BlendShapeWeights;
|
||||
public float[] m_BlendShapeWeights;
|
||||
|
||||
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
|
||||
{
|
||||
int m_Quality = reader.ReadInt32();
|
||||
var m_UpdateWhenOffscreen = reader.ReadBoolean();
|
||||
var m_SkinNormals = reader.ReadBoolean(); //3.1.0 and below
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
if (version[0] == 2 && version[1] < 6)//2.6 down
|
||||
if (version[0] == 2 && version[1] < 6) //2.6 down
|
||||
{
|
||||
var m_DisableAnimationWhenOffscreen = new PPtr<Animation>(reader);
|
||||
}
|
||||
|
@ -31,22 +31,9 @@ namespace AssetStudio
|
|||
m_Bones[b] = new PPtr<Transform>(reader);
|
||||
}
|
||||
|
||||
if (version[0] < 3)
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
|
||||
{
|
||||
int m_BindPose = reader.ReadInt32();
|
||||
reader.Position += m_BindPose * 16 * 4;//Matrix4x4f
|
||||
}
|
||||
else
|
||||
{
|
||||
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))//4.3 and up
|
||||
{
|
||||
int numBSWeights = reader.ReadInt32();
|
||||
m_BlendShapeWeights = new List<float>(numBSWeights);
|
||||
for (int i = 0; i < numBSWeights; i++)
|
||||
{
|
||||
m_BlendShapeWeights.Add(reader.ReadSingle());
|
||||
}
|
||||
}
|
||||
m_BlendShapeWeights = reader.ReadSingleArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ namespace AssetStudio
|
|||
}
|
||||
|
||||
m_DataSize = reader.ReadBytes(reader.ReadInt32());
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ namespace AssetStudio
|
|||
}
|
||||
|
||||
m_IndexBuffer = reader.ReadBytes(reader.ReadInt32());
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
m_VertexData = new VertexData(reader);
|
||||
}
|
||||
|
@ -257,13 +257,13 @@ namespace AssetStudio
|
|||
vertices[i] = new SpriteVertex(reader);
|
||||
}
|
||||
|
||||
indices = reader.ReadUInt16Array(reader.ReadInt32());
|
||||
reader.AlignStream(4);
|
||||
indices = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2018) //2018 and up
|
||||
{
|
||||
m_Bindpose = reader.ReadMatrixArray(reader.ReadInt32());
|
||||
m_Bindpose = reader.ReadMatrixArray();
|
||||
|
||||
if (version[0] == 2018 && version[1] < 2) //2018.2 down
|
||||
{
|
||||
|
@ -331,7 +331,7 @@ namespace AssetStudio
|
|||
if (version[0] > 5 || (version[0] == 5 && version[1] >= 3)) //5.3 and up
|
||||
{
|
||||
m_IsPolygon = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
if (version[0] >= 2017) //2017 and up
|
||||
|
@ -340,12 +340,7 @@ namespace AssetStudio
|
|||
var second = reader.ReadInt64();
|
||||
m_RenderDataKey = new KeyValuePair<Guid, long>(first, second);
|
||||
|
||||
var m_AtlasTagsSize = reader.ReadInt32();
|
||||
m_AtlasTags = new string[m_AtlasTagsSize];
|
||||
for (int i = 0; i < m_AtlasTagsSize; i++)
|
||||
{
|
||||
m_AtlasTags[i] = reader.ReadAlignedString();
|
||||
}
|
||||
m_AtlasTags = reader.ReadStringArray();
|
||||
|
||||
m_SpriteAtlas = new PPtr<SpriteAtlas>(reader);
|
||||
}
|
||||
|
@ -358,7 +353,7 @@ namespace AssetStudio
|
|||
m_PhysicsShape = new Vector2[m_PhysicsShapeSize][];
|
||||
for (int i = 0; i < m_PhysicsShapeSize; i++)
|
||||
{
|
||||
m_PhysicsShape[i] = reader.ReadVector2Array(reader.ReadInt32());
|
||||
m_PhysicsShape[i] = reader.ReadVector2Array();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,11 +44,7 @@ namespace AssetStudio
|
|||
new PPtr<Sprite>(reader);
|
||||
}
|
||||
|
||||
var m_PackedSpriteNamesToIndexSize = reader.ReadInt32();
|
||||
for (int i = 0; i < m_PackedSpriteNamesToIndexSize; i++)
|
||||
{
|
||||
reader.ReadAlignedString();
|
||||
}
|
||||
var m_PackedSpriteNamesToIndex = reader.ReadStringArray();
|
||||
|
||||
var m_RenderDataMapSize = reader.ReadInt32();
|
||||
m_RenderDataMap = new Dictionary<KeyValuePair<Guid, long>, SpriteAtlasData>(m_RenderDataMapSize);
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace AssetStudio
|
|||
{
|
||||
var m_ForcedFallbackFormat = reader.ReadInt32();
|
||||
var m_DownscaleFallback = reader.ReadBoolean();
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace AssetStudio
|
|||
m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
|
||||
m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
|
||||
//m_StreamingMipmaps 2018.2 and up
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
|
||||
{
|
||||
var m_StreamingMipmapsPriority = reader.ReadInt32();
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace AssetStudio
|
|||
var m_ProxyHeight = reader.ReadUInt32();
|
||||
var Width = reader.ReadUInt32();
|
||||
var Height = reader.ReadUInt32();
|
||||
if (version[0] >= 2017)//2017.x and up
|
||||
if (version[0] >= 2017) //2017.x and up
|
||||
{
|
||||
var m_PixelAspecRatioNum = reader.ReadUInt32();
|
||||
var m_PixelAspecRatioDen = reader.ReadUInt32();
|
||||
|
@ -28,19 +28,10 @@ namespace AssetStudio
|
|||
var m_FrameRate = reader.ReadDouble();
|
||||
var m_FrameCount = reader.ReadUInt64();
|
||||
var m_Format = reader.ReadInt32();
|
||||
//m_AudioChannelCount
|
||||
var size = reader.ReadInt32();
|
||||
reader.Position += size * 2;
|
||||
reader.AlignStream(4);
|
||||
//m_AudioSampleRate
|
||||
size = reader.ReadInt32();
|
||||
reader.Position += size * 4;
|
||||
//m_AudioLanguage
|
||||
size = reader.ReadInt32();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
reader.ReadAlignedString();
|
||||
}
|
||||
var m_AudioChannelCount = reader.ReadUInt16Array();
|
||||
reader.AlignStream();
|
||||
var m_AudioSampleRate = reader.ReadUInt32Array();
|
||||
var m_AudioLanguage = reader.ReadStringArray();
|
||||
//StreamedResource m_ExternalResources
|
||||
m_Source = reader.ReadAlignedString();
|
||||
var m_Offset = reader.ReadUInt64();
|
||||
|
|
|
@ -8,6 +8,11 @@ namespace AssetStudio
|
|||
{
|
||||
public static class BinaryReaderExtensions
|
||||
{
|
||||
public static void AlignStream(this BinaryReader reader)
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
}
|
||||
|
||||
public static void AlignStream(this BinaryReader reader, int alignment)
|
||||
{
|
||||
var pos = reader.BaseStream.Position;
|
||||
|
@ -65,6 +70,11 @@ namespace AssetStudio
|
|||
return new System.Drawing.RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||
}
|
||||
|
||||
public static Color4 ReadColor4(this BinaryReader reader)
|
||||
{
|
||||
return new Color4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||
}
|
||||
|
||||
public static Matrix ReadMatrix(this BinaryReader reader)
|
||||
{
|
||||
var m = new Matrix();
|
||||
|
@ -81,21 +91,41 @@ namespace AssetStudio
|
|||
private static T[] ReadArray<T>(Func<T> del, int length)
|
||||
{
|
||||
var array = new T[length];
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
array[i] = del();
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static bool[] ReadBooleanArray(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadBoolean, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static ushort[] ReadUInt16Array(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadUInt16, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static int[] ReadInt32Array(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadInt32, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static int[] ReadInt32Array(this BinaryReader reader, int length)
|
||||
{
|
||||
return ReadArray(reader.ReadInt32, length);
|
||||
}
|
||||
|
||||
public static uint[] ReadUInt32Array(this BinaryReader reader, int length)
|
||||
public static uint[] ReadUInt32Array(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadUInt32, length);
|
||||
return ReadArray(reader.ReadUInt32, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static float[] ReadSingleArray(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadSingle, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static float[] ReadSingleArray(this BinaryReader reader, int length)
|
||||
|
@ -103,24 +133,24 @@ namespace AssetStudio
|
|||
return ReadArray(reader.ReadSingle, length);
|
||||
}
|
||||
|
||||
public static Vector2[] ReadVector2Array(this BinaryReader reader, int length)
|
||||
public static string[] ReadStringArray(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadVector2, length);
|
||||
return ReadArray(reader.ReadAlignedString, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static Vector4[] ReadVector4Array(this BinaryReader reader, int length)
|
||||
public static Vector2[] ReadVector2Array(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadVector4, length);
|
||||
return ReadArray(reader.ReadVector2, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static ushort[] ReadUInt16Array(this BinaryReader reader, int length)
|
||||
public static Vector4[] ReadVector4Array(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadUInt16, length);
|
||||
return ReadArray(reader.ReadVector4, reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static Matrix[] ReadMatrixArray(this BinaryReader reader, int length)
|
||||
public static Matrix[] ReadMatrixArray(this BinaryReader reader)
|
||||
{
|
||||
return ReadArray(reader.ReadMatrix, length);
|
||||
return ReadArray(reader.ReadMatrix, reader.ReadInt32());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ namespace AssetStudio
|
|||
public string upperFileName;
|
||||
public int[] version = { 0, 0, 0, 0 };
|
||||
public BuildType buildType;
|
||||
public bool valid;
|
||||
public Dictionary<long, Object> Objects;
|
||||
|
||||
public SerializedFileHeader header;
|
||||
|
@ -36,151 +35,143 @@ namespace AssetStudio
|
|||
this.fullName = fullName;
|
||||
fileName = Path.GetFileName(fullName);
|
||||
upperFileName = fileName.ToUpper();
|
||||
try
|
||||
{
|
||||
//ReadHeader
|
||||
header = new SerializedFileHeader();
|
||||
header.m_MetadataSize = reader.ReadUInt32();
|
||||
header.m_FileSize = reader.ReadUInt32();
|
||||
header.m_Version = reader.ReadUInt32();
|
||||
header.m_DataOffset = reader.ReadUInt32();
|
||||
|
||||
if (header.m_Version >= 9)
|
||||
//ReadHeader
|
||||
header = new SerializedFileHeader();
|
||||
header.m_MetadataSize = reader.ReadUInt32();
|
||||
header.m_FileSize = reader.ReadUInt32();
|
||||
header.m_Version = reader.ReadUInt32();
|
||||
header.m_DataOffset = reader.ReadUInt32();
|
||||
|
||||
if (header.m_Version >= 9)
|
||||
{
|
||||
header.m_Endianess = reader.ReadByte();
|
||||
header.m_Reserved = reader.ReadBytes(3);
|
||||
m_FileEndianess = (EndianType)header.m_Endianess;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Position = header.m_FileSize - header.m_MetadataSize;
|
||||
m_FileEndianess = (EndianType)reader.ReadByte();
|
||||
}
|
||||
|
||||
//ReadMetadata
|
||||
if (m_FileEndianess == EndianType.LittleEndian)
|
||||
{
|
||||
reader.endian = EndianType.LittleEndian;
|
||||
}
|
||||
if (header.m_Version >= 7)
|
||||
{
|
||||
unityVersion = reader.ReadStringToNull();
|
||||
SetVersion(unityVersion);
|
||||
}
|
||||
if (header.m_Version >= 8)
|
||||
{
|
||||
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
|
||||
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
|
||||
{
|
||||
header.m_Endianess = reader.ReadByte();
|
||||
header.m_Reserved = reader.ReadBytes(3);
|
||||
m_FileEndianess = (EndianType)header.m_Endianess;
|
||||
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||
}
|
||||
}
|
||||
if (header.m_Version >= 13)
|
||||
{
|
||||
m_EnableTypeTree = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
//ReadTypes
|
||||
int typeCount = reader.ReadInt32();
|
||||
m_Types = new List<SerializedType>(typeCount);
|
||||
for (int i = 0; i < typeCount; i++)
|
||||
{
|
||||
m_Types.Add(ReadSerializedType());
|
||||
}
|
||||
|
||||
if (header.m_Version >= 7 && header.m_Version < 14)
|
||||
{
|
||||
var bigIDEnabled = reader.ReadInt32();
|
||||
}
|
||||
|
||||
//ReadObjects
|
||||
int objectCount = reader.ReadInt32();
|
||||
m_Objects = new List<ObjectInfo>(objectCount);
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
var objectInfo = new ObjectInfo();
|
||||
if (header.m_Version < 14)
|
||||
{
|
||||
objectInfo.m_PathID = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Position = header.m_FileSize - header.m_MetadataSize;
|
||||
m_FileEndianess = (EndianType)reader.ReadByte();
|
||||
reader.AlignStream();
|
||||
objectInfo.m_PathID = reader.ReadInt64();
|
||||
}
|
||||
objectInfo.byteStart = reader.ReadUInt32();
|
||||
objectInfo.byteStart += header.m_DataOffset;
|
||||
objectInfo.byteSize = reader.ReadUInt32();
|
||||
objectInfo.typeID = reader.ReadInt32();
|
||||
if (header.m_Version < 16)
|
||||
{
|
||||
objectInfo.classID = reader.ReadUInt16();
|
||||
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
|
||||
var isDestroyed = reader.ReadUInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = m_Types[objectInfo.typeID];
|
||||
objectInfo.serializedType = type;
|
||||
objectInfo.classID = type.classID;
|
||||
}
|
||||
if (header.m_Version == 15 || header.m_Version == 16)
|
||||
{
|
||||
var stripped = reader.ReadByte();
|
||||
}
|
||||
m_Objects.Add(objectInfo);
|
||||
}
|
||||
|
||||
//ReadMetadata
|
||||
if (m_FileEndianess == EndianType.LittleEndian)
|
||||
if (header.m_Version >= 11)
|
||||
{
|
||||
int scriptCount = reader.ReadInt32();
|
||||
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
|
||||
for (int i = 0; i < scriptCount; i++)
|
||||
{
|
||||
reader.endian = EndianType.LittleEndian;
|
||||
}
|
||||
if (header.m_Version >= 7)
|
||||
{
|
||||
unityVersion = reader.ReadStringToNull();
|
||||
SetVersion(unityVersion);
|
||||
}
|
||||
if (header.m_Version >= 8)
|
||||
{
|
||||
m_TargetPlatform = (BuildTarget)reader.ReadInt32();
|
||||
if (!Enum.IsDefined(typeof(BuildTarget), m_TargetPlatform))
|
||||
{
|
||||
m_TargetPlatform = BuildTarget.UnknownPlatform;
|
||||
}
|
||||
}
|
||||
if (header.m_Version >= 13)
|
||||
{
|
||||
m_EnableTypeTree = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
//ReadTypes
|
||||
int typeCount = reader.ReadInt32();
|
||||
m_Types = new List<SerializedType>(typeCount);
|
||||
for (int i = 0; i < typeCount; i++)
|
||||
{
|
||||
m_Types.Add(ReadSerializedType());
|
||||
}
|
||||
|
||||
if (header.m_Version >= 7 && header.m_Version < 14)
|
||||
{
|
||||
var bigIDEnabled = reader.ReadInt32();
|
||||
}
|
||||
|
||||
//ReadObjects
|
||||
int objectCount = reader.ReadInt32();
|
||||
m_Objects = new List<ObjectInfo>(objectCount);
|
||||
for (int i = 0; i < objectCount; i++)
|
||||
{
|
||||
var objectInfo = new ObjectInfo();
|
||||
var m_ScriptType = new LocalSerializedObjectIdentifier();
|
||||
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
|
||||
if (header.m_Version < 14)
|
||||
{
|
||||
objectInfo.m_PathID = reader.ReadInt32();
|
||||
m_ScriptType.localIdentifierInFile = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
objectInfo.m_PathID = reader.ReadInt64();
|
||||
reader.AlignStream();
|
||||
m_ScriptType.localIdentifierInFile = reader.ReadInt64();
|
||||
}
|
||||
objectInfo.byteStart = reader.ReadUInt32();
|
||||
objectInfo.byteStart += header.m_DataOffset;
|
||||
objectInfo.byteSize = reader.ReadUInt32();
|
||||
objectInfo.typeID = reader.ReadInt32();
|
||||
if (header.m_Version < 16)
|
||||
{
|
||||
objectInfo.classID = reader.ReadUInt16();
|
||||
objectInfo.serializedType = m_Types.Find(x => x.classID == objectInfo.typeID);
|
||||
var isDestroyed = reader.ReadUInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
var type = m_Types[objectInfo.typeID];
|
||||
objectInfo.serializedType = type;
|
||||
objectInfo.classID = type.classID;
|
||||
}
|
||||
if (header.m_Version == 15 || header.m_Version == 16)
|
||||
{
|
||||
var stripped = reader.ReadByte();
|
||||
}
|
||||
m_Objects.Add(objectInfo);
|
||||
m_ScriptTypes.Add(m_ScriptType);
|
||||
}
|
||||
}
|
||||
|
||||
if (header.m_Version >= 11)
|
||||
int externalsCount = reader.ReadInt32();
|
||||
m_Externals = new List<FileIdentifier>(externalsCount);
|
||||
for (int i = 0; i < externalsCount; i++)
|
||||
{
|
||||
var m_External = new FileIdentifier();
|
||||
if (header.m_Version >= 6)
|
||||
{
|
||||
int scriptCount = reader.ReadInt32();
|
||||
m_ScriptTypes = new List<LocalSerializedObjectIdentifier>(scriptCount);
|
||||
for (int i = 0; i < scriptCount; i++)
|
||||
{
|
||||
var m_ScriptType = new LocalSerializedObjectIdentifier();
|
||||
m_ScriptType.localSerializedFileIndex = reader.ReadInt32();
|
||||
if (header.m_Version < 14)
|
||||
{
|
||||
m_ScriptType.localIdentifierInFile = reader.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.AlignStream(4);
|
||||
m_ScriptType.localIdentifierInFile = reader.ReadInt64();
|
||||
}
|
||||
m_ScriptTypes.Add(m_ScriptType);
|
||||
}
|
||||
var tempEmpty = reader.ReadStringToNull();
|
||||
}
|
||||
|
||||
int externalsCount = reader.ReadInt32();
|
||||
m_Externals = new List<FileIdentifier>(externalsCount);
|
||||
for (int i = 0; i < externalsCount; i++)
|
||||
{
|
||||
var m_External = new FileIdentifier();
|
||||
if (header.m_Version >= 6)
|
||||
{
|
||||
var tempEmpty = reader.ReadStringToNull();
|
||||
}
|
||||
if (header.m_Version >= 5)
|
||||
{
|
||||
m_External.guid = new Guid(reader.ReadBytes(16));
|
||||
m_External.type = reader.ReadInt32();
|
||||
}
|
||||
m_External.pathName = reader.ReadStringToNull();
|
||||
m_External.fileName = Path.GetFileName(m_External.pathName);
|
||||
m_Externals.Add(m_External);
|
||||
}
|
||||
|
||||
if (header.m_Version >= 5)
|
||||
{
|
||||
//var userInformation = reader.ReadStringToNull();
|
||||
m_External.guid = new Guid(reader.ReadBytes(16));
|
||||
m_External.type = reader.ReadInt32();
|
||||
}
|
||||
|
||||
valid = true;
|
||||
m_External.pathName = reader.ReadStringToNull();
|
||||
m_External.fileName = Path.GetFileName(m_External.pathName);
|
||||
m_Externals.Add(m_External);
|
||||
}
|
||||
catch
|
||||
|
||||
if (header.m_Version >= 5)
|
||||
{
|
||||
// ignored
|
||||
//var userInformation = reader.ReadStringToNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ namespace AssetStudio
|
|||
if (append)
|
||||
sb.AppendFormat("{0}{1} {2} = {3}\r\n", (new string('\t', level)), varTypeStr, varNameStr, value);
|
||||
if (align)
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> ReadBoxingType(List<TypeTreeNode> members, BinaryReader reader)
|
||||
|
@ -284,7 +284,7 @@ namespace AssetStudio
|
|||
}
|
||||
}
|
||||
if (align)
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -482,7 +482,7 @@ namespace AssetStudio
|
|||
lastGroup = group;
|
||||
}
|
||||
|
||||
morph.Channels.Add(new Tuple<float, int, int>(i < sMesh.m_BlendShapeWeights.Count ? sMesh.m_BlendShapeWeights[i] : 0f, morph.KeyframeList.Count, mesh.m_Shapes.channels[i].frameCount));
|
||||
morph.Channels.Add(new Tuple<float, int, int>(i < sMesh.m_BlendShapeWeights.Length ? sMesh.m_BlendShapeWeights[i] : 0f, morph.KeyframeList.Count, mesh.m_Shapes.channels[i].frameCount));
|
||||
for (int frameIdx = 0; frameIdx < mesh.m_Shapes.channels[i].frameCount; frameIdx++)
|
||||
{
|
||||
ImportedMorphKeyframe keyframe = new ImportedMorphKeyframe();
|
||||
|
@ -596,22 +596,21 @@ namespace AssetStudio
|
|||
}
|
||||
iMat = new ImportedMaterial();
|
||||
iMat.Name = mat.m_Name;
|
||||
foreach (var col in mat.m_Colors)
|
||||
foreach (var col in mat.m_SavedProperties.m_Colors)
|
||||
{
|
||||
var color = new Color4(col.second[0], col.second[1], col.second[2], col.second[3]);
|
||||
switch (col.first)
|
||||
switch (col.Key)
|
||||
{
|
||||
case "_Color":
|
||||
iMat.Diffuse = color;
|
||||
iMat.Diffuse = col.Value;
|
||||
break;
|
||||
case "_SColor":
|
||||
iMat.Ambient = color;
|
||||
iMat.Ambient = col.Value;
|
||||
break;
|
||||
case "_EmissionColor":
|
||||
iMat.Emissive = color;
|
||||
iMat.Emissive = col.Value;
|
||||
break;
|
||||
case "_SpecColor":
|
||||
iMat.Specular = color;
|
||||
iMat.Specular = col.Value;
|
||||
break;
|
||||
case "_RimColor":
|
||||
case "_OutlineColor":
|
||||
|
@ -620,12 +619,12 @@ namespace AssetStudio
|
|||
}
|
||||
}
|
||||
|
||||
foreach (var flt in mat.m_Floats)
|
||||
foreach (var flt in mat.m_SavedProperties.m_Floats)
|
||||
{
|
||||
switch (flt.first)
|
||||
switch (flt.Key)
|
||||
{
|
||||
case "_Shininess":
|
||||
iMat.Power = flt.second;
|
||||
iMat.Power = flt.Value;
|
||||
break;
|
||||
case "_RimPower":
|
||||
case "_Outline":
|
||||
|
@ -637,10 +636,10 @@ namespace AssetStudio
|
|||
iMat.Textures = new string[5];
|
||||
iMat.TexOffsets = new Vector2[5];
|
||||
iMat.TexScales = new Vector2[5];
|
||||
foreach (var texEnv in mat.m_TexEnvs)
|
||||
foreach (var texEnv in mat.m_SavedProperties.m_TexEnvs)
|
||||
{
|
||||
Texture2D m_Texture2D = null;
|
||||
if (texEnv.m_Texture.TryGet<Texture2D>(out var m_Texture)) //TODO other Texture
|
||||
if (texEnv.Value.m_Texture.TryGet<Texture2D>(out var m_Texture)) //TODO other Texture
|
||||
{
|
||||
m_Texture2D = m_Texture;
|
||||
}
|
||||
|
@ -650,13 +649,13 @@ namespace AssetStudio
|
|||
continue;
|
||||
}
|
||||
int dest = -1;
|
||||
if (texEnv.name == "_MainTex")
|
||||
if (texEnv.Key == "_MainTex")
|
||||
dest = 0;
|
||||
else if (texEnv.name == "_BumpMap")
|
||||
else if (texEnv.Key == "_BumpMap")
|
||||
dest = 4;
|
||||
else if (texEnv.name.Contains("Spec"))
|
||||
else if (texEnv.Key.Contains("Spec"))
|
||||
dest = 2;
|
||||
else if (texEnv.name.Contains("Norm"))
|
||||
else if (texEnv.Key.Contains("Norm"))
|
||||
dest = 3;
|
||||
if (dest < 0 || iMat.Textures[dest] != null)
|
||||
{
|
||||
|
@ -685,8 +684,8 @@ namespace AssetStudio
|
|||
iMat.Textures[dest] = m_Texture2D.m_Name + ".png";
|
||||
textureNameDictionary.Add(m_Texture, iMat.Textures[dest]);
|
||||
}
|
||||
iMat.TexOffsets[dest] = new Vector2(texEnv.m_Offset[0], texEnv.m_Offset[1]);
|
||||
iMat.TexScales[dest] = new Vector2(texEnv.m_Scale[0], texEnv.m_Scale[1]);
|
||||
iMat.TexOffsets[dest] = texEnv.Value.m_Offset;
|
||||
iMat.TexScales[dest] = texEnv.Value.m_Scale;
|
||||
ConvertTexture2D(m_Texture2D, iMat.Textures[dest]);
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace AssetStudio
|
|||
value = reader.ReadChar();
|
||||
break;
|
||||
}
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace AssetStudio
|
|||
m_Keywords[i] = reader.ReadAlignedString();
|
||||
}
|
||||
m_ProgramCode = reader.ReadBytes(reader.ReadInt32());
|
||||
reader.AlignStream(4);
|
||||
reader.AlignStream();
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue