Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 11/08/2025 in Posts

  1. I'm trying my best to make it load somehow
    4 points
  2. Actually the LZSS provide above, is wrong, for the files. I did the reverse enginner of the algorithim, Try the tool, see if the image get right TenchuWoH_DeCompressor.zip
    3 points
  3. I've just released new version of ImageHeat 🙂 https://github.com/bartlomiejduda/ImageHeat/releases/tag/v0.39.1 Changelog: - Added new Nintendo Switch unswizzle modes (2_16 and 4_16) - Added support for PSP_DXT1/PSP_DXT3/PSP_DXT5/BGR5A3 pixel formats - Fixed issue with unswizzling 4-bit GameCube/WII textures - Added support for hex offsets (thanks to @MrIkso ) - Moved image rendering logic to new thread (thanks to @MrIkso ) - Added Ukrainian language (thanks to @MrIkso ) - Added support for LZ4 block decompression - Added Portuguese Brazillian language (thanks to @lobonintendista ) - Fixed ALPHA_16X decoding - Adjusted GRAY4/GRAY8 naming - Added support section in readme file
    2 points
  4. The textures are compressed with ZSTD - just that type 0 means the whole file is not compressed. But there doesn't seem to be any encryption once decompressed - looks something like ETC format:
    2 points
  5. Thanks for some info from here and made a tool for unpacking and packing localize map files, if someone is interested in it. https://github.com/dest1yo/wwm_utils
    2 points
  6. Animation file from FGO arcade, uses the same engine as various Project DIVA titles but the animation files are formatted in a different way. .mot Tool: https://github.com/h-kidd/noesis-project-diva (works with FGO Arcade's model files and .mot files from Miracle Girls Festival and Project DIVA but it doesn't work with FGO Arcade's .mot files, but you can edit the source code of the tool to try to make it work with the game's .mot files) Sample file is in the attachment. mot_svt_0001.zip
    1 point
  7. Today I am gonna discuss on how we can reverse engineer the extraction of the game archives, sit back because this is where it starts to get interesting... +==== TUTORIAL SECTION ====+ But how do those files store game assets like 3D Models, Textures, Sounds, Videos and etc... Well, the anwser is simple, they usually bundle them, they pack them close together in their eighter compressed or even encrypted form (Rarely). The packed file usually contains compressed data and a small separator/padding between them, hover it doesn't tell us the name and the path of the file we want to com press, whch is a problem. Heck, we don't even know which compression method was used and which "flavour/version" and how the decompressed file should look like... That's where QuckBMS comes to help. =| QuickBMS |= QuickBMS has one very specific function I wanna talk about, it's "comptype unzip_dynamic" it supports millions methods and their "flavours/versions". It has also a very fast perfomance and is good for extracting the multiple files out of the package at once. There are also already lots of QuckBMS scripts out there for extracting specific archives, but I'll talk about that later. =| PRACTICAL STEPS |= As said previously, the block separators/markers are very usefull to identify but turns out most of the compression methods have their own headers and magic numbers, here are few of them: Magic numbers: ZLIB: 78 01 (NoComp) 78 5E (Fastest) 78 9C (Default) 78 DA (Maximum) LZ4: [No Magic Numbers] LZ4 Frame: 04 22 4D 18 (Default) LZW: [No Magic Numbers] LZO: [No Magic Numbers] BZIP/BZIP2: 42 5A 68 GZIP: 1F 8B 08
    1 point
  8. Introduction This question is probably the most asked one and it makes total sense why, the answer unfortunatelly is pretty generic in it's nature, it depends but if we dive deeper turns out it's not as hard as you think might be here is why I personally think this way... Reverse engineering the game, specifically for asset extraction, requires 4 different steps to create: 1. Extract Game Archive, (Reverse enigneer game's extractioon method, spot a compression method, decrypt xor keys (Rarely)) 2. Reverse Enigneer Binary 3D model files 3. Reverse egnineer Binary Texture files 4. Reverse egnineer the Binary Audio files While those are not extreamly hard to topics to learn, it can took some time to figure them out yourselfe. There are numereous ways to reverse engineer those tasks, you can do it manually via binary inspection, or by using, exploits or even by using leaked Beta Builds or reloaded versions, that often are packed with .PDB files (debug symbols) that can be loaded into Ghidra for near source code, code debugging experience. While the best one is still a binary inspection, there are already dedicated tools for this, for inspecting and extracting manually sample by sample, but currently in time being there aren't any automated programs for this so you must choose to rely on Python scripts. For extracting game archives I recommend QuickBMS for model extraction Model Researcher for Textures Raw Texture Cooker and Audacity for Audio... By extracting all of the game content don't forget about the Headers and Magic Numbers, No matter how Payload loos like, the headers are always the same and often contain super usefull info with them. Graphic Debuggers vs Reverse Engineering This is hot topic is the most intersting one, since yes, Dumping 3D Models and Textures + Recording the Audio's using Graphic Debuggers like RenderDoc, nvidia Nsight Graphics and NinjaRipper Exploit obviously way, way easier than any reverse engineering the proprietary files, it can be done in few minutes vs it can took a few days to mounths in Reverse Engineering so the difference is huge sometimes, hovewer after you reverse engineered the binary files you have access to extreamly fast asset "ripping" speeds without relying on the drawcalls and of course you have access to all of the cut contents and very very easier and faster Map/World "ripping". There are obviously upsides and downsides in both of the methods, I personally recommend using exactly what you need for, if there are already scripts for extracting and maybe even converting some binary proprietary assets then go for it!
    1 point
  9. My best bet: edit: fail, at 0x1d934 there's only a copy of the mesh
    1 point
  10. You could check the MakeH2O_log.txt. If you find a structure like 12 4 4 4 4 4 (for example) the last "4 bytes block" might be alpha uvs (just a wild guess). edit: it's 16 8 8 4 4 here Try using 82ea3, 4 for uvs. Looks promising.
    1 point
  11. I've been trying to work on Jon Jones hair (beard) file and was able to export it with the beard diffuse UV, but I'm struggling to get the proper UV for the alpha texture. Any suggestions? hair_jon_jones_model.mcd(decompressed).7z
    1 point
  12. I think you've already set up the aes-key and the correct version of Octopath Traveler 0 (5.4) on fmodel. You need to add the usmap file, which I attached. To do this, go to Settings->Mapping File Path and select the game's usmap file. Then, in Fmodel, navigate to the correct folder (e.g., Content/Local/DataBase/GameText/Localize/EN-US/SystemText/GameTextUI.uasset) and export the file to .json, with right-click and then Save properties (.json).
    1 point
  13. I am attaching the fmodel json file. With uassetgui, what procedure did you follow to obtain that result? Maybe I'm missing something, as this is the first time I've used uassetgui. Edit: Ah ok, thanks, with .\UAssetGUI tojson GameTextUI.uasset GameTextUI.json VER_UE5_4 Mappings.usmap I can get the base64 code, but it is unreadable: ����������m_DataList�d��m_id��m_gametext��No data.�������������m_id�m_gametext��Held�������������m_id �m_gametext��None�������������m_id! GameTextUI_fmodel.rar
    1 point
  14. Yeah, the DWord face indices totally don't fit but I have a déjà vue of this picture, maybe on former Xentax? edit: correct vertex start is 0x144
    1 point
  15. When you choose "uncompressed" the file size should be bigger than for a DXT5 file. I'd try some other tool, maybe Gimp, for testing.
    1 point
  16. This file stores luac and dat data, so it cannot be processed using the unityfs split script. I wrote a new split script to experimentally disassemble the file content you provided and decompile the lua file. If you want to decompile please enable the -j parameter Basic usage (no decompilation) python pkg.py input.patch output_dir With decompilation (slower) python pkg.py input.patch output_dir -j For decompilation, please download unluac from other locations. After compilation, place the .jar file in the same directory as the script. Due to different compilation environments, errors may occur, so unluac needs to be compiled by yourself. pkg.py
    1 point
  17. I remember to make a request in your github about it. 👍 Somehow, we were not able to see these textures in ImageHeat, only after extraction and decompression. Anyway, for the Switch textures it seems to be an issue as h3x3r said above and I confirm it too. In the attachment you find all the textures in UNIFORM.TEX (including jersey-color) from the Switch version already decompressed. The stock texture file is in the Switch files in the first post (UNIFORM.TEX). In the screenshot below you see the parameters for the jersey-color texture. Maybe useful when you have time to check it to help you fix ImageHeat. UNIFORM Switch decompressed.zip
    1 point
  18. You need to decompress them first. Only then you can succeed... Here's jersey-color after decompression. PS4 format. But there's problem with switch format. ImageHeat doesn't support swizzle format. But RawTex can handle this.
    1 point
  19. But anyway, seeing as I had some time, this QuickBMS script will decompress the files correctly. Still needs some manual manipulation in something like ImageHeat to show the correct image: rat_ps2_dps.zip
    1 point
  20. The game have update and they hard-coded new text in .mpk lua script, because some words have many different meaning depend on the context. With packet sniffing, i observed that the game download some .pak file from easebar.com and put them in .mpk file. These file are encrypted.
    1 point
  21. Decided to extract some key frames. from that .mot file I shared earlier. Wonder if there is any insight. The NaNs are interesting tho.
    1 point
  22. It's Unity, but seems to have a protection layer so it can't be opened in Asset Studio. Game Assembly: https://www.mediafire.com/file/3i7kvobi4nacnbh/GameAssembly.zip/file THO.zip
    1 point
  23. fmt_FGOArcade_mot.py Still incomplete
    1 point
  24. I made a blender addon to import models, textures and animations for dolphin wave and other games that used the same engine. it can import lzs and lza files as is. You don't need to decrypt or decompress the files https://github.com/Al-Hydra/blenderBUM
    1 point
  25. To whoever ends up here in the future, there is a really simple to use utility to convert files from Xbox ADPCM to PCM and vice-versa on Github: Sergeanur/XboxADPCM Thanks for the thread, I really thought the WAV files I had were lost forever due to an obsolete codec..! In my case, I am porting the PT-BR voiceover of Max Payne from PC to Xbox, which I am surprised wasn't done before.
    1 point
  26. I found the solution. Use the pak.py python script (i uploaded) in the same directory as the .data file This will extract the UE4 .pak file from the .data file Since the version is 4.27, use the QuickBMS 4.27 Unreal Engine Script to extract all data! Then you can use UModel to extract models/audio etc! # Unreal Engine 4 - Unreal Tournament 4 (*WindowsNoEditor.pak) (script 0.4.27e) # script for QuickBMS http://quickbms.aluigi.org math NO_TAIL_INFO = 0 # set it to 1 for archives with corrupt/missing tail information (extract without index) math VERSION = 3 # set it to 3 if NO_TAIL_INFO = 1 for most of modern games quickbmsver "0.12" callfunction QUICKBMS_4GB_CHECK 1 # set your AES_KEY here as umodel hex ("0x1122...") or C string ("\x11\x22...") # don't change AES_KEY_IS_SET, it will be handled automatically set AES_KEY binary "" math TOC_FILE = 0 math ALTERNATIVE_MODE = 0 math AES_KEY_IS_SET = 0 math BASE_PATH_INCLUDED = 1 math DIR_FLAG = 1 math NAME_FROM_ARRAY = 0 math SKIP_COUNT = 0 get ARCHIVE_NAME basename get ARCHIVE_PATH FILEPATH math CHUNK_OFFSET_ABSOLUTE = -1 # default, enabled # 1 = HIT math WORKAROUND = 0 if NO_TAIL_INFO != 0 get OFFSET asize math ALTERNATIVE_MODE = 1 else goto -0xcc # version 11 (4.26-4.27) savepos MAGIC_OFF get MAGIC long get VERSION long endian guess VERSION get OFFSET longlong get SIZE longlong getdstring HASH 20 xmath SIZE "MAGIC_OFF - OFFSET - 1" get FSIZE asize savepos CUR_POS if CUR_POS = FSIZE string COMP1 = "" else get CHECK byte if CHECK > 1 goto -1 0 SEEK_CUR endif getdstring COMP1 32 getdstring COMP2 32 string COMP1 l COMP1 string COMP2 l COMP2 endif if VERSION >= 3 goto MAGIC_OFF goto -1 0 SEEK_CUR get ENCRYPTED byte if ENCRYPTED != 0 callfunction SET_AES_KEY 1 log MEMORY_FILE5 OFFSET SIZE encryption "" "" else log MEMORY_FILE5 OFFSET SIZE endif math TOC_FILE5 = -5 endif goto 0 callfunction GET_BASE_PATH 1 endif get FILES long TOC_FILE5 getdstring DUMMY 12 TOC_FILE5 get HASHES_OFFSET longlong TOC_FILE5 math HASHES_OFFSET - OFFSET get HASHES_SIZE longlong TOC_FILE5 getdstring DUMMY 24 TOC_FILE5 get NAMES_OFFSET longlong TOC_FILE5 math NAMES_OFFSET - OFFSET get NAMES_SIZE longlong TOC_FILE5 getdstring DUMMY 24 TOC_FILE5 savepos BASE_INDEX_OFF TOC_FILE5 goto NAMES_OFFSET TOC_FILE5 math CHUNK_SIZE = 0x10000 # just in case... for i = 0 < FILES callfunction GET_NAME_AND_OFFSET 1 if NAME = "" continue NEXT0 endif savepos TMP_OFF TOC_FILE get OFFSET longlong TOC_FILE get ZSIZE longlong TOC_FILE get SIZE longlong TOC_FILE get ZIP long TOC_FILE getdstring HASH 20 TOC_FILE math CHUNKS = 0 math ENCRYPTED = 0 if VERSION >= 3 if ZIP != 0 get CHUNKS long TOC_FILE for x = 0 < CHUNKS get CHUNK_OFFSET longlong TOC_FILE get CHUNK_END_OFFSET longlong TOC_FILE putarray 0 x CHUNK_OFFSET putarray 1 x CHUNK_END_OFFSET next x endif get ENCRYPTED byte TOC_FILE get CHUNK_SIZE long TOC_FILE endif #if ALTERNATIVE_MODE != 0 savepos TMP_OFF TOC_FILE math OFFSET + TMP_OFF #endif #comtype copy callfunction COMPRESSION_TYPE 1 if CHUNKS > 0 log NAME 0 0 append math TMP_SIZE = SIZE if CHUNK_OFFSET_ABSOLUTE < 0 && OFFSET != 0 getarray CHUNK_OFFSET 0 0 if CHUNK_OFFSET u< OFFSET math CHUNK_OFFSET_ABSOLUTE = 0 else math CHUNK_OFFSET_ABSOLUTE = 1 endif endif for x = 0 < CHUNKS getarray CHUNK_OFFSET 0 x getarray CHUNK_END_OFFSET 1 x math CHUNK_ZSIZE = CHUNK_END_OFFSET math CHUNK_ZSIZE - CHUNK_OFFSET math CHUNK_XSIZE = CHUNK_ZSIZE if ENCRYPTED != 0 callfunction SET_AES_KEY 1 math CHUNK_XSIZE x 16 endif if TMP_SIZE u< CHUNK_SIZE math CHUNK_SIZE = TMP_SIZE endif math CHUNK_OFFSET = OFFSET if ZIP == 0 log NAME CHUNK_OFFSET CHUNK_SIZE 0 CHUNK_XSIZE else clog NAME CHUNK_OFFSET CHUNK_ZSIZE CHUNK_SIZE 0 CHUNK_XSIZE endif math TMP_SIZE - CHUNK_SIZE math OFFSET + CHUNK_XSIZE next x append else # the file offset points to an entry containing # the "same" OFFSET ZSIZE SIZE ZIP HASH ZERO fields, # just an additional backup... so let's skip them savepos BASE_OFF TOC_FILE math BASE_OFF - TMP_OFF math OFFSET + BASE_OFF math XSIZE = ZSIZE if ENCRYPTED != 0 callfunction SET_AES_KEY 1 math XSIZE x 16 endif if ZIP == 0 math BLOCK = 0x40000000 xmath FSIZE "OFFSET + ZSIZE" log NAME 0 0 append for OFFSET = OFFSET < FSIZE xmath DIFF "FSIZE - OFFSET" if DIFF < BLOCK math XSIZE = DIFF if ENCRYPTED != 0 math XSIZE x 16 endif log NAME OFFSET DIFF 0 XSIZE else log NAME OFFSET BLOCK endif math OFFSET + BLOCK next append else clog NAME OFFSET ZSIZE SIZE 0 XSIZE endif endif encryption "" "" if ALTERNATIVE_MODE != 0 if CHUNKS == 0 math OFFSET + XSIZE endif goto OFFSET get TMP1 longlong get CHECK byte if TMP1 == 0 && CHECK != 0 goto OFFSET continue NEXT1 else goto OFFSET endif xmath CHECK "0x800 - (OFFSET % 0x800)" if CHECK <= 16 padding 0x800 endif savepos OFFSET get TMP1 longlong get TMP2 longlong if TMP2 == 0 padding 0x800 else goto OFFSET endif label NEXT1 endif label NEXT0 next i print "\nEntries ignored: %SKIP_COUNT%" for i = 0 < SKIP_COUNT getarray NAME 7 i print "Ignored entry: %NAME%" next i startfunction SET_AES_KEY_ASK math AES_KEY_IS_SET = 1 print "The archive is encrypted, you need to provide the key" if AES_KEY == "" set KEY unknown "???" else set KEY binary AES_KEY endif if KEY == "" math AES_KEY_IS_SET = -1 set AES_KEY string "No key provided, encryption disabled" elif KEY strncmp "0x" string KEY << 2 string AES_KEY h KEY else set AES_KEY binary KEY endif print "KEY: %AES_KEY%" endfunction startfunction SET_AES_KEY if AES_KEY_IS_SET == 0 callfunction SET_AES_KEY_ASK 1 endif if AES_KEY_IS_SET > 0 encryption aes AES_KEY "" 0 32 endif endfunction startfunction GET_BASE_PATH get NAMESZ long TOC_FILE5 getdstring BASE_PATH NAMESZ TOC_FILE5 if NAMESZ != 0x0A && NAMESZ < 0xFF string BASE_PATH | "../../../" math BASE_PATH_INCLUDED = 0 endif endfunction startfunction CHECK_UNICODE if NAMESZ >= 0 getdstring RESULT NAMESZ TOC_FILE5 else math NAMESZ n NAMESZ math NAMESZ * 2 getdstring RESULT NAMESZ TOC_FILE5 set RESULT unicode RESULT endif endfunction startfunction GET_NAME_AND_OFFSET if NAME_FROM_ARRAY = 1 if CURR_NAME < DIR_FILES getarray NAME 5 CURR_NAME getarray OFFSET 6 CURR_NAME goto OFFSET math CURR_NAME + 1 if CURR_NAME = DIR_FILES math NAME_FROM_ARRAY = 0 endif endif else if DIR_FLAG = 1 get DIR_COUNT long TOC_FILE5 math DIR_FLAG = 0 endif if DIR_COUNT = 0 math DIR_FLAG = 1 callfunction GET_NAME_AND_OFFSET 1 else math DIR_COUNT - 1 get NAMESZ signed_long TOC_FILE5 callfunction CHECK_UNICODE 1 string DIR_NAME = RESULT get DIR_FILES long TOC_FILE5 if DIR_FILES = 0 callfunction GET_NAME_AND_OFFSET 1 else for y = 0 < DIR_FILES get NAMESZ signed_long TOC_FILE5 callfunction CHECK_UNICODE 1 string NAME = RESULT string NAME p "%s%s" DIR_NAME NAME if BASE_PATH_INCLUDED == 0 string NAME p "%s%s" BASE_PATH NAME endif putarray 5 y NAME get OFFSET long TOC_FILE5 savepos TMP_INDEX_OFF TOC_FILE5 if OFFSET != 0x80000000 && OFFSET != 0x7FFFFFFF xmath INDEX_OFF "BASE_INDEX_OFF + OFFSET" goto INDEX_OFF TOC_FILE5 get FLAGS long TOC_FILE5 xmath HAS_SIZE "FLAGS & 0x3F" xmath IS_64 "FLAGS >> 28" if HAS_SIZE = 0x3F get CHUNK_SIZE long TOC_FILE5 endif if IS_64 = 0xE get OFFSET long TOC_FILE5 else get OFFSET longlong TOC_FILE5 endif else putarray 7 SKIP_COUNT NAME math SKIP_COUNT + 1 string NAME = "" putarray 5 y NAME endif putarray 6 y OFFSET goto TMP_INDEX_OFF TOC_FILE5 next y math NAME_FROM_ARRAY = 1 math CURR_NAME = 0 callfunction GET_NAME_AND_OFFSET 1 endif endif endif endfunction startfunction COMPRESSION_TYPE if COMP1 = "" comtype zlib endif if ZIP = 1 && COMP1 = "zlib" comtype zlib elif ZIP = 1 && COMP1 = "zstd" comtype zstd elif ZIP = 1 && COMP1 = "oodle" comtype oodle elif ZIP = 1 && COMP1 = "lz4" comtype lz4 elif ZIP = 1 && COMP1 = "gzip" comtype gzip elif ZIP = 2 && COMP2 = "zlib" comtype zlib elif ZIP = 2 && COMP2 = "zstd" comtype zstd elif ZIP = 2 && COMP2 = "oodle" comtype oodle elif ZIP = 2 && COMP2 = "lz4" comtype lz4 elif ZIP = 2 && COMP2 = "gzip" comtype gzip elif ZIP = 3 || ZIP = 4 || ZIP = 0x10 # 3 - Faith of Danschant, 4 - Days Gone, 10 - Ashen comtype oodle if WORKAROUND == 2 comtype lz4 endif endif endfunction startfunction QUICKBMS_4GB_CHECK math TMP64 = 0x10000000 math TMP64 * 16 if TMP64 == 0 print "You must use quickbms_4gb_files.exe with this script!" cleanexit endif endfunction pak.py
    1 point
  27. When i get home, i will compile the decompressor/compressor unpack and pck tool, is one all tool. std::vector<uint8_t> compressLZSSBlock(const std::vector<uint8_t>& input) { const int MIN_MATCH = 3; // comprimento mínimo para virar par const int MAX_MATCH = 17; // (0xF + 2) const int DICT_SIZE = 4096; const size_t n = input.size(); // Dicionário igual ao do descompressor std::vector<uint8_t> dict_buf(DICT_SIZE, 0); size_t dict_index = 1; // mesmo índice inicial do descompressor size_t producedBytes = 0; // quantos bytes já foram "gerados" (saída lógica) std::vector<uint32_t> flagWords; uint32_t curFlag = 0; int bitsUsed = 0; auto pushFlagBit = [&](bool isLiteral) { if (bitsUsed == 32) { flagWords.push_back(curFlag); curFlag = 0; bitsUsed = 0; } if (isLiteral) { // bit 1 = literal (mesmo significado do descompressor) curFlag |= (1u << (31 - bitsUsed)); } ++bitsUsed; }; std::vector<uint8_t> literals; std::vector<uint8_t> pairs; literals.reserve(n); pairs.reserve(n / 2 + 16); size_t pos = 0; while (pos < n) { size_t bestLen = 0; uint16_t bestOffset = 0; if (producedBytes > 0) { // tamanho máximo possível para este match (não pode passar do fim do input) const size_t maxMatchGlobal = std::min(static_cast<size_t>(MAX_MATCH), n - pos); // percorre todos os offsets possíveis do dicionário for (int off = 1; off < DICT_SIZE; ++off) { if (dict_buf[off] != input[pos]) continue; // --- SIMULAÇÃO DINÂMICA DO DESCOMPRESSOR PARA ESTE OFFSET --- uint8_t candidateBytes[MAX_MATCH]; size_t candidateLen = 0; for (size_t l = 0; l < maxMatchGlobal; ++l) { const int src_index = (off + static_cast<int>(l)) & 0x0FFF; // valor em src_index, levando em conta que o próprio bloco // pode sobrescrever posições do dicionário (overlap) uint8_t b = dict_buf[src_index]; // Se src_index for igual a algum índice de escrita deste MESMO par // (dict_index + j), usamos o byte já "gerado" candidateBytes[j] for (size_t j = 0; j < l; ++j) { const int dest_index = (static_cast<int>(dict_index) + static_cast<int>(j)) & 0x0FFF; if (dest_index == src_index) { b = candidateBytes[j]; break; } } if (b != input[pos + l]) { // não bate com o input, para por aqui break; } candidateBytes[l] = b; ++candidateLen; } if (candidateLen >= static_cast<size_t>(MIN_MATCH) && candidateLen > bestLen) { bestLen = candidateLen; bestOffset = static_cast<uint16_t>(off); if (bestLen == static_cast<size_t>(MAX_MATCH)) break; // não tem como melhorar } } } if (bestLen >= static_cast<size_t>(MIN_MATCH)) { // --- CODIFICA COMO PAR (offset, length) --- pushFlagBit(false); // 0 = par uint16_t lengthField = static_cast<uint16_t>(bestLen - 2); // 1..15 uint16_t pairVal = static_cast<uint16_t>((bestOffset << 4) | (lengthField & 0x0F)); pairs.push_back(static_cast<uint8_t>(pairVal & 0xFF)); pairs.push_back(static_cast<uint8_t>((pairVal >> 8) & 0xFF)); // Atualiza o dicionário exatamente como o DESCOMPRESSOR: // for (i = 0; i < length; ++i) { // b = dict[(offset + i) & 0xFFF]; // out.push_back(b); // dict[dict_index] = b; // dict_index = (dict_index + 1) & 0xFFF; // } for (size_t i = 0; i < bestLen; ++i) { int src_index = (bestOffset + static_cast<uint16_t>(i)) & 0x0FFF; uint8_t b = dict_buf[src_index]; dict_buf[dict_index] = b; dict_index = (dict_index + 1) & 0x0FFF; } pos += bestLen; producedBytes += bestLen; } else { // --- LITERAL SIMPLES --- pushFlagBit(true); // 1 = literal uint8_t literal = input[pos]; literals.push_back(literal); dict_buf[dict_index] = literal; dict_index = (dict_index + 1) & 0x0FFF; ++pos; ++producedBytes; } } // Par terminador (offset == 0) pushFlagBit(false); pairs.push_back(0); pairs.push_back(0); // Flush do último flagWord if (bitsUsed > 0) { flagWords.push_back(curFlag); } // Monta o bloco final: [u32 off_literals][u32 off_pairs][flags...][literais...][pares...] const size_t off_literals = 8 + flagWords.size() * 4; const size_t off_pairs = off_literals + literals.size(); const size_t totalSize = off_pairs + pairs.size(); std::vector<uint8_t> block(totalSize); auto write_u32_le = [&](size_t pos, uint32_t v) { block[pos + 0] = static_cast<uint8_t>(v & 0xFF); block[pos + 1] = static_cast<uint8_t>((v >> 8) & 0xFF); block[pos + 2] = static_cast<uint8_t>((v >> 16) & 0xFF); block[pos + 3] = static_cast<uint8_t>((v >> 24) & 0xFF); }; write_u32_le(0, static_cast<uint32_t>(off_literals)); write_u32_le(4, static_cast<uint32_t>(off_pairs)); size_t p = 8; for (uint32_t w : flagWords) { block[p + 0] = static_cast<uint8_t>(w & 0xFF); block[p + 1] = static_cast<uint8_t>((w >> 8) & 0xFF); block[p + 2] = static_cast<uint8_t>((w >> 16) & 0xFF); block[p + 3] = static_cast<uint8_t>((w >> 24) & 0xFF); p += 4; } std::copy(literals.begin(), literals.end(), block.begin() + off_literals); std::copy(pairs.begin(), pairs.end(), block.begin() + off_pairs); return block; } @morrigan my compressor, try it, and let me know the results.
    1 point
  28. Hello, I have managed to get the game files and uploaded to AssetStudio to view them, and I found Texture2Ds and Sprites but some of the assets are missing. For an example, there are literally no audio/voice files at all. Then, I noticed AssetStudio doesnt recognize the assets inside a folder called "ondemand" and there are about 2k assets there and I think they are encrypted/compressed. Here is one of the examples of the encrypted assets: Is there a way to decrypt/decompress this type of file? I think those are the remaining assets. If anyone can help me I would really apprecaite it. 5db8fd68-da55-9c4a-c71f-84af76d61103.7z
    1 point
  29. Yea, I'm working on BHD but mostly focused on the JO/DFX2 engine which is slightly newer and a different format. I'll post here when/if I get BHD usable.
    1 point
  30. I have a basic exporter for 3ds max here https://github.com/taylorfinnell/onbadexporter
    1 point
  31. Just found these forums, that's my github in the OP. Happy to help. This may help you too https://github.com/taylorfinnell/on3diimporter/blob/main/on3diimporter.py
    1 point
  32. You can either use this QuickBMS script to extract the msv audio files out of the rp2: get UNK long get FILES long goto 0x20 for i = 0 < FILES getdstring NAME 7 getdstring DUMMY 25 get OFFSET long get SIZE long get DUMMY2 long string NAME + ".msv" log NAME OFFSET SIZE next i Or you can use this txth file to play the audios out of the rp2 directly (needs vgmstream + an audio player like foobar2000): subsong_count = @0x04 subsong_spacing = 0x2c base_offset = 0x20 name_offset = 0x00 subfile_offset = @0x20 subfile_size = @0x24 subfile_extension = msv Save the text above as ".rp2.txth" and put it on the same directory as the rp2 file. Also if you're using foobar2000, make sure to check "Enable unknown exts" on the vgmstream preferences page.
    1 point
  33. Yes! I´ve to create a tool to merge and split image, so i can merge them, edit and later split to insert.
    1 point
  34. No, mané game extractor! attached my .exe try it you can drop the file into the .exe as well the tool looks like StarWars3PakExtractor.zip
    1 point
  35. Hi Reh! (Reh from former Xentax?) PS2 models are known for using auto created faces. Doesn't work here, so maybe a split up of this mesh is required? edit: tried steps of 120 vertices but even this obvious head gives a bad result when using fake faces.
    1 point
  36. Well, I did a little research on Flash Cookies (SOL files) and I put it all together in the article on RE Wiki https://rewiki.miraheze.org/wiki/Flash_Cookie_SOL I saw notes on your github and you were sligthly wrong with some fields, so you can compare it with my article on the wiki and make some corrections in your tool. The most important thing is that you should understand that SOL file is an Adobe format and payload (data block) follows AMF file format documented by Adobe https://web.archive.org/web/20220122035930/https://www.adobe.com/content/dam/acom/en/devnet/pdf/amf-file-format-spec.pdf So anything after data block header is a payload section that needs to be properly serialized by your tool. There are many tools that allow you proper serialization like: minerva, SOL Editor, Adobe AIR SDK, JPEXS Free Flash Decompiler etc. Some code for serializing is available on JPEXS github page: https://github.com/jindrapetrik/jpexs-decompiler/tree/master/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/sol https://github.com/jindrapetrik/jpexs-decompiler/tree/master/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/amf/amf3 You can test this code by going to Tools > Sol cookie editor in JPEXS Free Flash Decompiler: So you shouldn't ask "what are those three bytes". You should ask "how can I properly parse AMF3 serialized data" 🙂 There are lots of information (articles) about this, for example on wikipedia: https://en.wikipedia.org/wiki/Local_shared_object https://en.wikipedia.org/wiki/Action_Message_Format Good luck. 🙂
    1 point
  37. Okay, thanks for the lead. I successfully uncompressed the PUD file, and it is indeed a container. The value 0x2 represents the number of files within it. The uncomressed images are raw pixel data and need to be combined with the PAL file to get the correct image. can use imageheat to view the correct image.
    1 point
  38. I used the files from the zip, iirc. But seems, you're too late to the party...
    1 point
  39. This .pud files is another container that contains custom lzss blocks files, for example Title.pud contains 2 images with custom lzss compressed, if you decompress it you will see..
    1 point
  40. Edit - just tested it and no 4 mrts is uv, you was right in saying the 4th one is the uv maps by the rule
    1 point
  41. I've just released a new version of ImageHeat 🙂 https://github.com/bartlomiejduda/ImageHeat/releases/tag/v0.31.2 Changelog: - Added new pixel formats: APLHA4, ALPHA4_16X, ALPHA8, ALPHA8_16X, RGBA6666, RGBX6666, BGRT5551, BGRT8888, PAL8_TZAR, BGRA5551, BGRA5551_TZAR, BGRA8888_TZAR, BGRA4444_LEAPSTER - Added support for LZ4, Emergency RLE, Neversoft RLE, Tzar RLE, Leapster RLE, Reversed TGA RLE - Fixed issue with x360 swizzling - Fixed issue with PS Vita/Morton swizzling for 4-bpp images - Added support for palette values scaling (1x, 2x, 4x, 8x, 16x) - Added dropbox for palette scaling in "Palette Parameters" box - Added funding info
    1 point
  42. Because the fmlb and sound file does exits anymore because when before Game shutdown that files are dynamic content but some files like that are available in beta versión APK and obb but no all files
    1 point
  43. Did you ever figure out the animations format? I'd love to get access to the animations for some stuff but of course, the MOT files are formatted differently 😔
    1 point
  44. Mostly, PNG files are decompressed, so it's fairly easy to edit and reimport them. However, you need to compress your PNG files using the site iLoveIMG. For example, if the original PNG is 10 KB, your PNG must be 10 KB or less, so you will need to compress it on the site. I’ve attached 3 files: Two BMS scripts: One script will unpack the data, decompressing all files. The other script will unpack the file without decompressing it (this is the one you should use for reimporting; reimport with -r, not reimport 2 in quick bms). A Python script (.py): This program decompresses and compresses zlib files individually. I have set a compression level to reduce the file size even further. Use this if you need to handle compressed files. zlib_DeCompressor.py BMS.ZIP
    1 point
  45. Has anyone managed to extract the trading card images? I tried using the script for the 3D models. but it just doesn't work.
    1 point
×
×
  • Create New...