nesrak1 / UABEA

c# uabe for newer versions of unity
MIT License
1.21k stars 153 forks source link

UABEA Displays incorrect file size #267

Closed Jubilee333 closed 1 year ago

Jubilee333 commented 1 year ago

UABEA Displays incorrect file size When viewing assets in UABEA, it displays an incorrect file size of a texture asset. It displays as 200 bytes, when the data says it is 524288 bytes. Also, when I export the texture, it is the larger size, so reimporting the exact same asset back into it doesn't work either. This makes the texture importing function impossible to use, because the edited file will be larger than the original.

To Reproduce Steps to reproduce the behavior:

  1. Open .unity3D file
  2. Decompress to memory
  3. Select edit
  4. Observe incorrect file size

Expected behavior I expected the file size to be 524288 bytes, as the data says.

Screenshots Incorrect file size: Screenshot 2023-07-21 232426

File size according to data: Screenshot 2023-07-21 233414

Additional context For context, I am trying to mod this texture2D file. In order for the file to work in the game, the size of this asset need to be less than or equal to the original texture's size.

nesrak1 commented 1 year ago

The datagrid's size column only shows the asset's size, not the size in any other files that asset uses like texture data in resS. If you export raw and check the size of that file, it should match up with what you see in the datagrid. To show the size in resS as well I'd have to parse every texture2d up front and show the calculated size which may cause a longer load for files with a lot of textures.

Also, when I export the texture, it is the larger size, so reimporting the exact same asset back into it doesn't work either. This makes the texture importing function impossible to use, because the edited file will be larger than the original.

I'm not sure what you mean "impossible to use". Just because the file size is bigger doesn't mean it's broken. In this case, UABEA (and UABE as well) set image data rather than writing to the resS. This is a valid and alternative way to give Unity the texture data. The main reason is that imported textures can be bigger or smaller than the original and since the resS is just a bunch of textures side by side, increasing the size would require rebuilding the resS which would also take a lot of time. Yes, the old texture data can't be deleted, but it's more stable to do it this way.

Jubilee333 commented 1 year ago

Sorry if I'm being dense, but how exactly would I go about replacing it, without editing the resS?

I'm not sure what you mean "impossible to use".

Sorry, should've phrased that better. When I edit the file with the new texture, it is a larger file size than the original, so it doesn't work in-game.

nesrak1 commented 1 year ago

A larger file size would not cause the texture to fail to load ingame. If the bundle is in StreamingAssets, maybe look here for a fix: https://github.com/nesrak1/UABEA#addressables

Jubilee333 commented 1 year ago

Yeah, it's in StreamingAssets, then in a Batched folder, then in an assets.dat file. I have to use a .bms script to deconstruct the assets.dat, then reinject modded files with that script as well. When you try to reimport with a larger file, it makes a huge fuss and I have to "force" the file in. Then, when I run the game (PR:BFTG) and select the modded character, it loads indefinitely.

If the bundle is in StreamingAssets, maybe look here for a fix: https://github.com/nesrak1/UABEA#addressables

Unfortunately I have no idea what to do with this, does there happen to be a readme or something to help me get started?

nesrak1 commented 1 year ago

Yeah, it's in StreamingAssets, then in a Batched folder, then in an assets.dat file. I have to use a .bms script to deconstruct the assets.dat, then reinject modded files with that script as well.

That seems like a custom bundle storing format. That means the usual catalog.json patcher won't work since it probably doesn't exist.

When you try to reimport with a larger file, it makes a huge fuss and I have to "force" the file in.

Unfortunately with the way things work right now, UABEA will always make the bundle bigger because it's inserted into image data and not removed from the resS. You may be able to compress the bundle with lzma to be really small and pad the end of the file to come back to the original size.

You may also still have the CRC checking issue, just in a custom format. Assuming this is PC, you could check the unity player logs (Google to find the path to this) to see if it complains about CRC or not.

Jubilee333 commented 1 year ago

Alright, thanks.

You may be able to compress the bundle with lzma to be really small and pad the end of the file to come back to the original size.

Do you know of any LZMA compressors, besides the one built into UABEA?

nesrak1 commented 1 year ago

Why? I know it's slow but it should compress pretty well. UABE and probably UnityPy have compression code.

Jubilee333 commented 1 year ago

(1: Original, 2: Decompressed and edited, 3: Compressed and edited) image

Speed is no issue, it's a small file, it just doesn't compress to be small enough, so I was wondering if using another compressor would be the solution.

nesrak1 commented 1 year ago

If you're using a block format that stays the same size (m_CompleteSize stays the same after import), you may be able to do this:

  1. Make sure you are looking at the original bundle.
  2. Import the new texture into the Texture2D.
  3. Open the texture asset with view data. Take a look at the size and first few bytes of the image in image data.
  4. Export raw and open in a hex editor. Look for the first few bytes you saw in image data and to the length you saw.
  5. Paste it into a new file temporarily. Reopen the bundle without saving.
  6. Export the resS file from the bundle. Press view data on the original Texture2D.
  7. Look at the offset and size under m_StreamData. Go to that offset in the resS you just exported. Hopefully the size matches the size of the raw image data you extracted from earlier.
  8. Overwrite the bytes at that offset.
  9. Import the new resS over the old one (do not press remove first.)
Jubilee333 commented 1 year ago

Ok, things were looking good until step 7.

Go to that offset in the resS you just exported.

In a hex editor? Not sure what you mean, how do I go to the offset?

nesrak1 commented 1 year ago

Yes sorry, in a hex editor.

Jubilee333 commented 1 year ago

I can't seem to find it, what should I bee looking for? The number value? When I do ctrl+f nothing comes up with the value.

image

(forgive the dumb questions, I'm new to hex :/ )

nesrak1 commented 1 year ago

The offset isn't a value in the resS. It's just the byte offset from the start. If you're using HxD or imhex for example, you could press ctrl+g to go to an offset. Make sure you're in decimal and not hex mode. In HxD you can paste overwrite with ctrl+b and imhex with ctrl+shift+v.

Jubilee333 commented 1 year ago

Ok, I think I'm at part 8. When I ctrl+g it brings me to the start of the line of Offset (h) 0053A360. How many bytes do I replace?

nesrak1 commented 1 year ago

The hope is that the data you extracted from the new raw texture data (step 4) and m_StreamData's size (step 7) should be the same. So you would overwrite the entire old raw texture data (in resS) with the new raw texture data.