1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Black Desert Online Modding Tools

Discussion in 'Tools & Guides' started by BlackFireBR, Jul 7, 2016.

  1. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    PAZ Files Browser
    With this tool, you can preview 3D files from the game without having to open or extract the whole game.
    This way you can easily find the corresponding file name for an armor that you want to mod, using my other tools.
    browser_preview1.jpg
    The tool uses quickbms to extract the files and 3D Object Coverter to open them.
    Source code here: src-paz_browser_v1.0.zip

    Download: Black Desert Online - Paz Files Browser

    Instructions:
    - Extract ALL files to your "PAZ" folder
    - Run "paz_browser.exe"
    - Use the arrow keys and the ENTER key to navigate thought the menu

    paz_browser_preview_resized.gif

    Important: To visualize the model with textures, click on this icon:
    texture-on-icon.jpg
    Known issues:
    - Not all files can be opened by this program, sometimes you will encounter this message:
    error.jpg
    Unfortunately there's no fix for that.​

    - Some armors are missing and they will always be missing due to some files of the game that can't be read by my tool, but it should be less than 2% of the files.

    Observations:
    - Every file your preview is extracted, both .pac file and texture files under "Black Desert Online\Paz\patcher_resources\extracted_files\".

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    MIR-HEADER.png
    This tool allows Black Desert Online to use custom files instead of the original game files. It can be used to make the game recognize files such as custom textures, custom armors, nude mods, translations, etc.

    In other words:
    It makes the game look for the files in the Black Desert root folder instead of looking inside the compressed PADxxxxx.PAZ files, so you can use modified files.
    ezgif-2254507097.gif
    Download Link: Meta Injector Reloaded v1.6

    Source Code : src.zip
    Old versions:
    list
    Instructions:
    1 - Extract the zip file to your PAZ folder.
    2 - Put all your modified files in the "files_to_patch" folder.
    3 - Run "Meta Injector Reloaded.exe"
    4 - Follow the screen instructions.

    Do this every time a game update is released:
    - Restore you last backup using the tool, before you update the game, otherwise you will get a "corrupted files" message from the launcher and you'll have to re-check the whole game.

    Uninstall:
    Run Meta Injector Reloaded.exe and select the "Restore backup" option.
    The latest ones are the most up to date.
    ---------------------------------------------------------------------------------------------------------------------------------
    Hashes Generator for Meta Injector
    Sometimes the tool won't find the new armor just released for the game, to fix that, you need to generate the file "hashes.txt" again.

    Download the Hashes Generator for Meta Injector, and follow the instructions inside the .zip.
    ---------------------------------------------------------------------------------------------------------------------------------
    Files "Not Found"
    There are around 2% of game files (8000 files) that can't be patched with this tool.
    If you get this message in the end of the program:
    fail.jpg
    If it's a new armor you are trying to patch, try using the Hashes Generator. Otherwise unfortunately there is nothing it can be done for those files and they will not be recognized by the game.
    ---------------------------------------------------------------------------------------------------------------------------------
    All files must have their original name.
    This means that if you use Resorep texture names like: 472539502.dds won't work.You need to use the original name of the texture like : pbw_00_ub_0001.dds.To do that, use this tool created by Ray Wing:
    ---------------------------------------------------------------------------------------------------------------------------------
    Note1: If you are going to manually move the files, make sure the files are inside their original folders
    For example: pew_00_ub_0034.dds file should be under​
    so when you move or copy, it should go to this path:
    (This doesn't matter if you chose options 1 or 2 of the program though, the program does that for you)
    ----------------------------------------------------------------------------------------------------------------------------------
    Black Desert Online File Extractor
    fileextractor-gif.gif
    A tool that uses quickbms to extract all files from your game

    Download Link:

    Source Code: https://www.undertow.club/attachments/src-file-extractor-v1-1-zip.56139/

    Instructions:
    1 - Extract this zip file to your PAZ folder.
    2 - Run "File Extractor.exe"
    3 - Use the options on the screen to do what you want.

    Interesting facts about the program:
    1 - Extract all game files:
    You can chose 2 options:
    Slow - Extracts 100 percent of the files, it goes in each .PAZ file one by one and extracts all files. It takes a lot of time.
    Fast - Extracts 98 percent of the file. Uses a fixed version of the blackdesert.bms script to use the pad00000.meta file to extract all the files that this files tells you the game has, which unfortunately skips around 8000 files (2%) because they are not present in this file, but it's way faster than the first method.

    5 - Extract by extension:
    - Searches each PAZ files for the extension you type.
    Example:
    Extension: .ai
    Will go in each .PAZ file and extract the files only if they have the .ai extension.

    6 - Extract a specific file
    - It uses the file pazNamesRelations.txt which has the following structure:
    FILE_NAME|PAZ_NAME

    Example:
    pew_00_ub_0001.pac|PAD00057.PAZ

    The program looks for the file name you type in this file, if it finds, it opens the .PAZ file and extracts only that file for you.
    If the file is not present in the pazNamesRelations.txt, the program will now open each .PAZ file of your game and search for the file name your typed, starting from the last .PAZ to the fist one (if the file wasn't in the .txt file it most likely was added after the .txt file was generated and it probably is located in the latest .PAZ files)
     

    Attached Files:

    Last edited: Nov 2, 2016
    aliraja, comsci, Nharea and 4 others like this.
  2. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Modders Stuff:
    This section is reserved to gather all the information I was able to discover so far about the files my tools uses from the game, as well some useful small programs that I made.

    This is how the pad00000.meta file file is structured:
    meta5.jpg

    This is how a .PAZ file is structured:
    PAZ_FILE.jpg

    - Light-red colored means encrypted.

    This is a very simplified version of the pad00000.meta file:
    [​IMG]


    This is a small version of a meta file, with only 3 .PAZ files, 3 folders and 4 files. This is the basic structure of the meta file. The official meta file follows the same pattern, it just has more files in it ( a lot more).

    Before we proceed, this is a few things we need to clarify:
    - Each BIG Block represents 4 bytes.
    - Each small block represents one byte.
    - Red blocks with white background means this is encrypted and they will not appear like this, unless you decrypt those bytes.
    - DUMMY is a number that I don't know what's for.
    - ZSIZE is compressed size and SIZE is the uncompressed size.

    This is the same file as the first image, but with all the numbers converted from hex to dec:
    [​IMG]

    Now let's understand how the game knows which file to load:

    Let's pick the first FILE_HASH: 631490897:

    - We can see it belongs to a file, which folder num is 2
    - When we search for folder num = 2 in the "folders_part" of the file, we find that the name of the folder is "character/" ,so the file is in the "character" folder".
    - next, we know the file number is 0, so the game will look in the "file names part" and when it finds the first '\0', if will know that it's the end of the file name we are looking for. (If file num was == 2, we would have to count 2 '\0', and everything that is between the 2nd and the 3rd '\0' is the file name)

    So we discovered that the file with the hash 631490897 is "multiplemodeldesc.xml" and it's located in "character/"

    One thing you should be aware of, when converting from hex to dec.
    For example, the FILE_HASH we just used: 631490897
    When you convert it to hex, you get this:
    [​IMG]

    But when you look at the meta file, you are not going to find 25 A3 C9 51, instead you need to find 51 C9 A3 25
    [​IMG]


    So everytime you convert to hex, remember to change the order in blocks of 2 bytes.

    Warning, don't do this mistake:
    25 A3 C9 51 -> 15 9C 3A 52
    it's:
    25 A3 C9 51 - > 51 C9 A3 25

    New version of the blackdesert.bms file that prints FILE_HASH | FOLDER_NUM | FOLE_NUM | FOLDER_NAME | FILE_NAME reading all from the .meta file:
    quick_bms_script_print.zip

    The only difference is that I manually added the offsets so quickbms would skip those 256,000 bytes.
    Code:
        math OFFSET = 305932  # Pos after the 256,000 bytes (Where the file blocks starts)
        math TMP = 9231156    # Pos after the file blocks ends
        goto TMP
    
    I discovered that number (305932) by doing this:
    - Searching for the hash: 631490897 (from multiplemodeldesc.xml)
    - Go back 28 bytes (7 * 4) (nFields(hash,folderNum,fileNum,pazNum,offset,zsize,size) * sizeof(int))
    - Read hash,folderNum,fileNum,pazNum,offset,zsize,size
    - If pazNum >= 1 or <= 4160
    - Go back 28 bytes
    - repeat.

    Here's the code that does that:
    metaexplorer.c

    So my goal was to find which byte starts the first hash from the "file blocks" section.
    Here is the full list of the file blocks, in the order they appear in the pad000.meta file.
    script-meta-output.txt
    The order is: HASH|FOLDER_NUM|FILE_NUM|PAZ_NUM|FOLDER_NAME|FILE_NAME

    I also made a program that sorts this file by fileNum, and outputs the numbers of the files that are missing and how many of them are missing:
    filesort.zip
    Also, the sorted file is this:
    sorted_file.zip


    Quickbms Fixed Script
    This is a modified version of the original script found at http://aluigi.altervista.org/bms/blackdesert.bms

    In version 0.2.2 you get this error, when you try to extract game's files using pad00000.meta
    Code:
    Error: incomplete input file 0: C:\Program Files (x86)\Black Desert Online\Paz\PAD00000.meta
           Can't read 525213419 bytes from offset 00ffa5c8.
           Anyway don't worry, it's possible that the BMS script has been written
           to exit in this way if it's reached the end of the archive so check it
           or contact its author or verify that all the files have been extracted.
           Please check the following coverage information to know if it's ok.
    
      coverage file 0    45%   7539936    16754120
    
    Last script line before the error or that produced the error:
      50  log MEMORY_FILE2 TMP NAMES_SIZE
    This is a version created by me that works with the updated game and it's all commented

    It tells you what each line does, give you an example in C language of how to do the same thing for a more intuitive understanding, also it prints a lot of useful information while its running like variables values, which file is extracting, what is the hash of that file, the size, how many files were extracted already and the percentage of completeness, etc.

    Code:
    #  This is a modified version of the original script found at
    #  http://aluigi.altervista.org/bms/blackdesert.bms
    #  That makes the script jumps over the 256000 bytes they added in the meta file, after a patch.
    # For a visual guide on how the .meta and .PAZ file is sctructured, see this thread:
    # https://www.undertow.club/posts/129095
    
    quickbmsver "0.7.4"
    comtype blackdesert # Defines the compression type that will be used, when extracting a file
    
    get EXT extension  # gets the extension of the opened file
    
    
    if EXT == "meta" #If the file extension is .meta
    
        # pre-allocation, improves speed (doesn't matter if the values are bigger)
        putarray 0 0x4000  ""   # Array that is going to store the PAZs names
        putarray 1 0x2000  ""   # Array that is going to store the folder names
        putarray 2 0x80000 ""   # Array that is going to store the file names
    
        get DUMMY long        # Reads the first 4 bytes (long) of the meta file and stores it in the variable DUMMY. # In C: fread(&dummy,sizeof(long),1,metaFile);
        get pPAZCount long  # Reads how many PAZ files your game has. # In C: fread(&pPAZCount,sizeof(long),1,metaFile);
        print "pPAZCount: %pPAZCount%"
    
        # Paz files informations
        for i = 0 < pPAZCount
            get PAZ_NUM long
            get HASH long
            get PAZ_SIZE long
    
            string PAZ_NAME p= "PAD%05d.PAZ" PAZ_NUM # Using the number stored in PAZ_NUM with 5 digits,creates a string that will hold the complete .PAZ file name (E.g.:PAD00001.PAZ) # In C: sprintf(paz_name,"PAD%.5d.PAZ",paz_num);
            putarray 0 PAZ_NUM PAZ_NAME                # Stores in the array 0 in the position [PAZ_NUM], the string we just created # In C: array0[paz_num] = paz_name;
        next i
    
        get FILES_COUNT long # Reads how many files your game has. # In C: fread(&files_count,sizeof(long),1,metaFile)
        print "FILES_COUNT: %FILES_COUNT%"
    
        savepos BLOCK_256K_START                             # Saves the current position in the file in a variable. This position is the beginning of a block of 256000 bytes that we need to skip. # In C: long block_256k_start = ftell(metafile);
        print "BLOCK_256K_START: %BLOCK_256K_START%"
    
        xmath BLOCK_256K_END "BLOCK_256K_START + 256000"     # Calculates the byte that the 256000 bytes end # In C: long block_256k_end = block_256k_start + 256000;
        print "BLOCK_256K_END: %BLOCK_256K_END%"
    
        goto BLOCK_256K_END                                    # Skips the 256000 bytes # In C: fseek(metaFile,block_256k_end,SEEK_SET);
    
        savepos FILE_BLOCKS_START        # Saves the current position in the file in a variable. This position is the beginning of the blocks that have the following format: HASH|FOLDER_NUM|FILE_NUM|PAZ_NUM|OFFSET|ZSIZE|SIZE # # In C: long file_blocks_start = ftell(metafile);
        print "FILE_BLOCKS_START: %FILE_BLOCKS_START%"
    
        math FILE_BLOCKS_COUNT = 0        # Counter of how many of those blocks we have # In C: long file_blocks_count = 0;
    
        # Reads the file blocks, just to count how many of them there are, and where do they end, until the PAZ_NUM variable reads something that is out of the interval 1 <= PAZ_NUM <= pPAZCount
        Do
            get HASH long         # The unique indentifier of this file
            get FOLDER_NUM long    # The index in the array 1 (folders array) which has the folder name from this file
            get FILE_NUM long    # The index in the array 2 (files array) which has the file name from this file
            get PAZ_NUM long     # The number of the .PAZ file that the file is located
            get OFFSET long     # The offset inside the .PAZ file specified which the file starts
            get ZSIZE long        # The compressed size of the file
            get SIZE long        # The uncompressed size of the file
    
            if PAZ_NUM <= pPAZCount & PAZ_NUM >= 1
                math FILE_BLOCKS_COUNT += 1         # Counts how many file blocks we have
            endif
    
        While PAZ_NUM <= pPAZCount & PAZ_NUM >= 1 # Condiditon that checks if the PAZ_NUM variable reads something that is out of the interval 1 <= PAZ_NUM <= pPAZCount
    
        savepos CURRENT_POS    # This position should be 28 bytes after the end of the fileblocks, because it read a whole file block before the while checked if it was valid
    
        xmath FILE_BLOCKS_END "CURRENT_POS - (7 * 4)" # Calculates the position which is where the file blocks ended (each file block has 28 bytes (7 * sizeof(long)) # In C: long file_blocks_end = (current pos - 7 * sizeof(long));
        print "FILE_BLOCKS_END: %FILE_BLOCKS_END%"
    
        goto FILE_BLOCKS_END
    
        get FOLDER_NAMES_TOTAL_LENGTH long    # Gets the total length of the strings that are comming next, that are the folder names strings # In C: fread(&folder_names_total_length,sizeof(long),1,metaFile);
        print "FOLDER_NAMES_TOTAL_LENGTH: %FOLDER_NAMES_TOTAL_LENGTH%"
    
        savepos FOLDER_NAMES_START            # Saves the position where the folder names strings start # In C: long folder_names_start = ftell(fp);
        print "FOLDER_NAMES_START: %FOLDER_NAMES_START%"
    
        callfunction SET_ENCRYPTION 1                                    # Decrypts the folder names that are going to be read next
        log MEMORY_FILE FOLDER_NAMES_START FOLDER_NAMES_TOTAL_LENGTH     # Saves all the next "FOLDER_NAMES_TOTAL_LENGTH" bytes, starting from the offset "FOLDER_NAMES_START" in a temporary memory called MEMORY_FILE # In C: fread(memory_file,1,folder_names_total_length,metaFile);
        encryption "" ""                                                # Tells the program to stop decrypting stuff for now
    
        xmath FOLDER_NAMES_END "FOLDER_NAMES_START + FOLDER_NAMES_TOTAL_LENGTH"     # Calculates which byte the folder names strings end # In C: long folder_names_end = folder_names_start + folders_name_total_length;
        print "FOLDER_NAMES_END: %FOLDER_NAMES_END%"
    
        goto FOLDER_NAMES_END                                                         # Goes to that position # In C: fseek(metaFile,folder_names_end,SEEK_SET);
    
        get FILE_NAMES_TOTAL_LENGTH long # Gets the total length of the strings that are comming next, that are the file names strings # In C: fread(&file_names_total_length,sizeof(long),1,metaFile);
        print "FILE_NAMES_TOTAL_LENGTH: %FILE_NAMES_TOTAL_LENGTH%"
    
        savepos FILE_NAMES_START        # Saves the position where the file names strings start # In C: long file_names_start = ftell(fp);
        print "FILE_NAMES_START: %FILE_NAMES_START%"
    
        callfunction SET_ENCRYPTION 1                                # Decrypts the folder names that are going to be read next
        log MEMORY_FILE2 FILE_NAMES_START FILE_NAMES_TOTAL_LENGTH    # Saves all the next "FILE_NAMES_TOTAL_LENGTH" bytes, starting from the offset "FILE_NAMES_START" in a temporary memory called MEMORY_FILE2 # In C: fread(memory_file2,1,file_names_total_length,metaFile);
        encryption "" ""                                            # Tells the program to stop decrypting stuff for now
    
        math FOLDER_NAMES_TOTAL_LENGTH -= 8  # Don't know why, but it ignores the last 8 bytes of the folder names string (2 irrelevent longs, maybe?)
    
        # Reads the string which has all the folder names, assigning each folder name to a different position in the array 1 (folders array)
        print "Collecting folder names..."
        math i = 0
        for TMP = 0 < FOLDER_NAMES_TOTAL_LENGTH
            get INDEX_NUM long MEMORY_FILE      # Reads from the MEMORY_FILE the the index number of the current folder
            get SUB_FOLDERS long MEMORY_FILE    # Reads from the MEMORY_FILE the number of subfolder of the current folder
            get FOLDER_NAME string MEMORY_FILE    # Reads from the MEMORY_FILE a folder name, as string, until a '\0' is found. E.g: "character/"
    
            if FOLDER_NAME == "" # If no name was read, means that we reached the end of the folder names
                break
            endif
    
            putarray 1 i FOLDER_NAME    # Stores the folder name, in the position i of the array 1 (folders array) # In C: array1[i] = folder_name;
    
            savepos TMP MEMORY_FILE
        next i
    
        print "Collecting file names..."
        math i = 0
        # Reads the string which has all the file names, assigning each file name to a different position in the array 2 (files array)
        for TMP = 0 < FILE_NAMES_TOTAL_LENGTH
    
            get FILE_NAME string MEMORY_FILE2         # Reads from the MEMORY_FILE a file name, as string, until a '\0' is found.
    
            if FILE_NAME == ""    # If no name was read, means that we reached the end of the file names
                break
            endif
    
            putarray 2 i FILE_NAME    # Stores the folder name, in the position i of the array 1 (folders array) # In C: array1[i] = file_name;
            savepos TMP MEMORY_FILE2
        next i
    
    
    
        # Now we are going to extract the files, combining the information we find in the file blocks, with the arrays filled with the file and folder names
        goto FILE_BLOCKS_START            # Goes back to the beginning of the file blocks
        for i = 0 < FILE_BLOCKS_COUNT    # For all file blocks
            get HASH long         # The unique indentifier of this file
            get FOLDER_NUM long    # The index in the array 1 (folders array) which has the folder name from this file
            get FILE_NUM long    # The index in the array 2 (files array) which has the file name from this file
            get PAZ_NUM long     # The number of the .PAZ file that the file is located
            get OFFSET long     # The offset inside the .PAZ file specified which the file starts
            get ZSIZE long        # The compressed size of the file
            get SIZE long        # The uncompressed size of the file
    
            getarray PAZ_NAME 0 PAZ_NUM            # Gets the PAZ name at the position [PAZ_NUM] of the array 0 (PAZ names array) and stores is in the PAZ_NAME variable             # In C: paz_name     = array0[paz_num];
            getarray FOLDER_NAME 1 FOLDER_NUM    # Gets the folder name at the position [FOLDER_NUM] of the array 1 (folders array) and stores is in the FOLDER_NAME variable     # In C: folder_name = array1[paz_num];
            getarray FILE_NAME 2 FILE_NUM        # Gets the file name at the position [FILE_NUM] of the array 1 (folders array) and stores is in the FILE_NAME variable             # In C: file_name     = array2[paz_num];
            string FILE_PATH = FOLDER_NAME
            string FILE_PATH += FILE_NAME # Creates a string and concatenates folder name with the file name strings, so we get the full path to the file. Eg: "character/multiplemodeldesc.xml"
    
            open FDSE PAZ_NAME 1    # Open the .PAZ file specified in the PAZ_NAME variable
    
            print "\n[FOLDER NAME]: %FOLDER_NAME%\n[ FILE_NAME ]: %FILE_NAME%\n  HASH   |FOLDER_NUM|FILE_NUM|PAZ_NUM| OFFSET|ZSIZE|SIZE\n%HASH%|   %FOLDER_NUM%   | %FILE_NUM% |  %PAZ_NUM% |%OFFSET%|%ZSIZE%|%SIZE%"
    
            callfunction SET_ENCRYPTION 1
            # If uncompressed size is greater than compressed size, it means that the file is compressed, so we use "clog" which uncompresses and extracts the file
            if SIZE > ZSIZE
    
            # Uncompress and extracts the file and saves it just like is specified in "FILE_PATH", OFFSET is what byte of the .PAZ file the file starts, ZSIZE is the compressed size and SIZE is the uncompressed size, this uses the compression algothithm defined with the "comtype" command
                clog FILE_PATH OFFSET ZSIZE SIZE 1
    
            else  # If uncompressed size is lesser or equal than compressed size, it means that the file is NOT compressed, so we use "log" which just extracts the file
    
            # Simply extracts the file and saves it just like is specified in "FILE_PATH", OFFSET is what byte of the .PAZ file the file start and SIZE is the file size
                log FILE_PATH OFFSET SIZE 1
            endif
            encryption "" ""
    
            print ""
            xmath PERCENTAGE "i*100/FILE_BLOCKS_COUNT"
            print "Files Extracted: %i%/%FILE_BLOCKS_COUNT% (%PERCENTAGE% Percent Completed)"
        next i
    
    
    else if EXT == "PAZ"  #If the file extension is .PAZ
    
        get DUMMY long            # Reads the first 4 bytes (long) of the meta file and stores it in the variable DUMMY. # In C: fread(&dummy,sizeof(long),1,metaFile);
        get TOTAL_FILES long    # Reads how many files this .PAZ file has. # In C: fread(&paz_files,sizeof(long),1,metaFile);
        get FILE_PATHS_TOTAL_LENGTH long     # Gets the total length of the strings that are the folder names and file names like this "character/multiplemodeldesc.xml"
    
        savepos FILE_BLOCKS_START    # Saves the current file's position, which is where the file blocks start # In C: long file_paths_start = ftell(file);
        xmath FILE_BLOCKS_END "FILE_BLOCKS_START + (TOTAL_FILES * 4 * 6)"    # Calculates the position where the file blocks end and it's where the file paths start
        callfunction SET_ENCRYPTION 1                                        # Decrypts the what is going to be read next
        log MEMORY_FILE FILE_BLOCKS_END FILE_PATHS_TOTAL_LENGTH                # Starting for the offset where the file blocks end, it reads the next "FILE_PATHS_TOTAL_LENGTH" bytes and stores them in the MEMORY_FILE file # In C: fread(MEMORY_FILE,1,FILE_PATHS_TOTAL_LENGTH,file);
        encryption "" ""                                                    # Tells the program to stop decrypting stuff for now
    
        # Reads the bytes which has all the file paths, assigning each folder name to a different position in the array 0
        math i = 0
        for TMP = 0 < FILE_PATHS_TOTAL_LENGTH
            get FILE_PATH string MEMORY_FILE # Reads from the MEMORY_FILE a file path, as string, until a '\0' is found. E.g: "character/"
    
            if FILE_PATH == "" # If nothing was read, means that we reached the end of the file paths
                break
            endif
    
            putarray 0 i FILE_PATH # Stores the folder name, in the position i of the array 0  # In C: array0[i] = file_path;
            savepos TMP MEMORY_FILE
        next i
    
        for i = 0 < TOTAL_FILES
            get HASH long         # The unique indentifier of this file
            get FOLDER_NUM long    # The index in the array 0  which has the folder name from this file
            get FILE_NUM long    # The index in the array 0  which has the file name from this file
            get OFFSET long     # The offset inside the .PAZ file specified which the file starts
            get ZSIZE long        # The compressed size of the file
            get SIZE long        # The uncompressed size of the file
    
            getarray FOLDER_NAME 0 FOLDER_NUM    # Gets the folder name at the position [FOLDER_NUM] of the array 1 (folders array) and stores is in the FOLDER_NAME variable     # In C: folder_name = array1[paz_num];
            getarray TMP 0 FILE_NUM        # Gets the file name at the position [FILE_NUM] of the array 1 (folders array) and stores is in the FILE_NAME variable             # In C: file_name     = array2[paz_num];
            string FILE_PATH = FOLDER_NAME
            string FILE_PATH += TMP # Creates a string and concatenates folder name with the file name strings, so we get the full path to the file. Eg: "character/multiplemodeldesc.xml"
    
            print "\n[FOLDER NAME]: %FOLDER_NAME%\n[ FILE_NAME ]: %TMP%\n  HASH   |FOLDER_NUM|FILE_NUM| OFFSET|ZSIZE|SIZE\n%HASH%|   %FOLDER_NUM%   | %FILE_NUM% |%OFFSET%|%ZSIZE%|%SIZE%"
    
            callfunction SET_ENCRYPTION 1
            # If uncompressed size is greater than compressed size, it means that the file is compressed, so we use "clog" which uncompresses and extracts the file
            if SIZE > ZSIZE
    
            # Uncompress and extracts the file and saves it just like is specified in "FILE_FULL_PATH", OFFSET is what byte of the .PAZ file the file starts, ZSIZE is the compressed size and SIZE is the uncompressed size, this uses the compression algothithm defined with the "comtype" command
                clog FILE_PATH OFFSET ZSIZE SIZE
    
            else  # If uncompressed size is lesser or equal than compressed size, it means that the file is NOT compressed, so we use "log" which just extracts the file
    
            # Simply extracts the file and saves it just like is specified in "FILE_FULL_PATH", OFFSET is what byte of the .PAZ file the file start and SIZE is the file size
                log FILE_PATH OFFSET SIZE
            endif
            encryption "" ""
    
        next i
    endif
    
    startfunction SET_ENCRYPTION
            encryption ice "\x51\xF3\x0F\x11\x04\x24\x6A\x00"
    endfunction
    
    

    If you need help understanding quickbms scripts, please refer to http://aluigi.altervista.org/papers/quickbms.txt, everything you need is there.

    meta5.jpg
     

    Attached Files:

    Last edited: Oct 13, 2016
  3. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Reserved
     
  4. Hanabikimchi

    Hanabikimchi Potential Patron

    Joined:
    Jan 25, 2013
    Messages:
    8
    Likes Received:
    0
    looks super interesting, I'm looking forward what you can do with that
     
  5. alcaster4242

    alcaster4242 Avid Affiliate

    Joined:
    Mar 12, 2016
    Messages:
    151
    Likes Received:
    34
    Is the png icons working?
    I couldn't get it to work, unless it's a special png file?
     
  6. Kenith

    Kenith Potential Patron

    Joined:
    Mar 7, 2016
    Messages:
    23
    Likes Received:
    16
    Thanx
     
    Last edited: Jul 14, 2016
  7. Kenith

    Kenith Potential Patron

    Joined:
    Mar 7, 2016
    Messages:
    23
    Likes Received:
    16
    I wanna change 'Black garter belt' and find the file of it

    dxt1
    pew_99_ub_0004_02.dds
    pew_99_ub_0004_dec_sp.dds
    dxt5
    pew_99_ub_0004_dec.dds
    pew_99_ub_0004_dec_m.dds
    ( It's used in 'resorep mod')

    but when I run 'meta injector'
    It failed to find 'pew_99_ub_0004_dec.dds' ( maybe main part of 'Bra and Panties' )
     
  8. Jensen

    Jensen Potential Patron

    Joined:
    Jun 4, 2016
    Messages:
    10
    Likes Received:
    0
    hey, this looks really good, but ive been trying to get something but i cant find how, and if its possible
    basically i want Le Vladian underware, i want to remove the underware, just leave the stockings and waist/leg chains

    is this possible ? it used to be before the last patches (EU), then i moved to resorepless and i couldnt do it any more
    any info is appreciated, thanks
     
  9. latuel

    latuel Potential Patron

    Joined:
    Mar 24, 2016
    Messages:
    8
    Likes Received:
    0
    I wanna change Valkyrie's New Clothes texture.
    PVW_00_Ub_076.PAC
    Textures in PAD04089.PAZ(pvw_00_ub_0076.dds, pvw_00_ub_0076_hair.dds)
    How can i do it?
     
  10. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Are you using the original names for those files?
    Does it at least succeed in the "Running Meta Injector" part?
     
  11. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Yeah, I tried to patch that file too, unfortunately it doesn't work.
    I'm trying to see if I can find an alternative for those cases, but I need to study the pad00000.meta file a little more to see if I can do something about it.

    Download this:
    Le Vladian underware textures removed.zip
    - Extract to the "files_to_patch" folder.
    - Run "Meta Injector Reloaded.exe"
    - After done patching, move the folder inside the "files_to_patch" folder to your Black Desert Online root folder.
    Eg:
    If you were in
    "C:\Program Files (x86)\Black Desert Online\PAZ\files_to_patch\"
    you should move the "character" folder to
    "C:\Program Files (x86)\Black Desert Online\"

    Aparently this file doesn't exist in the NA version yet. I just extracted the whole have and I haven't found it.
    You will have to extract it yourself using quickbms and then just follow the instructions from the Meta Injector Reloaded normally.
    Let me know if you need help when extracting the files.
     

    Attached Files:

    Jensen likes this.
  12. Kera

    Kera Vivacious Visitor

    Joined:
    Mar 29, 2016
    Messages:
    27
    Likes Received:
    4
    In the interest of removing a step, would it hurt to just make the final step in your patcher copy the files from files_to_patch into the root folder?

    Maybe make it optional. One of the reasons I do not like moving the files (and would prefer a copy) is that way files_to_patch files just overwrites whatever was in the target directory and keeps it up to date. If you want to tinker, you do it inside of files_to_patch, then just re-run the patcher and it places everything nicely. It also handles deletes - delete from files_to_patch, re-run patcher, and those entries are unpatched so the files can remain where they are without causing issues.
     
  13. Jensen

    Jensen Potential Patron

    Joined:
    Jun 4, 2016
    Messages:
    10
    Likes Received:
    0
    thanks a bunch man, works almost perfectly
    first pic is with transparent resorepless installed, and it works fine
    second pic is the same, but after i press show underware
    2016-07-09_1239850503.jpg
    maybe you know how to fix it ? or maybe i did something wrong
    again, thanks a bunch
     
  14. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Download the Le Vladian underwear textures removed in the post above and follow the instructions I mentioned above.
    This should fix your problem (Assuming you don't want to see the Le Vladian underwear
     
  15. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Black Desert Online Texture Extractor
    [​IMG]
    A tool that uses quickbms to extract only the texture files from your .PAZ files.

    Download Link:

    Source Code: Source Code - Texture Extractor.zip
    Instructions:
    1 - Extract this zip file to your PAZ folder.

    2 - Run "Texture Extractor.exe"

    3 - Press 1 if you want to create a folder called "extracted_textures" in your "PAZ" folder and extract all the textures there.

    4 - Press 2 if you want to specify another folder to extract the textures.

    Note: After the textures are extracted, a file called "log-textures.txt" will be created in your PAZ folder which contains the relation between all .PAZ files number and texture names, this can be useful if you want to extract only a specific file in the future without having to extract all .PAZ files again
     
    alcaster4242 likes this.
  16. alcaster4242

    alcaster4242 Avid Affiliate

    Joined:
    Mar 12, 2016
    Messages:
    151
    Likes Received:
    34
    Nice, been looking for this.
     
  17. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    META INJECTOR RELOADED V1.1
    performance-meta-reloaded.jpg
    The program now runs almost twice as fast due to the new copy technique and now in "Part 2" the meta file is loaded in memory instead of accessing the file directly and after all the changes are done, a new file is created and filled with the modified content of the memory.​

    - Added options about what to do with the files in the "files_to_patch" folder after the patch is done:
    NEW-OPTIONS-META-INJECTOR-RELOADED.jpg

    - Added a header to the program showing the version.
    - File count and detection is now made before the first menu shows up
    - The "Running Meta Injector" was renamed to "Part (1/2)"
    - The "Running Meta Patcher" was renamed to "Part (2/2)"
    - Part 1 slightly faster than before.
    - Part 2 insanely faster than before.
    - Now it shows which meta file is chosen in the beginning after the user input in the first menu.
    - Fixed a bug where the same file could result in "not found" or "Success!" in "Part 2" depending on which order of the meta files were used.
     
    Last edited: Jul 9, 2016
    alcaster4242 likes this.
  18. latuel

    latuel Potential Patron

    Joined:
    Mar 24, 2016
    Messages:
    8
    Likes Received:
    0
    [​IMG]

    i'm KR Server.
    Not Found result.

     

    Attached Files:

  19. BlackFireBR

    BlackFireBR Club Regular Content Creator

    Joined:
    Sep 2, 2013
    Messages:
    921
    Likes Received:
    499
    Yeah, unfortunately those new files will not be able to be patched. Sorry =/
     
    Last edited: Jul 9, 2016
  20. Chronix

    Chronix Potential Patron

    Joined:
    Apr 24, 2016
    Messages:
    18
    Likes Received:
    1
    Since I started using the metainjector I stopped crashing to desktop in heidel.

    But I found a new problem. It's been a few times now but I get these strange graphical glitches when a valkyrie is wearing Acher Guard armor, atleast the 2 times I saw it it was a valkyrie. I'll try to screenshot it next time.

    Oh yah I don't seem to get the gltich when it is my own valkyrie wearing the armor. (armor swap and pearl shop, dont know if it would be the same if I bought it for real)