# # File:: repack_frag_tune.rb # Description:: Extract an IMG file, look up the *.ift's tune files, pack it in the *.ift # and put them back in the original *.img file. # # Author:: Terry Litrenta # Date:: 30 July 2009 # # This is my first Ruby script so please no snickering, laughing or downright knee slapping # because of the numerous ways I am doing things. I will learn over time, but for now, lots of copy/pasting. :) # #---------------------------------------------------------------------------- # Uses #---------------------------------------------------------------------------- require 'pipeline/gui/log_window' require 'pipeline/config/projects' require 'pipeline/os/getopt' require 'pipeline/os/path' require 'pipeline/projectutil/data_extract' require 'pipeline/projectutil/data_convert' require 'pipeline/resourcing/image' require 'pipeline/util/rage' require 'pipeline/win32/kernel32' include Pipeline #---------------------------------------------------------------------------- # Constants #---------------------------------------------------------------------------- OPTIONS = [ [ '--project', '-p', Getopt::REQUIRED, 'project data to convert (e.g. jimmy, gta4_jpn).' ], [ '--branch', '-b', Getopt::REQUIRED, 'project branch to convert (e.g. dev, dev_migrate).' ], [ '--output', '-o', OS::Getopt::REQUIRED, 'output directory (root for multiple RPF extraction).' ], [ '--overwrite', '-f', OS::Getopt::BOOLEAN, 'overwrite files if required.' ], [ '--debug', '-d', OS::Getopt::BOOLEAN, 'debug mode toggle.' ], [ '--help', '-h', OS::Getopt::BOOLEAN, 'display usage information.' ] ] TRAILING_DESC = { 'files' => 'IMG files to extract.' } IMAGE_MOUNT = 'image:/' PACK_MNT = "pack:/" #---------------------------------------------------------------------------- # Implementation #---------------------------------------------------------------------------- if ( __FILE__ == $0 ) then begin g_AppName = File::basename( __FILE__, '.rb' ) g_ProjectName = '' g_Project = nil g_Branch = '' g_Config = Pipeline::Config.instance( ) #--------------------------------------------------------------------- # Parse Command Line #--------------------------------------------------------------------- opts, trailing = OS::Getopt.getopts( OPTIONS ) if ( opts['help'] ) then puts OS::Getopt.usage( OPTIONS, TRAILING_DESC ) exit( 1 ) end g_Debug = opts['debug'].nil? ? false : true Pipeline::Config::instance()::log_trace = g_Debug # Force log output Pipeline::Config::instance()::log_level = 2 Pipeline::Config::instance()::log_level = 1 if ( g_Debug ) g_Log = Log.new( g_AppName ) g_ProjectName = ( nil == opts['project'] ) ? '' : opts['project'] project_exists = ( g_Config.projects.has_key?( g_ProjectName ) ) if ( not project_exists ) then puts OS::Getopt.usage( OPTIONS, TRAILING_DESC ) puts "\nError project: #{g_ProjectName} does not exist or its configuration is unreadable." exit( 2 ) end g_Project = g_Config.projects[ g_ProjectName ] if ( not g_Project.enabled ) then puts "\nError project: #{g_ProjectName} is not enabled on this machine. Re-run installer." exit( 3 ) end g_Project.load_config( ) g_BranchName = ( nil == opts['branch'] ) ? g_Project.default_branch : opts['branch'] if ( not g_Project.branches.has_key?( g_BranchName ) ) then puts "\nError project: #{g_ProjectName} does not have a branch called #{g_BranchName}." exit( 4 ) end g_Branch = g_Project.branches[g_BranchName] # Initialise RAGE (image file interface) Pipeline::Config.instance.log_generate_html = false r = Pipeline::RageUtils.new( g_Project, g_BranchName ) # Get the image file we want to extract and the path to extract to. image = ::File::expand_path( trailing[0] ) path = OS::Path::combine(OS::Path.get_temp_directory(), OS::Path.get_basename(image)) # If we already have a directory with previous data then kill it and remake the directory, otherwise just create a new directory. if ( File.directory?(path) ) then FileUtils::remove_dir(path, true) FileUtils.mkdir(path) else FileUtils.mkdir(path) end # Make sure the image file exists and it's not read-only. if (not File.exists?(image)) then puts "\nError: #{image} file does not exist." exit(5) end if (not File.writable?(image)) then puts "\nError: #{image} file is not writable. Please check it out from Perforce before running this." exit(6) end # Get a list of all the files in the image file. files = [] r.image.mount( image, IMAGE_MOUNT ) image_files = r.find_files( "#{IMAGE_MOUNT}*.*" ) image_files.each do |file| files << file end r.image.unmount( image ) # Keep a variable to see if we actually need to rebuild the .img. # If no .ift files are in the source image then there is no point to build or convert the final image. bNeedToBuildImg = false # Do the actual extraction of the needed files from the image. exfiles = Resourcing::Image.extract( r, image, path, files ) # Go through the files extracted and just look at the .ift files. exfiles.each do |f| if (OS::Path.get_extension(f) == "ift") then # Extract the *.ift RPF file. ProjectUtil.data_extract_rpf( r, f, OS::Path::combine(path, OS::Path.get_basename(f)) ) # See if we have a tune file for this object in the data\fragments folder. tuneFile = OS::Path::combine(g_Branch.common, "data", "fragments", OS::Path::get_basename(f)) + '.tune' if (File.exists?(tuneFile)) then # Copy the tune file from the data\fragments folder into our temp extracted folder. r.util.copy_file(tuneFile, OS::Path::combine(path, OS::Path.get_basename(f), OS::Path.get_basename(f)) + '.tune') # Start a new RPF file. r.pack.start() # Grab all the files in the temp IFT object directory. newFileList = r.find_files(OS::Path::combine(path, OS::Path.get_basename(f)) + "\\*.*") finalIFT = OS::Path::combine(path, OS::Path.get_basename(f)) + '.ift' # Take all the files in the temp directory and add them to the new RPF file. newFileList.each do |packFile| fullFilename = OS::Path::combine(path, OS::Path.get_basename(f), packFile) puts "Adding: #{fullFilename}\n" r.pack.add(fullFilename, nil) end # Save the new RPF file with it's updated contents. r.pack.save(finalIFT) r.pack.close() end # We have a reason to live! bNeedToBuildImg = true end end if (bNeedToBuildImg) then # Get a list of all the files in the temp directory minus the folders we extracted data too. imageFileList = r.util.find_files("#{path}\\*.*", false, true).split(",") # Overwrite the original image with the new one we built. Resourcing::Image.create( r, image, imageFileList ) # Do the platform conversion of the new image file. ProjectUtil::data_convert_file( image, true ) # Yay! puts "\n\nCompleted: #{image}" else puts "\n\nNo rebuilding needed. No *.ift files exist in image" end rescue Exception => ex exit( ex.status ) if ( 'exit' == ex.message ) puts "\n#{g_AppName} unhandled exception: #{ex.message}" puts ex.backtrace.join("\n\t") end end