nesrak1 / AssetsTools.NET

Read and write unity assets/bundle files, based on https://github.com/SeriousCache/UABE
MIT License
521 stars 101 forks source link

System.ArgumentOutOfRangeException: Non-negative number required. #14

Closed neobenedict closed 4 years ago

neobenedict commented 4 years ago

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)

neobenedict commented 4 years ago

This asset seems bugged in general;

Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')"} | System.ArgumentOutOfRangeException

   at System.ThrowHelper.ThrowArgumentOutOfRange_IndexException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at AssetsTools.NET.Extra.AssetsManager.GetATI(AssetsFile file, AssetFileInfoEx info, Boolean forceFromCldb) in G:\Projects\Rayshift\AssetTools.NET\Extra\AssetsManager\AssetsManager.cs:line 185
   at Rhongomyniad.Assets.AssetFunctions.LoadAllObjects(AssetsFileInstance mainFile) in G:\Projects\Rayshift\Rhongomyniad\Assets\AssetFunctions.cs:line 142
   at Rhongomyniad.Assets.ImageProcessing.PrepareAtlasComponents(FileStream inputStream) in G:\Projects\Rayshift\Rhongomyniad\Assets\ImageProcessing.cs:line 129
   at Rhongomyniad.Assets.Models.AtlasModel..ctor(FileStream inputImage) in G:\Projects\Rayshift\Rhongomyniad\Assets\Models\AtlasModel.cs:line 16
   at DebugLibrary.Program.Main(String[] args) in G:\Projects\Rayshift\DebugLibrary\Program.cs:line 153
        public Dictionary<AssetFileInfoEx, List<object>> LoadAllObjects(AssetsFileInstance mainFile)
        {
            Dictionary<AssetFileInfoEx, List<object>> output = new Dictionary<AssetFileInfoEx, List<object>>();
            foreach (AssetFileInfoEx info in mainFile.table.assetFileInfo)
            {
                ClassDatabaseType type = AssetHelper.FindAssetClassByID(am.classFile, info.curFileType);
                if (type == null)
                    continue;

                var baseField = am.GetATI(mainFile.file, info).GetBaseField();
        public AtlasComponents PrepareAtlasComponents(FileStream inputStream)
        {
            var am = new AssetFunctions();
            var loadedAsset = am.LoadAsset(inputStream);
            var objectList = am.LoadAllObjects(loadedAsset);

https://i.imgur.com/VJtTm2N.png thus it is the Texture2D objects causing the issue

nesrak1 commented 4 years ago

This bundle is in 5.3.4, but the library and the tools really only support 5.5 and on. The two issues are that GameObjects are laid out differently so AssetInfo's GetAssetNameFast method fails because it only jumps 12 bytes instead of 16 for each asset. The real issue is that the field names are different, in pre 5.5, the field was just "second". Now it's called "component". curFileType and inheritedUnityClass are also used in pre 5.5 which I don't have handled in AssetsView. I did some quick patches and it mostly works but it's really hacked together so I'm not releasing it right now. image

neobenedict commented 4 years ago

Can you send me the patches or tell me how to avoid the error that is happening in my second comment? Is it only to do with reading the name? I don't actually need that in this case, so I could patch it out. Or otherwise fix it somehow.

neobenedict commented 4 years ago

OK, well the code causing the error is ushort scriptIndex = file.typeTree.unity5Types[info.curFileTypeOrIndex].scriptIndex; where info.curFileTypeOrIndex = 28, but the unity5types is only 8 entries long. So it's something beyond what I could fix without completely reverse engineering Unity from scratch. Some advice would be appreciated.

nesrak1 commented 4 years ago

AssetsViewPre55.zip Here's the fix, although it's just something I put together in a few minutes, it probably will still break in a lot of cases and may not even work in files 5.5 and above. It's just that the tools weren't made for older version files because I never modded any games before 5.5 while writing this, and the format between 5.4 and 5.5 changed a lot, so I never implemented anything for it.

nesrak1 commented 4 years ago

At some point I'm planning to add real support for it, I just haven't gotten around to it.

nesrak1 commented 4 years ago

AssetsViewPre55.zip I forgot to include the AssetsTools.NET.dll file as well so here's that ^

neobenedict commented 4 years ago

OK, I'm actually using files from the wrong version of the game there to test because I'm dull, thus it's not critical you need to fix this as soon as possible. The library otherwise works fine when I actually use the newer files. Thanks for the patch though, I'll take a look if I run into issues.

What are your plans for image export implementation? I've used bits of code from uTinyRipper to achieve it and all is well on my end but uTinyRipper has no licence so I don't think you can just copy paste their huge image processing functions. Their library also relies on 3 external libs and I assume you're aiming for 100% cross platform support on the base library which using external windows dlls from AssetStudio won't have. (luckily my textures are all ETC_RGB4 and there is a c# implementation of that)

PS. if you have a gitter or IRC or discord might be easier to discuss things

nesrak1 commented 4 years ago

Yes I'm aiming for cross plat support. Thankfully I have a mostly working port of this library https://github.com/hglm/detex in c# that I'll probably add soon. It's not native fast but it's fast enough.