Jump to content

HDT AutoPatch Script


kharlynak

Recommended Posts

Hey everyone. I like using The Joy of Perspective with HDT BBP enabled bodies, and wrote a script to automatically add the extradata string needed to enable it.

 

Requirements

 

(This order)

 

Python 3.3 (32 or 64bit is fine).

PyWin for 3.3

PyFFI 2.2.2

 

Usage

 

There are two ways to use the script. By default, it's set up to take a directory (with the -d switch) and will recurse into it and add the extradata string for HDT to each nif found in the folders.

 

The way to use this with BodySlide is to select *only* gloves/boots etc (everything but the main armor) and batch build that. Then batch build all the armors without the gloves/boots etc. while holding CTRL down. Put it into a separate directory somewhere and issue this command:

python hdt_data_adder.py -d <directory>

After it's finished and returns to prompt, copy the directory into your Skyrim Data directory and overwrite.

 

 

The other way is a single file mode. Go to the bottom of the file here and replace alt_main() with main(), then call it like this 

python hdt_data_adder.py -i <inputfile> -o <outputfile> -p <hdtxmlpath>

The last parameter is optional and allows specifying the path to the HDT xml file that will be used.

#!C:\Python32
from __future__ import print_function
import os, sys, getopt
from pyffi.formats.nif import NifFormat

m_version = 0
u_version = 0

def list_files(dir):                                                                                                  
    r = []                                                                                                            
    subdirs = [x[0] for x in os.walk(dir)]                                                                            
    for subdir in subdirs:                                                                                            
        files = os.walk(subdir).__next__()[2]                                                                             
        if (len(files) > 0):                                                                                          
            for file in files:                                                                                        
                r.append(subdir + "/" + file)                                                                         
    return r        
def alt_main():
    global m_version, u_version

    input_directory = ''
    
    hdtpath = 'Data\meshes\hdt.xml'
    try:
        opts, args = getopt.getopt( sys.argv[1:], 'hd:' )
    except getopt.GetoptError:
        print( 'test.py -d <directory>' )
        os._exit(1)

    for opt, arg in opts:
        if opt == '-h':
            print( 'test.py -d <directory>' )
            os._exit(1)    
        elif opt == '-d':
            input_directory = arg
                
    subdirs = [x[0] for x in os.walk(input_directory)]                                                                            
    
    for subdir in subdirs:
        
        files = os.walk(subdir).__next__()[2]
                                                                                
        if (len(files) > 0):                                                                                          
            for file in files:
                print( "Processing file - " + file + " .", end='' )

                try:
                    f = open( subdir + "/" + file, 'rb' )
                except Exception:
                    print( 'Could not open file ' + subdir + "/" + file )
                    os._exit(1)
                                    
                print( ".", end='' )

                try:
                    data = NifFormat.Data(version=0x14010003, user_version=10)
                    data.read( f )
                except Exception: 
                    print( 'Could not read data from file.' )
                    os._exit(1)

                print( ".", end='' )

                try: 
                    f.close()
                except Exception:
                    print( 'Could not close file.' )
                    os._exit(1)

                print( ".", end='' )

                try:
                    f = open( subdir + "/" + file, 'wb' )
                except Exception:
                    print( 'Could not open file ' + subdir + "/" + file )
                    os._exit(1)

                print( ".", end='' )

                try:
                    root_block = None

                    for root in data.roots:
                        if isinstance( root, NifFormat.NiNode ): 
                            root_block = root
                            break   

                    hdt_extra_data = create_block( 'NiStringExtraData' )
                    hdt_extra_data.name = 'HDT Havok Path'
                    hdt_extra_data.string_data = hdtpath

                    bytes_name = hdt_extra_data.name
                    bytes_data = hdt_extra_data.string_data

                    root_block.add_extra_data( hdt_extra_data )
                except Exception:
                    print( 'Problem finding root, creating or adding block.' )
                    
                print( ".", end='' )

                try:
                    data.write( f )
                except Exception:
                    print( 'Error writing file' )
                    os._exit(1)

                print( ".", end='' )

                try:
                    f.close()
                except Exception:
                    print( 'Error closing file.' )
                    os._exit(1)

                print( ". Done!" )
                    
def main():
    global m_version, u_version

    inputfile = ''
    outputfile = ''
    hdtpath = 'Data\meshes\hdt.xml'
    try:
        opts, args = getopt.getopt( sys.argv[1:], 'hi:o:p:' )
    except getopt.GetoptError:
        print( 'test.py -i <inputfile> -o <outputfile> -p <hdtxmlpath>' )
        os._exit(1)

    for opt, arg in opts:
        if opt == '-h':
            print( 'test.py -i <inputfile> -o <outputfile>' )
            os._exit(1)    
        elif opt == '-i':
            inputfile = arg
        elif opt == '-o':
            outputfile = arg
        elif opt == '-p':
            hdtpath = arg

    try:
        f = open( inputfile, 'rb' )
    except Exception:
        print( 'Could not open file ' + inputfile )
        os._exit(1)

    try:
        data = NifFormat.Data(version=0x14010003, user_version=10)
        data.read( f )
    except Exception: 
        print( 'Could not read data from file.' )
        os._exit(1)

    try: 
        f.close()
    except Exception:
        print( 'Could not close file.' )
        os._exit(1)

    try:
        f = open( outputfile, 'wb' )
    except Exception:
        print( 'Could not open file ' + inputfile )
        os._exit(1)

    try:
        root_block = None

        for root in data.roots:
            if isinstance( root, NifFormat.NiNode ): 
                root_block = root
                break   

        hdt_extra_data = create_block( 'NiStringExtraData' )
        hdt_extra_data.name = 'HDT Havok Path'
        hdt_extra_data.string_data = hdtpath

        bytes_name = hdt_extra_data.name
        bytes_data = hdt_extra_data.string_data

        root_block.add_extra_data( hdt_extra_data )
    except Exception:
        print( 'Problem finding root, creating or adding block.' )
        
    try:
        data.write( f )
    except Exception:
        print( 'Error writing file' )
        os._exit(1)
    try:
        f.close()
    except Exception:
        print( 'Error closing file.' )
        os._exit(1)

    print( 'HDT extra data name = ' + bytes_name.strip().decode( 'ascii' ) )
    print( 'HDT extra data string data= ' + bytes_data.strip().decode( 'ascii' ) )

def test_main():
    input_directory = ''
    
    hdtpath = 'Data\meshes\hdt.xml'
    try:
        opts, args = getopt.getopt( sys.argv[1:], 'hd:' )
    except getopt.GetoptError:
        print( 'test.py -d <directory>' )
        os._exit(1)

    for opt, arg in opts:
        if opt == '-h':
            print( 'test.py -d <directory>' )
            os._exit(1)    
        elif opt == '-d':
            input_directory = arg

    print( os.path.abspath(input_directory) )

""" create_block taken from http://niftools.sourceforge.net/doc/blender_nif_plugin/_modules/io_scene_nif/nif_export.html """
def create_block( blocktype, b_obj = None ):
    """Helper function to create a new block, register it in the list of
    exported blocks, and associate it with a Blender object.

    @param blocktype: The nif block type (for instance "NiNode").
    @type blocktype: C{str}
    @param b_obj: The Blender object.
    @return: The newly created block."""
    try:
        block = getattr( NifFormat, blocktype )()
    except AttributeError:
        raise NifExportError(
            "'%s': Unknown block type (this is probably a bug)."
            % blocktype )

    return block


if __name__ == "__main__":
    alt_main()
Link to comment

Nice .Hey message to Hydrogen to help ,your knowledge will be useful  for making jff 2 quicker )) We need to help how we can for this. 

 

 

Well to be honest, I'm not a python programmer - I don't like the way it uses whitespace for scoping.

 

The above script is basically very simple - it just opens the file and adds a StringExtraData node. All the magic is there in the function for adding a block (node).

 

The rest of it is just standard file operations. 

Link to comment

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use