-
-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Edit Texture2D make file corrupted #230
Comments
I fixed code in in @image_data.setter
def image_data(self, data: bytes):
self._image_data = data
# ignore writing to cab for now until it's more stable
if self.version >= (5, 3) and self.m_StreamData.path:
path = self.m_StreamData.path
cab = self.assets_file.get_writeable_cab(path.split("/")[-1])
if cab:
self.m_StreamData.offset = cab.Position
cab.write(data)
self.m_StreamData.size = len(data)
self.m_StreamData.path = cab.path and i got this
can i remove this cab and add modified cab myself? |
Hello. Can you provide the bundle file? I'm just curious, maybe I can help. |
ui_jiazai.zip |
It's strange but UnityPy thinks the file is encrypted |
haha,it's becauese in that version of decryptor i forgot fix header's flags and blocks' flag so UnityPy thinks the file is encrypted. |
I'm happy to tell you that I managed to solve this problem. img_data, tex_format = Texture2DConverter.image_to_texture2d(
img, self.m_TextureFormat
) Then find the corresponding data in the unpacked bundlefile and replace it directly before repacking. |
You can write an embedded texture using typetree changing just a few values (not in resS). from PIL import Image
for obj in env.objects:
if obj.type.name == "Texture2D":
data = obj.read()
fp = os.path.join(replace_dir, data.name)
pil_img = Image.open(fp)
# UnityPy converts to original format by default
data.set_image(pil_img)
data.save_via_tree() classes\Texture2D.py def save_via_tree(self):
tree = self.read_typetree()
if "m_MipMap" in tree:
tree["m_MipMap"] = self.m_MipMap
else:
tree["m_MipCount"] = self.m_MipCount
tree["m_TextureFormat"] = self.m_TextureFormat
tree["m_CompleteImageSize"] = len(self.image_data)
tree["image data"] = self.image_data
# Reset StreamData
tree["m_StreamData"] = {
"offset": 0,
"size": 0,
"path": ""
}
self.save_typetree_dump(tree) classes\Object.py def save_typetree_dump(self, tree: dict, nodes: list = None, writer: EndianBinaryWriter = None):
return self.reader.save_typetree(tree, nodes, writer) Saving for name, file in env.files.items():
if hasattr(file, "is_changed") and file.is_changed:
file_name = os.path.basename(name)
with open(os.path.join(dest, file_name), "wb") as f:
f.write(file.save(packer="original")) |
thanks for your reply |
my solution be like this import os
from PIL import Image
import UnityPy
from UnityPy.export import Texture2DConverter
dir = r"work"
src = r"test.asset"
dst = r"work\test.asset.fix"
# set unityCN key for unityCN
# bundle_key = ""
# UnityPy.set_assetbundle_decrypt_key(bundle_key)
# load file
env = UnityPy.load(os.path.join(dir, src))
# view Texture2D info
# some file has more than one texture2D data store in .resS
textureList = {}
totalSize = 0
for obj in env.objects:
if obj.type.name == "Texture2D":
data = obj.read()
# print(data.name)
# print(f"offset:{data.m_StreamData.offset}")
# print(f"size:{data.m_StreamData.size}")
# print(f"path:{data.m_StreamData.path}")
# print(f"TextureFormat:{data.m_TextureFormat}")
textureList[data.name] = {
"offset": data.m_StreamData.offset,
"size": data.m_StreamData.size,
"path": data.m_StreamData.path,
"TextureFormat": data.m_TextureFormat
}
totalSize += data.m_StreamData.size
# convert data
# toLoadImg should be the same wide/height as toEditTexture
# so that img_data has the same size as data.m_StreamData.size
toEditTextureName = "example"
toLoadImg = os.path.join(dir, "example.fix.png")
img = Image.open(toLoadImg)
toEditTexture = textureList[toEditTextureName]
img_data, tex_format = Texture2DConverter.image_to_texture2d(
img, toEditTexture["TextureFormat"]
)
# replace data with different size is possible
# when needed i will add support
if len(img_data) != toEditTexture["size"]:
raise ValueError(f"data size missmatch,except {toEditTexture['size']} but recieved {len(img_data)}")
# save file with no compression
newFileData = bytearray(env.file.save(packer="none"))
size = len(newFileData)
begin = size - totalSize + toEditTexture["offset"]
newFileData[begin:begin + toEditTexture["size"]] = img_data
with open(dst, 'wb') as f:
f.write(newFileData)
env = UnityPy.load(dst)
with open(dst, 'wb') as f:
f.write(env.file.save(packer="lz4")) |
Code
I use example code to edit Texture2D
and save like this
Error
I got
mabye because the game implemented its own dynamic resource loading strategy
Bug
however,using assetstudio to see dump information about Texture2D before and after edit, something broken
before
after
i think that's the problem,i tried uabea and got the same result
To Reproduce
The text was updated successfully, but these errors were encountered: