improved
This commit is contained in:
parent
a98fd52831
commit
c6484ba77e
|
@ -181,6 +181,7 @@
|
||||||
<Compile Include="StudioClasses\GameObjectTreeNode.cs" />
|
<Compile Include="StudioClasses\GameObjectTreeNode.cs" />
|
||||||
<Compile Include="StudioClasses\LocalSerializedObjectIdentifier.cs" />
|
<Compile Include="StudioClasses\LocalSerializedObjectIdentifier.cs" />
|
||||||
<Compile Include="StudioClasses\ObjectInfo.cs" />
|
<Compile Include="StudioClasses\ObjectInfo.cs" />
|
||||||
|
<Compile Include="StudioClasses\ScriptHelper.cs" />
|
||||||
<Compile Include="StudioClasses\SerializedFileHeader.cs" />
|
<Compile Include="StudioClasses\SerializedFileHeader.cs" />
|
||||||
<Compile Include="StudioClasses\SerializedType.cs" />
|
<Compile Include="StudioClasses\SerializedType.cs" />
|
||||||
<Compile Include="StudioClasses\SevenZipHelper.cs">
|
<Compile Include="StudioClasses\SevenZipHelper.cs">
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
if (openFileDialog1.ShowDialog() == DialogResult.OK)
|
if (openFileDialog1.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
resetForm();
|
ResetForm();
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
{
|
{
|
||||||
mainPath = Path.GetDirectoryName(openFileDialog1.FileNames[0]);
|
mainPath = Path.GetDirectoryName(openFileDialog1.FileNames[0]);
|
||||||
|
@ -107,7 +107,7 @@ namespace AssetStudio
|
||||||
var openFolderDialog1 = new OpenFolderDialog();
|
var openFolderDialog1 = new OpenFolderDialog();
|
||||||
if (openFolderDialog1.ShowDialog(this) == DialogResult.OK)
|
if (openFolderDialog1.ShowDialog(this) == DialogResult.OK)
|
||||||
{
|
{
|
||||||
resetForm();
|
ResetForm();
|
||||||
ThreadPool.QueueUserWorkItem(state =>
|
ThreadPool.QueueUserWorkItem(state =>
|
||||||
{
|
{
|
||||||
mainPath = openFolderDialog1.Folder;
|
mainPath = openFolderDialog1.Folder;
|
||||||
|
@ -180,7 +180,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
Text = $"AssetStudio - {productName} - {assetsfileList[0].unityVersion} - {assetsfileList[0].platformStr}";
|
Text = $"AssetStudio - {productName} - {assetsfileList[0].unityVersion} - {assetsfileList[0].platformStr}";
|
||||||
}
|
}
|
||||||
else if (assetsfileList.Count > 0)
|
else
|
||||||
{
|
{
|
||||||
Text = $"AssetStudio - no productName - {assetsfileList[0].unityVersion} - {assetsfileList[0].platformStr}";
|
Text = $"AssetStudio - no productName - {assetsfileList[0].unityVersion} - {assetsfileList[0].platformStr}";
|
||||||
}
|
}
|
||||||
|
@ -843,7 +843,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
textPreviewBox.Text = GetScriptString(reader);
|
textPreviewBox.Text = ScriptHelper.GetScriptString(reader);
|
||||||
}
|
}
|
||||||
textPreviewBox.Visible = true;
|
textPreviewBox.Visible = true;
|
||||||
|
|
||||||
|
@ -1705,7 +1705,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetForm()
|
private void ResetForm()
|
||||||
{
|
{
|
||||||
Text = "AssetStudio";
|
Text = "AssetStudio";
|
||||||
|
|
||||||
|
@ -1723,7 +1723,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
resourceFileReaders.Clear();
|
resourceFileReaders.Clear();
|
||||||
assetsFileIndexCache.Clear();
|
assetsFileIndexCache.Clear();
|
||||||
productName = "";
|
productName = string.Empty;
|
||||||
|
|
||||||
sceneTreeView.Nodes.Clear();
|
sceneTreeView.Nodes.Clear();
|
||||||
|
|
||||||
|
@ -1756,8 +1756,8 @@ namespace AssetStudio
|
||||||
|
|
||||||
FMODreset();
|
FMODreset();
|
||||||
|
|
||||||
moduleLoaded = false;
|
ScriptHelper.moduleLoaded = false;
|
||||||
LoadedModuleDic.Clear();
|
ScriptHelper.LoadedModuleDic.Clear();
|
||||||
treeNodeCollection.Clear();
|
treeNodeCollection.Clear();
|
||||||
treeNodeDictionary.Clear();
|
treeNodeDictionary.Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
str = Studio.GetScriptString(reader);
|
str = ScriptHelper.GetScriptString(reader);
|
||||||
}
|
}
|
||||||
File.WriteAllText(exportFullName, str);
|
File.WriteAllText(exportFullName, str);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -5,7 +5,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using SharpDX;
|
using SharpDX;
|
||||||
using static AssetStudio.Studio;
|
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
|
@ -1051,5 +1050,47 @@ namespace AssetStudio
|
||||||
parentFrame.AddChild(frame);
|
parentFrame.AddChild(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static float[] QuatToEuler(float[] q)
|
||||||
|
{
|
||||||
|
double eax = 0;
|
||||||
|
double eay = 0;
|
||||||
|
double eaz = 0;
|
||||||
|
|
||||||
|
float qx = q[0];
|
||||||
|
float qy = q[1];
|
||||||
|
float qz = q[2];
|
||||||
|
float qw = q[3];
|
||||||
|
|
||||||
|
double[,] M = new double[4, 4];
|
||||||
|
|
||||||
|
double Nq = qx * qx + qy * qy + qz * qz + qw * qw;
|
||||||
|
double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
|
||||||
|
double xs = qx * s, ys = qy * s, zs = qz * s;
|
||||||
|
double wx = qw * xs, wy = qw * ys, wz = qw * zs;
|
||||||
|
double xx = qx * xs, xy = qx * ys, xz = qx * zs;
|
||||||
|
double yy = qy * ys, yz = qy * zs, zz = qz * zs;
|
||||||
|
|
||||||
|
M[0, 0] = 1.0 - (yy + zz); M[0, 1] = xy - wz; M[0, 2] = xz + wy;
|
||||||
|
M[1, 0] = xy + wz; M[1, 1] = 1.0 - (xx + zz); M[1, 2] = yz - wx;
|
||||||
|
M[2, 0] = xz - wy; M[2, 1] = yz + wx; M[2, 2] = 1.0 - (xx + yy);
|
||||||
|
M[3, 0] = M[3, 1] = M[3, 2] = M[0, 3] = M[1, 3] = M[2, 3] = 0.0; M[3, 3] = 1.0;
|
||||||
|
|
||||||
|
double test = Math.Sqrt(M[0, 0] * M[0, 0] + M[1, 0] * M[1, 0]);
|
||||||
|
if (test > 16 * 1.19209290E-07F)//FLT_EPSILON
|
||||||
|
{
|
||||||
|
eax = Math.Atan2(M[2, 1], M[2, 2]);
|
||||||
|
eay = Math.Atan2(-M[2, 0], test);
|
||||||
|
eaz = Math.Atan2(M[1, 0], M[0, 0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eax = Math.Atan2(-M[1, 2], M[1, 1]);
|
||||||
|
eay = Math.Atan2(-M[2, 0], test);
|
||||||
|
eaz = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new[] { (float)(eax * 180 / Math.PI), (float)(eay * 180 / Math.PI), (float)(eaz * 180 / Math.PI) };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,348 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using dnlib.DotNet;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
//TODO unfinished
|
||||||
|
public static class ScriptHelper
|
||||||
|
{
|
||||||
|
public static bool moduleLoaded;
|
||||||
|
public static Dictionary<string, ModuleDef> LoadedModuleDic = new Dictionary<string, ModuleDef>();
|
||||||
|
|
||||||
|
public static string GetScriptString(ObjectReader reader)
|
||||||
|
{
|
||||||
|
if (!moduleLoaded)
|
||||||
|
{
|
||||||
|
var openFolderDialog = new OpenFolderDialog();
|
||||||
|
openFolderDialog.Title = "Select Assembly Folder";
|
||||||
|
if (openFolderDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
var files = Directory.GetFiles(openFolderDialog.Folder, "*.dll");
|
||||||
|
var moduleContext = new ModuleContext();
|
||||||
|
var asmResolver = new AssemblyResolver(moduleContext, true);
|
||||||
|
var resolver = new Resolver(asmResolver);
|
||||||
|
moduleContext.AssemblyResolver = asmResolver;
|
||||||
|
moduleContext.Resolver = resolver;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
var module = ModuleDefMD.Load(file, moduleContext);
|
||||||
|
LoadedModuleDic.Add(Path.GetFileName(file), module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleLoaded = true;
|
||||||
|
}
|
||||||
|
var m_MonoBehaviour = new MonoBehaviour(reader);
|
||||||
|
var sb = CreateMonoBehaviourHeader(m_MonoBehaviour);
|
||||||
|
if (m_MonoBehaviour.m_Script.TryGet(out var script))
|
||||||
|
{
|
||||||
|
var m_Script = new MonoScript(script);
|
||||||
|
if (!LoadedModuleDic.TryGetValue(m_Script.m_AssemblyName, out var module))
|
||||||
|
{
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
var typeDef = module.Assembly.Find(m_Script.m_Namespace != "" ? $"{m_Script.m_Namespace}.{m_Script.m_ClassName}" : m_Script.m_ClassName, false);
|
||||||
|
if (typeDef != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DumpType(typeDef.ToTypeSig(), sb, reader, null, -1, true);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
sb = CreateMonoBehaviourHeader(m_MonoBehaviour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StringBuilder CreateMonoBehaviourHeader(MonoBehaviour m_MonoBehaviour)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
sb.AppendLine("PPtr<GameObject> m_GameObject");
|
||||||
|
sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_GameObject.m_FileID}");
|
||||||
|
sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_GameObject.m_PathID}");
|
||||||
|
sb.AppendLine($"UInt8 m_Enabled = {m_MonoBehaviour.m_Enabled}");
|
||||||
|
sb.AppendLine("PPtr<MonoScript> m_Script");
|
||||||
|
sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_Script.m_FileID}");
|
||||||
|
sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_Script.m_PathID}");
|
||||||
|
sb.AppendLine($"string m_Name = \"{m_MonoBehaviour.m_Name}\"");
|
||||||
|
return sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DumpType(TypeSig typeSig, StringBuilder sb, ObjectReader reader, string name, int indent, bool isRoot = false)
|
||||||
|
{
|
||||||
|
var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
|
if (typeSig.IsPrimitive)
|
||||||
|
{
|
||||||
|
object value = null;
|
||||||
|
switch (typeSig.TypeName)
|
||||||
|
{
|
||||||
|
case "Boolean":
|
||||||
|
value = reader.ReadBoolean();
|
||||||
|
break;
|
||||||
|
case "Byte":
|
||||||
|
value = reader.ReadByte();
|
||||||
|
break;
|
||||||
|
case "SByte":
|
||||||
|
value = reader.ReadSByte();
|
||||||
|
break;
|
||||||
|
case "Int16":
|
||||||
|
value = reader.ReadInt16();
|
||||||
|
break;
|
||||||
|
case "UInt16":
|
||||||
|
value = reader.ReadUInt16();
|
||||||
|
break;
|
||||||
|
case "Int32":
|
||||||
|
value = reader.ReadInt32();
|
||||||
|
break;
|
||||||
|
case "UInt32":
|
||||||
|
value = reader.ReadUInt32();
|
||||||
|
break;
|
||||||
|
case "Int64":
|
||||||
|
value = reader.ReadInt64();
|
||||||
|
break;
|
||||||
|
case "UInt64":
|
||||||
|
value = reader.ReadUInt64();
|
||||||
|
break;
|
||||||
|
case "Single":
|
||||||
|
value = reader.ReadSingle();
|
||||||
|
break;
|
||||||
|
case "Double":
|
||||||
|
value = reader.ReadDouble();
|
||||||
|
break;
|
||||||
|
case "Char":
|
||||||
|
value = reader.ReadChar();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reader.AlignStream(4);
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeSig.FullName == "System.String")
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeSig.FullName == "System.Object")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.IsDelegate)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeSig is ArraySigBase)
|
||||||
|
{
|
||||||
|
if (!typeDef.IsEnum && !IsBaseType(typeDef) && !IsAssignFromUnityObject(typeDef) && !IsEngineType(typeDef) && !typeDef.IsSerializable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var size = reader.ReadInt32();
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
||||||
|
sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
|
||||||
|
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
|
||||||
|
DumpType(typeDef.ToTypeSig(), sb, reader, "data", indent + 2);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isRoot && typeSig is GenericInstSig genericInstSig)
|
||||||
|
{
|
||||||
|
if (genericInstSig.GenericArguments.Count == 1)
|
||||||
|
{
|
||||||
|
var type = genericInstSig.GenericArguments[0].ToTypeDefOrRef().ResolveTypeDefThrow();
|
||||||
|
if (!type.IsEnum && !IsBaseType(type) && !IsAssignFromUnityObject(type) && !IsEngineType(type) && !type.IsSerializable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var size = reader.ReadInt32();
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
||||||
|
sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
|
||||||
|
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
|
||||||
|
DumpType(genericInstSig.GenericArguments[0], sb, reader, "data", indent + 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (indent != -1 && IsAssignFromUnityObject(typeDef))
|
||||||
|
{
|
||||||
|
var pptr = reader.ReadPPtr();
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.IsEnum)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (indent != -1 && !IsEngineType(typeDef) && !typeDef.IsSerializable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.FullName == "UnityEngine.Rect")
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
||||||
|
var rect = reader.ReadSingleArray(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.FullName == "UnityEngine.LayerMask")
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
||||||
|
var value = reader.ReadInt32();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.FullName == "UnityEngine.AnimationCurve")
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
||||||
|
var animationCurve = new AnimationCurve<float>(reader, reader.ReadSingle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.FullName == "UnityEngine.Gradient")
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
||||||
|
if (reader.version[0] == 5 && reader.version[1] < 5)
|
||||||
|
reader.Position += 68;
|
||||||
|
else if (reader.version[0] == 5 && reader.version[1] < 6)
|
||||||
|
reader.Position += 72;
|
||||||
|
else
|
||||||
|
reader.Position += 168;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.FullName == "UnityEngine.RectOffset")
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
||||||
|
var left = reader.ReadSingle();
|
||||||
|
var right = reader.ReadSingle();
|
||||||
|
var top = reader.ReadSingle();
|
||||||
|
var bottom = reader.ReadSingle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (typeDef.FullName == "UnityEngine.GUIStyle") //TODO
|
||||||
|
{
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
if (typeDef.IsClass || typeDef.IsValueType)
|
||||||
|
{
|
||||||
|
if (name != null && indent != -1)
|
||||||
|
{
|
||||||
|
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
||||||
|
}
|
||||||
|
if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object")
|
||||||
|
{
|
||||||
|
DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
|
||||||
|
}
|
||||||
|
if (indent != -1 && typeDef.BaseType.FullName != "System.Object")
|
||||||
|
{
|
||||||
|
DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
|
||||||
|
}
|
||||||
|
foreach (var fieldDef in typeDef.Fields)
|
||||||
|
{
|
||||||
|
var access = fieldDef.Access & FieldAttributes.FieldAccessMask;
|
||||||
|
if (access != FieldAttributes.Public)
|
||||||
|
{
|
||||||
|
if (fieldDef.CustomAttributes.Any(x => x.TypeFullName.Contains("SerializeField")))
|
||||||
|
{
|
||||||
|
DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0 && (fieldDef.Attributes & FieldAttributes.NotSerialized) == 0)
|
||||||
|
{
|
||||||
|
DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsAssignFromUnityObject(TypeDef typeDef)
|
||||||
|
{
|
||||||
|
if (typeDef.FullName == "UnityEngine.Object")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (typeDef.BaseType != null)
|
||||||
|
{
|
||||||
|
if (typeDef.BaseType.FullName == "UnityEngine.Object")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
typeDef = typeDef.BaseType.ResolveTypeDefThrow();
|
||||||
|
if (typeDef.BaseType == null)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (typeDef.BaseType.FullName == "UnityEngine.Object")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsBaseType(IFullName typeDef)
|
||||||
|
{
|
||||||
|
switch (typeDef.FullName)
|
||||||
|
{
|
||||||
|
case "System.Boolean":
|
||||||
|
case "System.Byte":
|
||||||
|
case "System.SByte":
|
||||||
|
case "System.Int16":
|
||||||
|
case "System.UInt16":
|
||||||
|
case "System.Int32":
|
||||||
|
case "System.UInt32":
|
||||||
|
case "System.Int64":
|
||||||
|
case "System.UInt64":
|
||||||
|
case "System.Single":
|
||||||
|
case "System.Double":
|
||||||
|
case "System.String":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsEngineType(IFullName typeDef)
|
||||||
|
{
|
||||||
|
switch (typeDef.FullName)
|
||||||
|
{
|
||||||
|
case "UnityEngine.Vector2":
|
||||||
|
case "UnityEngine.Vector3":
|
||||||
|
case "UnityEngine.Vector4":
|
||||||
|
case "UnityEngine.Rect":
|
||||||
|
case "UnityEngine.Quaternion":
|
||||||
|
case "UnityEngine.Matrix4x4":
|
||||||
|
case "UnityEngine.Color":
|
||||||
|
case "UnityEngine.Color32":
|
||||||
|
case "UnityEngine.LayerMask":
|
||||||
|
case "UnityEngine.AnimationCurve":
|
||||||
|
case "UnityEngine.Gradient":
|
||||||
|
case "UnityEngine.RectOffset":
|
||||||
|
case "UnityEngine.GUIStyle":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,10 +4,8 @@ using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using dnlib.DotNet;
|
|
||||||
using static AssetStudio.Exporter;
|
using static AssetStudio.Exporter;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
|
@ -21,12 +19,10 @@ namespace AssetStudio
|
||||||
private static HashSet<string> assetsNameHash = new HashSet<string>(); //avoid the same name asset
|
private static HashSet<string> assetsNameHash = new HashSet<string>(); //avoid the same name asset
|
||||||
public static List<AssetItem> visibleAssets = new List<AssetItem>(); //used to build the ListView from all or filtered assets
|
public static List<AssetItem> visibleAssets = new List<AssetItem>(); //used to build the ListView from all or filtered assets
|
||||||
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> AllTypeMap = new Dictionary<string, SortedDictionary<int, TypeTreeItem>>();
|
public static Dictionary<string, SortedDictionary<int, TypeTreeItem>> AllTypeMap = new Dictionary<string, SortedDictionary<int, TypeTreeItem>>();
|
||||||
public static string mainPath;
|
|
||||||
public static string productName = "";
|
|
||||||
public static bool moduleLoaded;
|
|
||||||
public static Dictionary<string, ModuleDef> LoadedModuleDic = new Dictionary<string, ModuleDef>();
|
|
||||||
public static List<GameObjectTreeNode> treeNodeCollection = new List<GameObjectTreeNode>();
|
public static List<GameObjectTreeNode> treeNodeCollection = new List<GameObjectTreeNode>();
|
||||||
public static Dictionary<GameObject, GameObjectTreeNode> treeNodeDictionary = new Dictionary<GameObject, GameObjectTreeNode>();
|
public static Dictionary<GameObject, GameObjectTreeNode> treeNodeDictionary = new Dictionary<GameObject, GameObjectTreeNode>();
|
||||||
|
public static string mainPath;
|
||||||
|
public static string productName = string.Empty;
|
||||||
|
|
||||||
//UI
|
//UI
|
||||||
public static Action<int> SetProgressBarValue;
|
public static Action<int> SetProgressBarValue;
|
||||||
|
@ -748,400 +744,5 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float[] QuatToEuler(float[] q)
|
|
||||||
{
|
|
||||||
double eax = 0;
|
|
||||||
double eay = 0;
|
|
||||||
double eaz = 0;
|
|
||||||
|
|
||||||
float qx = q[0];
|
|
||||||
float qy = q[1];
|
|
||||||
float qz = q[2];
|
|
||||||
float qw = q[3];
|
|
||||||
|
|
||||||
double[,] M = new double[4, 4];
|
|
||||||
|
|
||||||
double Nq = qx * qx + qy * qy + qz * qz + qw * qw;
|
|
||||||
double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
|
|
||||||
double xs = qx * s, ys = qy * s, zs = qz * s;
|
|
||||||
double wx = qw * xs, wy = qw * ys, wz = qw * zs;
|
|
||||||
double xx = qx * xs, xy = qx * ys, xz = qx * zs;
|
|
||||||
double yy = qy * ys, yz = qy * zs, zz = qz * zs;
|
|
||||||
|
|
||||||
M[0, 0] = 1.0 - (yy + zz); M[0, 1] = xy - wz; M[0, 2] = xz + wy;
|
|
||||||
M[1, 0] = xy + wz; M[1, 1] = 1.0 - (xx + zz); M[1, 2] = yz - wx;
|
|
||||||
M[2, 0] = xz - wy; M[2, 1] = yz + wx; M[2, 2] = 1.0 - (xx + yy);
|
|
||||||
M[3, 0] = M[3, 1] = M[3, 2] = M[0, 3] = M[1, 3] = M[2, 3] = 0.0; M[3, 3] = 1.0;
|
|
||||||
|
|
||||||
double test = Math.Sqrt(M[0, 0] * M[0, 0] + M[1, 0] * M[1, 0]);
|
|
||||||
if (test > 16 * 1.19209290E-07F)//FLT_EPSILON
|
|
||||||
{
|
|
||||||
eax = Math.Atan2(M[2, 1], M[2, 2]);
|
|
||||||
eay = Math.Atan2(-M[2, 0], test);
|
|
||||||
eaz = Math.Atan2(M[1, 0], M[0, 0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eax = Math.Atan2(-M[1, 2], M[1, 1]);
|
|
||||||
eay = Math.Atan2(-M[2, 0], test);
|
|
||||||
eaz = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new[] { (float)(eax * 180 / Math.PI), (float)(eay * 180 / Math.PI), (float)(eaz * 180 / Math.PI) };
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetScriptString(ObjectReader reader)
|
|
||||||
{
|
|
||||||
if (!moduleLoaded)
|
|
||||||
{
|
|
||||||
var openFolderDialog = new OpenFolderDialog();
|
|
||||||
openFolderDialog.Title = "Select Assembly Folder";
|
|
||||||
if (openFolderDialog.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
|
||||||
var files = Directory.GetFiles(openFolderDialog.Folder, "*.dll");
|
|
||||||
var moduleContext = new ModuleContext();
|
|
||||||
var asmResolver = new AssemblyResolver(moduleContext, true);
|
|
||||||
var resolver = new Resolver(asmResolver);
|
|
||||||
moduleContext.AssemblyResolver = asmResolver;
|
|
||||||
moduleContext.Resolver = resolver;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
var module = ModuleDefMD.Load(file, moduleContext);
|
|
||||||
LoadedModuleDic.Add(Path.GetFileName(file), module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleLoaded = true;
|
|
||||||
}
|
|
||||||
var m_MonoBehaviour = new MonoBehaviour(reader);
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("PPtr<GameObject> m_GameObject");
|
|
||||||
sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_GameObject.m_FileID}");
|
|
||||||
sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_GameObject.m_PathID}");
|
|
||||||
sb.AppendLine($"UInt8 m_Enabled = {m_MonoBehaviour.m_Enabled}");
|
|
||||||
sb.AppendLine("PPtr<MonoScript> m_Script");
|
|
||||||
sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_Script.m_FileID}");
|
|
||||||
sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_Script.m_PathID}");
|
|
||||||
sb.AppendLine($"string m_Name = \"{m_MonoBehaviour.m_Name}\"");
|
|
||||||
if (m_MonoBehaviour.m_Script.TryGet(out var script))
|
|
||||||
{
|
|
||||||
var m_Script = new MonoScript(script);
|
|
||||||
if (!LoadedModuleDic.TryGetValue(m_Script.m_AssemblyName, out var module))
|
|
||||||
{
|
|
||||||
/*using (var openFileDialog = new OpenFileDialog())
|
|
||||||
{
|
|
||||||
openFileDialog.Title = $"Select {m_Script.m_AssemblyName}";
|
|
||||||
openFileDialog.FileName = m_Script.m_AssemblyName;
|
|
||||||
openFileDialog.Filter = $"{m_Script.m_AssemblyName}|{m_Script.m_AssemblyName}";
|
|
||||||
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
|
||||||
{
|
|
||||||
var moduleContext = new ModuleContext();
|
|
||||||
var asmResolver = new AssemblyResolver(moduleContext, true);
|
|
||||||
var resolver = new Resolver(asmResolver);
|
|
||||||
moduleContext.AssemblyResolver = asmResolver;
|
|
||||||
moduleContext.Resolver = resolver;
|
|
||||||
module = ModuleDefMD.Load(openFileDialog.FileName, moduleContext);
|
|
||||||
LoadedModule.Add(m_Script.m_AssemblyName, module);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
var typeDef = module.Assembly.Find(m_Script.m_Namespace != "" ? $"{m_Script.m_Namespace}.{m_Script.m_ClassName}" : m_Script.m_ClassName, false);
|
|
||||||
if (typeDef != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
DumpType(typeDef.ToTypeSig(), sb, reader, null, -1, true);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
sb = new StringBuilder();
|
|
||||||
sb.AppendLine("PPtr<GameObject> m_GameObject");
|
|
||||||
sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_GameObject.m_FileID}");
|
|
||||||
sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_GameObject.m_PathID}");
|
|
||||||
sb.AppendLine($"UInt8 m_Enabled = {m_MonoBehaviour.m_Enabled}");
|
|
||||||
sb.AppendLine("PPtr<MonoScript> m_Script");
|
|
||||||
sb.AppendLine($"\tint m_FileID = {m_MonoBehaviour.m_Script.m_FileID}");
|
|
||||||
sb.AppendLine($"\tint64 m_PathID = {m_MonoBehaviour.m_Script.m_PathID}");
|
|
||||||
sb.AppendLine($"string m_Name = \"{m_MonoBehaviour.m_Name}\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DumpType(TypeSig typeSig, StringBuilder sb, ObjectReader reader, string name, int indent, bool isRoot = false)
|
|
||||||
{
|
|
||||||
var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
if (typeSig.IsPrimitive)
|
|
||||||
{
|
|
||||||
object value = null;
|
|
||||||
switch (typeSig.TypeName)
|
|
||||||
{
|
|
||||||
case "Boolean":
|
|
||||||
value = reader.ReadBoolean();
|
|
||||||
break;
|
|
||||||
case "Byte":
|
|
||||||
value = reader.ReadByte();
|
|
||||||
break;
|
|
||||||
case "SByte":
|
|
||||||
value = reader.ReadSByte();
|
|
||||||
break;
|
|
||||||
case "Int16":
|
|
||||||
value = reader.ReadInt16();
|
|
||||||
break;
|
|
||||||
case "UInt16":
|
|
||||||
value = reader.ReadUInt16();
|
|
||||||
break;
|
|
||||||
case "Int32":
|
|
||||||
value = reader.ReadInt32();
|
|
||||||
break;
|
|
||||||
case "UInt32":
|
|
||||||
value = reader.ReadUInt32();
|
|
||||||
break;
|
|
||||||
case "Int64":
|
|
||||||
value = reader.ReadInt64();
|
|
||||||
break;
|
|
||||||
case "UInt64":
|
|
||||||
value = reader.ReadUInt64();
|
|
||||||
break;
|
|
||||||
case "Single":
|
|
||||||
value = reader.ReadSingle();
|
|
||||||
break;
|
|
||||||
case "Double":
|
|
||||||
value = reader.ReadDouble();
|
|
||||||
break;
|
|
||||||
case "Char":
|
|
||||||
value = reader.ReadChar();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
reader.AlignStream(4);
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeSig.FullName == "System.String")
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeSig.FullName == "System.Object")
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.IsDelegate)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeSig is ArraySigBase)
|
|
||||||
{
|
|
||||||
if (!typeDef.IsEnum && !IsBaseType(typeDef) && !IsAssignFromUnityObject(typeDef) && !IsEngineType(typeDef) && !typeDef.IsSerializable)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var size = reader.ReadInt32();
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
|
|
||||||
DumpType(typeDef.ToTypeSig(), sb, reader, "data", indent + 2);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isRoot && typeSig is GenericInstSig genericInstSig)
|
|
||||||
{
|
|
||||||
if (genericInstSig.GenericArguments.Count == 1)
|
|
||||||
{
|
|
||||||
var type = genericInstSig.GenericArguments[0].ToTypeDefOrRef().ResolveTypeDefThrow();
|
|
||||||
if (!type.IsEnum && !IsBaseType(type) && !IsAssignFromUnityObject(type) && !IsEngineType(type) && !type.IsSerializable)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var size = reader.ReadInt32();
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
|
|
||||||
DumpType(genericInstSig.GenericArguments[0], sb, reader, "data", indent + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (indent != -1 && IsAssignFromUnityObject(typeDef))
|
|
||||||
{
|
|
||||||
var pptr = reader.ReadPPtr();
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.IsEnum)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (indent != -1 && !IsEngineType(typeDef) && !typeDef.IsSerializable)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.FullName == "UnityEngine.Rect")
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
|
||||||
var rect = reader.ReadSingleArray(4);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.FullName == "UnityEngine.LayerMask")
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
|
||||||
var value = reader.ReadInt32();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.FullName == "UnityEngine.AnimationCurve")
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
|
||||||
var animationCurve = new AnimationCurve<float>(reader, reader.ReadSingle);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.FullName == "UnityEngine.Gradient")
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
|
||||||
if (reader.version[0] == 5 && reader.version[1] < 5)
|
|
||||||
reader.Position += 68;
|
|
||||||
else if (reader.version[0] == 5 && reader.version[1] < 6)
|
|
||||||
reader.Position += 72;
|
|
||||||
else
|
|
||||||
reader.Position += 168;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.FullName == "UnityEngine.RectOffset")
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
|
||||||
var left = reader.ReadSingle();
|
|
||||||
var right = reader.ReadSingle();
|
|
||||||
var top = reader.ReadSingle();
|
|
||||||
var bottom = reader.ReadSingle();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.FullName == "UnityEngine.GUIStyle") //TODO
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeDef.IsClass || typeDef.IsValueType)
|
|
||||||
{
|
|
||||||
if (name != null && indent != -1)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
|
|
||||||
}
|
|
||||||
if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object")
|
|
||||||
{
|
|
||||||
DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
|
|
||||||
}
|
|
||||||
if (indent != -1 && typeDef.BaseType.FullName != "System.Object")
|
|
||||||
{
|
|
||||||
DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
|
|
||||||
}
|
|
||||||
foreach (var fieldDef in typeDef.Fields)
|
|
||||||
{
|
|
||||||
var access = fieldDef.Access & FieldAttributes.FieldAccessMask;
|
|
||||||
if (access != FieldAttributes.Public)
|
|
||||||
{
|
|
||||||
if (fieldDef.CustomAttributes.Any(x => x.TypeFullName.Contains("SerializeField")))
|
|
||||||
{
|
|
||||||
DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0 && (fieldDef.Attributes & FieldAttributes.NotSerialized) == 0)
|
|
||||||
{
|
|
||||||
DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsAssignFromUnityObject(TypeDef typeDef)
|
|
||||||
{
|
|
||||||
if (typeDef.FullName == "UnityEngine.Object")
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (typeDef.BaseType != null)
|
|
||||||
{
|
|
||||||
if (typeDef.BaseType.FullName == "UnityEngine.Object")
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
typeDef = typeDef.BaseType.ResolveTypeDefThrow();
|
|
||||||
if (typeDef.BaseType == null)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (typeDef.BaseType.FullName == "UnityEngine.Object")
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsBaseType(IFullName typeDef)
|
|
||||||
{
|
|
||||||
switch (typeDef.FullName)
|
|
||||||
{
|
|
||||||
case "System.Boolean":
|
|
||||||
case "System.Byte":
|
|
||||||
case "System.SByte":
|
|
||||||
case "System.Int16":
|
|
||||||
case "System.UInt16":
|
|
||||||
case "System.Int32":
|
|
||||||
case "System.UInt32":
|
|
||||||
case "System.Int64":
|
|
||||||
case "System.UInt64":
|
|
||||||
case "System.Single":
|
|
||||||
case "System.Double":
|
|
||||||
case "System.String":
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool IsEngineType(IFullName typeDef)
|
|
||||||
{
|
|
||||||
switch (typeDef.FullName)
|
|
||||||
{
|
|
||||||
case "UnityEngine.Vector2":
|
|
||||||
case "UnityEngine.Vector3":
|
|
||||||
case "UnityEngine.Vector4":
|
|
||||||
case "UnityEngine.Rect":
|
|
||||||
case "UnityEngine.Quaternion":
|
|
||||||
case "UnityEngine.Matrix4x4":
|
|
||||||
case "UnityEngine.Color":
|
|
||||||
case "UnityEngine.Color32":
|
|
||||||
case "UnityEngine.LayerMask":
|
|
||||||
case "UnityEngine.AnimationCurve":
|
|
||||||
case "UnityEngine.Gradient":
|
|
||||||
case "UnityEngine.RectOffset":
|
|
||||||
case "UnityEngine.GUIStyle":
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ namespace AssetStudio
|
||||||
gs.CopyTo(stream);
|
gs.CopyTo(stream);
|
||||||
}
|
}
|
||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
using (reader = new EndianBinaryReader(stream, EndianType.LittleEndian))
|
using (var binaryReader = new BinaryReader(stream))
|
||||||
{
|
{
|
||||||
ReadWebData(reader);
|
ReadWebData(binaryReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -51,9 +51,9 @@ namespace AssetStudio
|
||||||
var stream = new MemoryStream();
|
var stream = new MemoryStream();
|
||||||
brotliStream.CopyTo(stream);
|
brotliStream.CopyTo(stream);
|
||||||
stream.Position = 0;
|
stream.Position = 0;
|
||||||
using (reader = new EndianBinaryReader(stream, EndianType.LittleEndian))
|
using (var binaryReader = new BinaryReader(stream))
|
||||||
{
|
{
|
||||||
ReadWebData(reader);
|
ReadWebData(binaryReader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -64,14 +64,14 @@ namespace AssetStudio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadWebData(EndianBinaryReader reader)
|
private void ReadWebData(BinaryReader reader)
|
||||||
{
|
{
|
||||||
var signature = reader.ReadStringToNull();
|
var signature = reader.ReadStringToNull();
|
||||||
if (signature != "UnityWebData1.0")
|
if (signature != "UnityWebData1.0")
|
||||||
return;
|
return;
|
||||||
var headLength = reader.ReadInt32();
|
var headLength = reader.ReadInt32();
|
||||||
var dataList = new List<WebData>();
|
var dataList = new List<WebData>();
|
||||||
while (reader.Position < headLength)
|
while (reader.BaseStream.Position < headLength)
|
||||||
{
|
{
|
||||||
var data = new WebData();
|
var data = new WebData();
|
||||||
data.dataOffset = reader.ReadInt32();
|
data.dataOffset = reader.ReadInt32();
|
||||||
|
@ -85,7 +85,7 @@ namespace AssetStudio
|
||||||
{
|
{
|
||||||
var file = new StreamFile();
|
var file = new StreamFile();
|
||||||
file.fileName = Path.GetFileName(data.path);
|
file.fileName = Path.GetFileName(data.path);
|
||||||
reader.Position = data.dataOffset;
|
reader.BaseStream.Position = data.dataOffset;
|
||||||
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));
|
file.stream = new MemoryStream(reader.ReadBytes(data.dataLength));
|
||||||
fileList.Add(file);
|
fileList.Add(file);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue