Code Monkey home page Code Monkey logo

assetstools.net's People

Contributors

dmc31a42 avatar indacosub avatar killemanon avatar kingenderbrine avatar nesrak1 avatar razmoth avatar shalzuth avatar www avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

assetstools.net's Issues

AssetsView "Properties" context menu item crashes the application

If I rightclick any item in AssetsView and choose Properties, the application crashes. The cause is an ArgumentOutOfRangeException that gets thrown at the following line in StartScreen.cs:

ushort monoId = currentFile.file.typeTree.unity5Types[info.curFileTypeOrIndex].scriptIndex;

curFileTypeOrIndex is (for example) 115, but unity5Types has only 9 items.

The assets file I opened has version number 5.1.4f1.

NuGet release

Hi. The latest release on NuGet is 9 months old, are there any plans to update it? I'd like to use the new texture replacement support in my tool and adding it via NuGet would make dependency management much easier.

Issue Creating a GameObject Asset

I am trying to create a GameObject asset using the following code:

// Import
AssetsManager assetsManager = new AssetsManager();
List<AssetsReplacer> replacers = new List<AssetsReplacer>();
assetsManager.LoadClassPackage("classdata.tpk");
AssetsFileInstance assetsFileInstance = assetsManager.LoadAssetsFile("sharedassets0.assets", false);
assetsManager.LoadClassDatabaseFromPackage(assetsFileInstance.file.typeTree.unityVersion);
AssetsFileTable assetsFileTable = assetsFileInstance.table;

// Template
AssetTypeTemplateField templateField = new AssetTypeTemplateField();
ClassDatabaseType cldbType = AssetHelper.FindAssetClassByName(assetsManager.classFile, "GameObject");
templateField.FromClassDatabase(assetsManager.classFile, cldbType, 0);

// New Asset
AssetTypeValueField newAsset = ValueBuilder.DefaultValueFieldFromTemplate(templateField);
replacers.Add(new AssetsReplacerFromMemory(0, assetsFileTable.assetFileInfo.Max(i => i.index) + 1, cldbType.classId, 0xFFFF, newAsset.WriteToByteArray()));

// Export
AssetsFileWriter writer = new AssetsFileWriter(File.OpenWrite("sharedassets0-new.assets"));
assetsFileInstance.file.Write(writer, 0, replacers, 0);
writer.Close();

The code runs without any error. However, when I try to view the GameObject using AssetsView, I get the following error:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at AssetsTools.NET.AssetTypeValueField.get_Item(Int32 index)
   at AssetsView.Winforms.GameObjectViewer.GetRootGameObject(AssetExternal ext)
   at AssetsView.Winforms.GameObjectViewer.GameObjectViewer_Load(Object sender, EventArgs e)
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form.OnCreateControl()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

I think this is an issue with my code and not AssetsView. How should I correctly initialize a new GameObject asset?

Note:
I am using the AssetsTools.NET.dll provided in AssetsTools.NET.zip in #22. The rest of the files are from update 14 (2.0.6)

System.ArgumentOutOfRangeException: Non-negative number required.

Caused by removed upon loading into AssetView.NET

************** Exception Text **************
System.ArgumentOutOfRangeException: Non-negative number required.
Parameter name: count
at System.IO.BinaryReader.ReadBytes(Int32 count)
at AssetsTools.NET.AssetsFileReader.ReadStringLength(Int32 len)
at AssetsView.AssetHelpers.AssetInfo.GetAssetNameFast(AssetFileInfoEx afi, ClassDatabaseFile cldb, ClassDatabaseType type, AssetsFileInstance inst)
at AssetsView.Winforms.StartScreen.LoadGeneric(AssetsFileInstance mainFile, Boolean isLevel)
at AssetsView.Winforms.StartScreen.LoadMainAssetsFile(AssetsFileInstance inst)
at AssetsView.Winforms.StartScreen.LoadBundleFile(String path)
at AssetsView.Winforms.StartScreen.addFileToolStripMenuItem_Click(Object sender, EventArgs e)
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Marshal.UnsafeAddrOfPinnedArrayElement() called on unpinned array

Both the example code in the README file and the code of AssetsView itself use Marshal.UnsafeAddrOfPinnedArrayElement() when passing texture data to the System.Drawing.Bitmap constructor. However, neither of them pin the data array first, which goes against the Microsoft documentation:

The array must be pinned using a GCHandle before it is passed to this method. For maximum performance, this method does not validate the array passed to it; this can result in unexpected behavior.

Indeed, if the array is not pinned, the garbage collector is free to move it around in memory at any time - and if this happens while GDI+ is busy creating the bitmap, the user will get anything from a corrupted texture to a crash.

As a side remark, neither the example code nor AssetsView dispose the Bitmap object when they're done with it.

[Bug] If MonoBehaviour reference(include) itself, throw System.StackOverflowException

Hello,
I tested UABE.NET, and I found bug about MonoDeserializer.
first of all, I'll show you 'TMPro.TMP_FontAsset' structure by UABE.Cpp
if monobehaviour reference itself
In Array fallbackFontAssets(and TMP_FontWeights in Array fontWeights) field, it reference(include) itself(TMPro.TMP_FontAsset).
Originally, these things should be loaded as "PPtr<TMP_FontAsset>", but MonoDeserializer.cs load TMP_FontAsset in Array fallbackFontAssets as it is.
so, it try to load TMP_FontAsset again, and again. After infinity loop, UABE.NET throw 'System.StackOverflowException'.
I'm try to figure out how to resolve. But before that, I want to make you know about it.
If i find solution before you fix, I'll do pull request.
Thank you.

System.IO.EndOfStreamException with AssetViewer

When trying to read PlayerSettings in globalgamemanagers, an EndOfStreamException gets thrown

File: globalgamemanagers.zip

Exception:

image

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.IO.EndOfStreamException: Unable to read beyond the end of the stream.
   at System.IO.BinaryReader.ReadByte()
   at AssetsTools.NET.AssetTypeTemplateField.ReadType(AssetsFileReader reader, UInt64 filePos, AssetTypeValueField valueField, Boolean bigEndian)
   at AssetsTools.NET.AssetTypeTemplateField.ReadType(AssetsFileReader reader, UInt64 filePos, AssetTypeValueField valueField, Boolean bigEndian)
   at AssetsTools.NET.AssetTypeInstance..ctor(UInt32 baseFieldCount, AssetTypeTemplateField[] ppBaseFields, AssetsFileReader reader, Boolean bigEndian, UInt64 filePos)
   at AssetsTools.NET.Extra.AssetsManager.GetATI(AssetsFile file, AssetFileInfoEx info, Boolean fromTypeTree)
   at AssetsView.Winforms.StartScreen.assetList_CellDoubleClick(Object sender, DataGridViewCellEventArgs e)
   at System.Windows.Forms.DataGridView.OnCellDoubleClick(DataGridViewCellEventArgs e)
   at System.Windows.Forms.DataGridView.OnDoubleClick(EventArgs e)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.DataGridView.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.4069.0 built by: NET48REL1LAST_B
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
AssetsView
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/AssetsToolsNET_AssetsView/AssetsView.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.4042.0 built by: NET48REL1LAST_C
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.4001.0 built by: NET48REL1LAST_C
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.3761.0 built by: NET48REL1
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
AssetsTools.NET
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/AssetsToolsNET_AssetsView/AssetsTools.NET.DLL
----------------------------------------
System.Configuration
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.3761.0 built by: NET48REL1
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Core
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.4110.0 built by: NET48REL1LAST_B
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.8.3761.0 built by: NET48REL1
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

UnityFS 2019.4.5f1 crashes - System.OverflowException

This seems to hold true for any 2019.4.5f1 bundle that I throw at it, the 2019.1.8f1 counterparts work fine.
Here's the Stacktrace:

System.OverflowException: Arithmetic operation resulted in an overflow.
   at AssetsTools.NET.Type_0D.Read(Boolean hasTypeTree, AssetsFileReader reader, UInt32 version)
   at AssetsTools.NET.TypeTree.Read(AssetsFileReader reader, UInt32 version)
   at AssetsTools.NET.AssetsFile..ctor(AssetsFileReader reader)
   at AssetsTools.NET.Extra.AssetsFileInstance..ctor(Stream stream, String filePath, String root)
   at AssetsTools.NET.Extra.AssetsManager.LoadAssetsFile(Stream stream, String path, Boolean loadDeps, String root)
   at AssetsView.Winforms.StartScreen.LoadBundleFile(String path)
   at AssetsView.Winforms.StartScreen.addFileToolStripMenuItem_Click(Object sender, EventArgs e)
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

This happens both when opening the bundle using AssetsView and my own implementation (which calls the AssetsFileInstance constructor)

I tried loading the bundle using several applications

  • UABE says they're not valid Assets files.
  • AssetStudio doesn't load them at all, no warnings / errors

On the other hand

  • uTinyRipper seems to unpack without trouble
  • devXUnityUnpacker loads the bundles fine as well

I did see you mentioning reading the assets manually using the AssetsFileReader on the main ReadMe, could you elaborate on that?

how to get an asset's fields completely?

hi, refering to the README document, i can get a asset's name easily using this script:
` //Load assets file
var am = new AssetsManager();
var inst = am.LoadAssetsFile("C:\Users\Desktop\UnityDemo_2018_3D_Data\sharedassets0.assets", true);

        //Load class database
        am.LoadClassPackage("classdata.tpk");
        am.LoadClassDatabaseFromPackage(inst.file.typeTree.unityVersion);

        //Get asset info
        var table = inst.table;

        //foreach (var inf in inst.table.GetAssetsOfType((int)AssetClassID.GameObject))
        foreach (var inf in inst.table.GetAssetsOfType(150))
        {
            var baseField = am.GetTypeInstance(inst, inf).GetBaseField();

            var name = baseField.Get("m_Name").GetValue().AsString();
            Console.WriteLine(name);
        }`

but, i wonder how to get my asset's full field completly, just like this:
image

Grabbing the VertexData of a mesh?

Hiya! Is it possible to grab the vertice data of a mesh so I can reconstruct the mesh inside of Unity at runtime?

I've got it to where I can grab any of the data of the Mesh object, only problem is that I don't think theres Vector3 support inside of AssetsTools.NET which is needed for Unity's mesh stuff :P

Adding a value to an array in an asset

enabledVRDevices has an array inside it, so I can get that array like so:

var enabledVRDevices = baseField.Get("enabledVRDevices").Get(0);

If I want to change the value of the first element of the array, I do this:

enabledVRDevices .Get(0).SetValue("Something");

This works as expected, and when I write the changes to a file I can confirm that the new value is there.

But what I need is to actually add a new value to the array, since it starts out as empty.

I tried with SetChildrenList but in the final file the array is always empty:

var something = new AssetTypeValueField();
something .value = new AssetTypeValue(EnumValueTypes.ValueType_String, "Something");
enabledVRDevices .SetChildrenList(new[] { something });

I was trying to find some way to just to something like this:

var newArray = new AssetTypeArray();
enabledVRDevices.GetValue().Set(newArray);

But I have no idea how to add anything inside this newArray. Seems like that part is commented out in the source code?

So, what is the correct way to add items into an array here?

Crash reading Bundle

Hi, i'm trying to read a bundle file from a game but the code crash at:

        public string GetFileName(int index)
        {
            if (bundleHeader3 != null)
                return assetsLists3.entries[index].name;

            if (bundleHeader6 != null)
                return bundleInf6.dirInf[index].name;

            return null;
        }

with NullExeption for "bundleInf6.dirInf"

var am = new AssetsManager();
var bun = am.LoadBundleFile("shape");
//load first asset from bundle
var assetInst = am.LoadAssetsFileFromBundle(bun, 0, true);

ths file "shape" without extension start with bytes: "UnityFS ๏ฟฝ5.x.x 2021.1.17f1". It contains a list of fbx files that I have already extracted with the AssetStudioGui program but I would like to manage the extraction in my tool.

Can't open written file

Opening my bundle with AssetViewer shows 3 files

Icon - Sprite
SpriteIndex - AssetBundle
Icon - Texture2D

It's unity version is 2019.4.23f1

I've copy pasted the code for Writing an Asset Bundle as so

            var am = new AssetsManager();

            var bunInst = am.LoadBundleFile("art.bundle");
            //read the boring file from the bundle
            var inst = am.LoadAssetsFileFromBundle(bunInst, 0, false);

            var inf = inst.table.GetAssetInfo("Icon");
            var baseField = am.GetTypeInstance(inst, inf).GetBaseField();
            var thing = baseField.Get("m_Name").GetValue().AsString();
            Console.WriteLine(thing);
            baseField.Get("m_Name").GetValue().Set("MyCoolAsset");

            var newGoBytes = baseField.WriteToByteArray();
            var repl = new AssetsReplacerFromMemory(0, inf.index, (int)inf.curFileType, 0xffff, newGoBytes);

            //write changes to memory
            byte[] newAssetData;
            using (var stream = new MemoryStream())
            using (var writer = new AssetsFileWriter(stream))
            {
                inst.file.Write(writer, 0, new List<AssetsReplacer>() { repl }, 0);
                newAssetData = stream.ToArray();
            }

            //rename this asset name from boring to cool when saving
            var bunRepl = new BundleReplacerFromMemory("Icon", "Renamed", true, newAssetData, -1);

            var bunWriter = new AssetsFileWriter(File.OpenWrite("coolbundle.bundle"));
            bunInst.file.Write(bunWriter, new List<BundleReplacer>() { bunRepl });

Opening the created bundle gives the following error

System.ArgumentOutOfRangeException: Stream length must be non-negative and less than 2^31 - 1 - origin. (Parameter 'value')
   at System.IO.MemoryStream.set_Position(Int64 value)
   at AssetsTools.NET.AssetsFile..ctor(AssetsFileReader reader) in C:\Users\nesquack\Documents\GitReposLocal\AssetsTools.NET\AssetTools.NET\Standard\AssetsFileFormat\AssetsFile.cs:line 49
   at AssetsTools.NET.Extra.AssetsFileInstance..ctor(Stream stream, String filePath, String root) in C:\Users\nesquack\Documents\GitReposLocal\AssetsTools.NET\AssetTools.NET\Extra\AssetsManager\AssetsFileInstance.cs:line 26
   at AssetsTools.NET.Extra.AssetsManager.LoadAssetsFile(Stream stream, String path, Boolean loadDeps, String root, BundleFileInstance bunInst) in C:\Users\nesquack\Documents\GitReposLocal\AssetsTools.NET\AssetTools.NET\Extra\AssetsManager\AssetsManager.cs:line 29
   at AssetsView.Winforms.StartScreen.LoadBundleFile(String path) in C:\Users\nesquack\Documents\GitReposLocal\AssetsTools.NET\AssetsView\Winforms\StartScreen.cs:line 128
   at AssetsView.Winforms.StartScreen.addFileToolStripMenuItem_Click(Object sender, EventArgs e) in C:\Users\nesquack\Documents\GitReposLocal\AssetsTools.NET\AssetsView\Winforms\StartScreen.cs:line 103
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

If I DON'T rename the file then it saves and opens properly. That's exactly why I need this though... to rename a file in a bundle and I can't find a different tool that can do this programatically.

The headers are here where the first is changed and the second unchanged:

UnityFS    ๏ฟฝ5.x.x 2019.4.23f1       1ยป   [   [   @                                 ๏ฟฝ  bH  bH @   ๏ฟฝ              1    ๏ฟฝCAB-0207725071a623d62e45b4a33e9c7b85       1       1(   ๏ฟฝ509   	รฉ  1    ๏ฟฝ  ๏ฟฝ     2019.4.23f1 
UnityFS    ๏ฟฝ5.x.x 2019.4.23f1       1ยป   [   [   @                                 ๏ฟฝ  1   1  @   ๏ฟฝ              1    ๏ฟฝCAB-0207725071a623d62e45b4a33e9c7b85   				รฉ  1    ๏ฟฝ  ๏ฟฝ     2019.4.23f1 

So how do I rename this file then?

Cannot serialize custom monobehaviours field values

I'm trying to change some field values on an assetbundle, unity version 2018.4.16f1
AssetsTools version is latest commit.
I'm using the following code :

Init the asset manager

private static void InitAssetsManager()
{
	_assetsManager = new AssetsManager();
	_assetsManager.LoadClassPackage("classdata.tpk");
}

Loading the bundle

private static void LoadUserAssetBundleData(string userAssetBundlePath)
{
	_userAssetBundleFileInstance = _assetsManager.LoadBundleFile(userAssetBundlePath, true);

	for (int i = 0; i < _userAssetBundleFileInstance.file.NumFiles; i++)
	{
		if (!_userAssetBundleFileInstance.file.IsAssetsFile(i))
		{
			continue;
		}

		var assetBundleAssetsFile = _assetsManager.LoadAssetsFileFromBundle(_userAssetBundleFileInstance, i);
		_userAssetBundleAssetsFiles.Add(assetBundleAssetsFile);
		_assetsManager.LoadClassDatabaseFromPackage(assetBundleAssetsFile.file.typeTree.unityVersion);
	}
}

Two helper methods for saving the changes to the field

private static void SetUnityObjRef(AssetTypeValueField fieldChildren, SerializedUnityObjectRef unityObjectRef)
{
	if (fieldChildren.childrenCount == 2)
	{
		AssetTypeValueField fileId = fieldChildren.children[0];
		AssetTypeValueField pathId = fieldChildren.children[1];
		string fileIdName = fileId.templateField.name;
		string fileIdType = fileId.templateField.type;
		string pathIdName = pathId.templateField.name;
		string pathIdType = pathId.templateField.type;
		if (fileIdName == "m_FileID" && fileIdType == "int" &&
			pathIdName == "m_PathID" && pathIdType == "SInt64")
		{
			fileId.GetValue().Set(unityObjectRef.FileId);
			pathId.GetValue().Set(unityObjectRef.PathId);
		}
	}
}

private static void SaveFieldChange(List<AssetsReplacer> assetsReplacers, AssetFileInfoEx assetInfo, AssetTypeValueField field, ushort monoScriptIndex = 0xFFFF)
{
	var newFieldBytes = field.WriteToByteArray();
	Console.WriteLine("monoScriptIndex:" + monoScriptIndex);
	var repl = new AssetsReplacerFromMemory(0, assetInfo.index, (int)assetInfo.curFileType, monoScriptIndex, newFieldBytes);
	assetsReplacers.Add(repl);
}

Code that actually retrieve the "test" field on my custom script, which is a reference to a gameobject asset

foreach (var assetsFile in _userAssetBundleAssetsFiles)
{
	if (!_userAssetsFilesToReplacers.TryGetValue(assetsFile, out var assetsReplacers))
	{
		assetsReplacers = new();
		_userAssetsFilesToReplacers.Add(assetsFile, assetsReplacers);
	}

	foreach (var assetInfo in assetsFile.table.assetFileInfo)
	{
		if (assetInfo.index != 8948727843312140990)
		{
			continue;
		}

		var field = _assetsManager.GetTypeInstance(assetsFile, assetInfo).GetBaseField();
		AssetTypeValueField components = field.Get("m_Component").Get("Array");
		int componentSize = components.GetValue().AsArray().size;
		AssetTypeValueField componentPtr = components[componentSize - 1].GetLastChild();
		AssetExternal assetExternal = _assetsManager.GetExtAsset(assetsFile, componentPtr);
		if (assetExternal.instance != null)
		{
			string className = AssetHelper.FindAssetClassByID(_assetsManager.classFile, assetExternal.info.curFileType).name.GetString(_assetsManager.classFile);
			if (className == "MonoBehaviour")
			{
				var managedPath = @"C:\Users\Quentin\desktop_files\code\csharp\ror2\UnityProjFixBundleRef\FixBundleRefTest\OutputGame\FixBundleRefTest_Data\Managed";
				var targetBaseField = MonoDeserializer.GetMonoBaseField(_assetsManager, assetsFile, assetExternal.info, managedPath);
				var testField = targetBaseField.Get("test");
				SetUnityObjRef(testField, new SerializedUnityObjectRef(3, 8));
				SaveFieldChange(assetsReplacers, assetExternal.info, testField, AssetHelper.GetScriptIndex(assetsFile.file, assetExternal.info));
				break;
			}
		}
	}
}

Code that save the changes to a new bundle file :

private static void SaveChangesToAssetBundle(string userAssetBundlePath)
{
	var newAssetsFileDatas = new List<(string, byte[])>();
	foreach ((var userAssetFile, var assetsReplacer) in _userAssetsFilesToReplacers)
	{
		byte[] newAssetsFileData;
		using (var memoryStream = new MemoryStream())
		using (var _writer = new AssetsFileWriter(memoryStream))
		{
			userAssetFile.file.Write(_writer, 0, assetsReplacer, 0);
			newAssetsFileData = memoryStream.ToArray();

			newAssetsFileDatas.Add((userAssetFile.name, newAssetsFileData));
		}
	}

	using (var fileStream = new FileStream(userAssetBundlePath + "_ref_fixed", FileMode.Create))
	{
		var bundleReplacers = new List<BundleReplacer>();
		foreach ((var assetsFileName, var newAssetsFileData) in newAssetsFileDatas)
		{
			var bundleReplacer = new BundleReplacerFromMemory(assetsFileName, null, false, newAssetsFileData, -1);
			bundleReplacers.Add(bundleReplacer);
		}

		var writer = new AssetsFileWriter(fileStream);
		_userAssetBundleFileInstance.file.Write(writer, bundleReplacers);
	}
}

Unmodified bundle :
https://i.imgur.com/DVFAiOB.png

Modified bundle :
https://i.imgur.com/mJ08Bzp.png

We can see that the changes end up in the wrong location, and i'm not sure why

Problems with large asset bundles

I've been trying to use this library in one of my projects to modify asset bundles but I keep running into issues when using with large asset bundles. I'm basically just iterating over the MonoScript assets in the bundle and modifying the m_AssemblyName property on each one to point to a different assembly. It works well on smaller bundles but I run into issues on larger ones.

Notably that the library seems to use a LOT of memory when reading large files, many times more than the size of the decompressed bundle itself, but also that because of this integer cast bundles with decompressed sizes over 2GB will also cause an integer overflow and fail to load entirely throwing an ArgumentOutOfBounds exception on the ReadBytes() call below.

I was hoping that the BundleReplacerFromStream and AssetsReplacerFromStream would allow me to perform my operations while keeping memory usage down but after trying and looking into it, it too just reads the entire stream into another byte array and doesn't really solve much of anything.

I would like to continue using this library and I'll be experimenting seeing if I can find any workarounds, but I thought I'd open this just in case anyone had some useful info.

Modifying of Unity 5.6.5 assets

I've issues with modifying assets of the game based on Unity 5.6.5. Already found that using AssetsReplacer with no changes at all crashes game.

I've done 2 tests. First, AssetsFileWriter without any AssetsReplacer doesn't change anything. Second, adding AssetsReplacerFromMemory with changedBytes (baseField.WriteToByteArray()) without doing any modifications completely changes whole file and makes game crash.

I'm using AssetsTools.NET v2.0.11.

[Bug] Throw System.ArgumentOutOfRangeException in GetAssetNameFast when read '0x00000062 (DelayedCallManager)' in globalgamemanager

Throw System.ArgumentOutOfRangeException in GetAssetNameFast when read '0x00000062 (DelayedCallManager)' in globalgamemanager, because 'DelayedCallManager' is unknown in UABE.Cpp also.( UABE.Cpp said 'Unknown asset format!' when 'View Data' DelayedCallManager Type asset in globalgamemanager.)
in classdatabase file, DelayedCallManager has only one field, so type.fields[1] is invaild.

if (type.fields.Count == 0) return type.name.GetString(cldb);
if (type.fields[1].fieldName.GetString(cldb) == "m_Name")

image

I changed to

            if (type.fields.Count <= 1) return type.name.GetString(cldb);
            if (type.fields[1].fieldName.GetString(cldb) == "m_Name")

Modifying AssetBundles

Greetings. Is there a way to replace file in assets inside assetBundle, and save the modified bundle?
I got the decompression and extraction part with AssetView.NET code, but replacement seems to be not clear...
After using the sample code from readme for modification (even without the part that modifies filename), the exported output file seems to be filled with Unicode replacement character, same thing happened when I tried to extract TextAsset using baseField.Get("m_Script").GetValue().AsString() (and not only as string).
My goal is to modify TextAsset data and save modified asset bundle.

And even if i'll manage to get a modified asset, how can I place it as a replacement in asset bundle and then save it?
This code always creates an empty 2KB bundle, even if original bundle is not empty

var am = new AssetsManager();
var ab = am.LoadBundleFile(FilePath);
var writer = new AssetsFileWriter(File.OpenWrite("output.ab"));
ab.file.Write(writer);

P.S. I would like to notice that the sample code has multiple errors in it (variable is used before declaration, curFileType is not converted to int, Write function uses AssetsReplacer array instead of List, and is missing two other arguments required by the function) which is really confusing...

OutOfMemoryException when trying to view BuildSettings

Game: Hollow Knight
Version 1.5.68.11808
Unity Version used for it: 2020.2
AssetsView version: AssetsTools Update 3

Procedure:

  1. Start AssetsView
  2. File -> Add File (globalgamemanagers)
  3. Double click BuildSettings
  4. OoM exception

when disable write typetree, am.LoadAssetsFileFromBundle returns null

If I use the code below to build bundles

BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.DisableWriteTypeTree, BuildTarget.WebGL);

and use the code below to read a bundle. am.LoadAssetsFileFromBundle always returns null.

            var am = new AssetsManager();

            am.LoadClassPackage("classdata.tpk");

            var bun = am.LoadBundleFile("file/bg_11zhuan1.bundle");
            var inst = am.LoadAssetsFileFromBundle(bun, bun.file.GetFileName(0));

If I use BuildAssetBundleOptions.None instead of BuildAssetBundleOptions.DisableWriteTypeTree to build bundles, am.LoadAssetsFileFromBundle doesn't return null.
What should I do I, if I want to use BuildAssetBundleOptions.DisableWriteTypeTree?

Import Texture2D from a bundle to a asset

Hello! i need/want import a Texture2D from an asset, i want do this without decode the texture via 'WriteToByteArray' but only return this:
image

could you tell me how I can do it? thanks

Here's a Better Fix for Loading ClassDatabseFile from Package

I notice that AssetsTools.NET will throw error's if the am.classFile is null or if a wrong one is loaded, and your code will select a Unity 5.x version because of how the list is ordered, so that is definately going to cause issues if using a new Unity version, like getting the type instance or basefield.. So short of as you said a version selector, here is a modification to your code that will find the closest matching Unity version if the game version doesn't exist in the tpk. (It helps alot, but some Unity versions still may not work correctly if it's not in the tpk) Note: You will also notice a significant performance increase in parsing resource's You can test it with 'Mist Legacy' from steam, there's no TypeDump for the Unity version (2020.3.20f1) yet but x.18f1 exists which should be your result:

if (am.classFile == null)
{
	int index = am.classPackage.header.files.FindIndex(f => f.name.StartsWith("U" + inst.file.typeTree.unityVersion));
	if (index >= 0) // -1 mean's it isn't in current tpk
	{
		am.classFile = am.classPackage.files[index]; // If am.classFile is Null you get errors.
	}
	else
	{
		List<ClassDatabaseFile> files = am.classPackage.files;

		// Filter all classDbFiles for matching versions
		var unityMajMinVer = inst.file.typeTree.unityVersion.Substring(0, 6);
		var filter1 = files.Where(f => f.header.unityVersions[0].StartsWith(unityMajMinVer)).OrderBy(v => v.header.unityVersions[v.header.unityVersionCount - 1]);
		var filter2 = filter1.Where(f => f.header.unityVersions[f.header.unityVersionCount - 1].Trim().Length == inst.file.typeTree.unityVersion.Length).OrderBy(v => v.header.unityVersions[v.header.unityVersionCount - 1]);

		// Get the SubMinor version number
		string unitySubMinVer = inst.file.typeTree.unityVersion.Split('.')[2];
		string tmpNum = "";
		if (unitySubMinVer.Length >= 4) { tmpNum = unitySubMinVer.Substring(0, 2); } else { tmpNum = unitySubMinVer.Substring(0, 1); }

		// Make Existing Num List 
		List<int> nums = new List<int>();
		foreach (var pos in filter2) { nums.Add(int.Parse(pos.header.unityVersions[pos.header.unityVersionCount - 1].Split('.')[2].Substring(0, tmpNum.Length))); }
		int closest = nums.Aggregate((x, y) => Math.Abs(x - int.Parse(tmpNum)) < Math.Abs(y - int.Parse(tmpNum)) ? x : y);

		ClassDatabaseFile result = filter2.Where(f => f.header.unityVersions[f.header.unityVersionCount - 1].StartsWith(unityMajMinVer + "." + closest)).Single();
		am.classFile = result;

		//ORIG:
		//List<ClassDatabaseFile> files = tmpam.classPackage.files;
		//tmpam.classFile = files[files.Count - 1]; // will be Unity 5.x, due to order of list
	}
}

Fix bundle repacking in-memory

Bundles right now are being compressed directly in memory. This is because it needs to be placed after a compressed table which is dependent on the compressed data after it, and the compressed table can change in size depending on how the compressed data is compressed. Both Unity and DevX compress in a temporary file and copy over later, UnityPy writes directly in memory (what we're doing), and UABE sets the "table at end of file" flag (0x80).

  • Writing in a temporary file
    • I don't like this method particularly because the input into Pack method is a stream. If the stream is a MemoryStream, how do we decide where to place temporary files (or just put them in %temp% or something?). This requires making a temporary file with the compressed data and copying the data into the final file later, so you end up with two copies of the data on the disk.
  • Using written file as a temporary file and move the bytes
    • Basically just write the table uncompressed up front, write the compress data after it, compress and overwrite the original table, and reposition the compressed bytes. Prevents us from using a temporary file but still requires double writing.
  • Writing in memory
    • Obviously not good for large bundles, but easiest to do. MemoryStreams are limited to 2GB, but apparently we can make a custom MemoryStream to support more than 2GB. I don't like this idea but it's possible.
  • Use table at end of file flag
    • Easiest option, just set the flag and write table at the end. The editor never uses this itself, so you'll never see this from any built game afaik. I don't know if this will stick around or not.

I think the table at end of file flag is probably the best decision, but it produces bundles with a flag that isn't used normally and can be easily identified as being created by AssetsTools(.NET).

Replacer Ammends New Transform instead of Modifying it

I have the following code that is intended to remove a child from a father transform.

// Import
AssetsManager assetsManager = new AssetsManager();
List<AssetsReplacer> replacers = new List<AssetsReplacer>();
assetsManager.LoadClassPackage("classdata.tpk");
AssetsFileInstance assetsFileInstance = assetsManager.LoadAssetsFile("sharedassets0.assets", false);
assetsManager.LoadClassDatabaseFromPackage(assetsFileInstance.file.typeTree.unityVersion);
AssetsFileTable assetsFileTable = assetsFileInstance.table;

// Get Father
long fatherID = 16256;
long childID = 16153;
AssetFileInfoEx fatherFile = assetsFileTable.GetAssetInfo(fatherID);
AssetTypeValueField fatherBaseField = assetsManager.GetTypeInstance(assetsFileInstance.file, fatherFile).GetBaseField();

// Clear Father's Child
AssetTypeValueField[] fatherChildren = fatherBaseField.Get("m_Children").Get("Array").children;
AssetTypeValueField[] newChildren = fatherChildren.Where(child => child.Get("m_PathID").GetValue().AsInt64() != childID).ToArray();
fatherBaseField.Get("m_Children").Get("Array").SetChildrenList(newChildren);

// Save
replacers.Add(new AssetsReplacerFromMemory(0, fatherFile.index, (int)fatherFile.curFileType, 0xFFFF, fatherBaseField.WriteToByteArray()));

// Export
AssetsFileWriter writer = new AssetsFileWriter(File.OpenWrite("sharedassets0-new.assets"));
assetsFileInstance.file.Write(writer, 0, replacers, 0);
writer.Close();

However, instead of editing the existing father transform, the replaces amend a new transform so I end up with 2 transforms of the same ID (according to AssetsView). What am I missing here? In addition, I also update child's m_Father, I can upload that too if needed. Also, when viewing the transform, AssetsView claims the child has not been removed, but I think it is referencing the older transform and not the one I ammended.

I am using AssetsTools Update 15 v2.0.6 in .NET Framework v4.7.2.

ARGB4444 and RGBA4444 texture formats are decoded incorrectly

RGBADecoders.ReadARGB4444() outputs the color components in the opposite order of the correct one. The format stores each pixel as 0xGB 0xAR, so the code should be:

int a = bytes[i + 1] >> 4;
int r = bytes[i + 1] & 0xf;
int g = bytes[i] >> 4;
int b = bytes[i] & 0xf;
data[dataPos + 0] = (byte)((b << 4) | b);
data[dataPos + 1] = (byte)((g << 4) | g);
data[dataPos + 2] = (byte)((r << 4) | r);
data[dataPos + 3] = (byte)((a << 4) | a); 

ReadRGBA4444() has a similarly incorrect order, and on top of that, doesn't perform the necessary nibble duplication ((component << 4) | component).

System.OutOfMemoryException when Unpack

I am trying to uncompress the bundle files because I can't read the compressed files.
This code:

    AssetsManager helper = new AssetsManager();
    helper.LoadClassPackage("classdata.tpk");
    var inst = helper.LoadBundleFile(inputFilename, false);
    var file = inst.file;
    if (file.bundleHeader6.GetCompressionType() == 0) return;
    using (FileStream stream = File.Open(outputFilename, FileMode.Create, FileAccess.ReadWrite))
    {
        file.reader.Position = 0;
        file.Unpack(file.reader, new AssetsFileWriter(stream));
        stream.Position = 0;
    }

With reference from NuGet crash with message for a bundle file of 900MB but not with a bundle of 6MB
System.OutOfMemoryException in AssetsTools.NET.AssetBundleFile.Unpack(AssetsFileReader reader, AssetsFileWriter writer)
same error from version 2.0.7 to 2.0.9

but work correctly if i donwload the source code and add to my tool the AssetsTools.NET.csproj project

Editing / patching globalgamemanagers?

I see that this tool lets you explore globalgamemanagers but doesn't let you edit it. UABE has this option to export these files to a text file, and then import it again as a way to create a modified version.

I'm actually looking for a way to edit globalgamemanagers programmatically. Just want to be able to go into it, change a setting in BuildSettings, and save a new file. Do you have any tips on how this could be achieved?

Sorry that this isn't an actual issue, I just didn't know any other way to contact you.

RGB565 texture format not supported

AssetsTools.NET doesn't support the RGB565 texture format even though it's quite easy to implement:

public static byte[] ReadRGB565(byte[] input, int width, int height)
{
    int inputLength = width * height * 2;
    byte[] output = new byte[width * height * 4];
    int outputPos = 0;
    for (int inputPos = 0; inputPos < inputLength; inputPos += 2)
    {
        int rgb = (input[inputPos + 1] << 8) | input[inputPos];
        
        int r = (rgb >> 11) & 0x1F;
        r = (r << 3) | (r & 7);

        int g = (rgb >> 5) & 0x3F;
        g = (g << 2) | (g & 3);

        int b = rgb & 0x1F;
        b = (b << 3) | (b & 7);

        output[outputPos + 0] = (byte)b;
        output[outputPos + 1] = (byte)g;
        output[outputPos + 2] = (byte)r;
        output[outputPos + 3] = 0xFF;
        outputPos += 4;
    }
    return output;
}

CI builds

Transparent CI builds would be an important improvement, depending on the platform, I can send a PR that adds this feature.

Modifying Assets

Greetings. Is there a way to ADD asset to .assets file?
I have been looking for a code to ADD an asset for a long time.
I used example code from readme for modification:

var am = new AssetsManager();
am.LoadClassPackage("classdata.tpk");

var inst = am.LoadAssetsFile("resources.assets", true);
am.LoadClassDatabaseFromPackage(inst.file.typeTree.unityVersion);

var inf = inst.table.GetAssetInfo("MyBoringAsset");
var baseField = am.GetTypeInstance(inst.file, inf).GetBaseField();
baseField.Get("m_Name")
.GetValue()
.Set("MyCoolAsset");
var newGoBytes = baseField.WriteToByteArray();
//AssetsReplacerFromMemory's monoScriptIndex should always be 0xFFFF unless it's a MonoBehaviour
var repl = new AssetsReplacerFromMemory(0, inf.index, (int)inf.curFileType, 0xFFFF, newGoBytes);
var writer = new AssetsFileWriter(File.OpenWrite("resources-modified.assets"));
inst.file.Write(writer, 0, new List() { repl }, 0);

My goal is to ADD an asset and change it or ADD a ready asset.
This code changes the name, but I need to ADD an asset.

I have also tried this code:

var templateField = new AssetTypeTemplateField();
var cldbType = AssetHelper.FindAssetClassByName(am.classFile, "TextAsset");
templateField.FromClassDatabase(am.classFile, cldbType, 0);
var baseField = ValueBuilder.DefaultValueFieldFromTemplate(templateField);
baseField.Get("m_Name").GetValue().Set("MyCoolTextAsset");
baseField.Get("m_Script").GetValue().Set("I have some sick text");

//or you can just use table.assetFileInfoCount + 2 but that doesn't always work
var nextAssetId = table.assetFileInfo.Max(i => i.index) + 1;
replacers.Add(new AssetsReplacerFromMemory(0, nextAssetId, cldbType.classId, 0xffff, baseField.WriteToByteArray()));
//... do other replacer stuff

But when I use it my program crashes.
What do I need to do?

Reading asset bundle from memory

Hi,

Bit a of a newbie here. (especially when it comes to Unity assets) I have some asset bundles that are loaded into memory that I'm looking to read. They are of type MonoBehaviour, as I understand.

I think I can use the following to load the data, but I'm not sure where to go after that.

var bun = new AssetBundleFile();
bun.Read(new AssetsFileReader(memoryStream), true);
if (bun.bundleHeader6.GetCompressionType() != 0)
{
    bun = BundleHelper.UnpackBundle(bun);
}

Decompressing some UnityFS archives to memory fails with various exceptions

Hi,

I'm trying to decompress some UnityFS archives that neither UABE or AssetsTools.NET can handle, but AssetsTools is at least providing meaningful exceptions. I'm curious whether it is known that this version of the format doesn't work, or these perhaps are using some new or unusual version of the format?

The header looks like this:
UnityFS.....5.x.x.2018.4.23f1

The '5.x.x' makes it unclear to me whether this version of Unity is producing one of the formats your README says are unsupported (5.0-5.4) or what. 2018.4.23f1 appears to be after the officially numbered 5.x releases, but isn't that new... both UABE and AssetTools agree that they are compressed. If it means anything in this context, the FS files are from an Android game. It has MP4 files and CRIWare archives next to it that both decompress as-is with existing tools, there's no weird encryption applied to them, so I would be surprised if they did anything fancy to the UnityFS packages that leaves the headers intact. The 'opening bundle file' window says these archives are compressed with LZ4.

Sample exception messages:

An error occurred:
The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'.

Parameter name: chars
An error occurred:
Unable to read beyond the end of the stream.
No valid assets files found in the bundle.
An error occurred:
Arithmetic operation resulted in an overflow.

Replacing assets not working correctly

I'm trying to replace some assets in an asset bundle using a tool I made that runs on this library (https://github.com/Skyluker4/UnityAssetReplacer). When I save a new asset bundle to replace assets, something gets messed up. Without even actually replacing any assets and just making a copy of the bundle using AssetTools.NET it ends up being 20 bytes less than the original. The beginning of the file differs from the original (about the first few hundred bytes or so are different).

This is only for one specific asset bundle, other ones work fine. When trying to read from UABE, it says "invalid assets file".

Here's a look at the files -- the original on the left and the one AssetTools.NET generated on the right.

image

I don't know if this is a problem with my own code or a problem with the library. I'm using AssetReplacerFromMemory to replace the assets and BundleReplacerFromMemory and AssetsFileWriter to create the new bundle.

Asset bundle data offset is increased by 16 bytes when writing

When writing a file I read with AssetsManager, the offset of the asset data is increased from 0x1000 to 0x1010. I've tested it with Unity versions 2017.4.33f1 and 2018.4.26f1 and it uniformly increases the offset by 16 bytes. When replacing the original file, the mismatch causes Unity to hang with the following errors (the first probably being specific to the file):

Mismatched serialization in the builtin class 'PreloadData'. (Read 12 bytes but expected 144 bytes)
 
(Filename:  Line: 1929)

The file 'sharedassets0_original.assets' is corrupted! Remove it and launch unity again!
[Position out of bounds!]
 
(Filename:  Line: 215)

I isolated the mismatch to if statement where after the method pads the file to 0x1000 bytes, it adds another 16 if the position is a multiple of 16. I've been removing the first case during development, but is there a way to make sure whatever bug got fixed stays fixed while eliminating the mismatch?

I have attached the code I used to test the issue and the bundles used and produced. Thank you for making this project, it is very helpful!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.