358 lines
13 KiB
Ruby
Executable File
358 lines
13 KiB
Ruby
Executable File
#
|
|
# File:: data_remove.rb
|
|
# Description:: Functions for removing unused data.
|
|
#
|
|
# Author:: Marissa Warner-Wu <marissa.warner-wu@rockstarnorth.com>
|
|
# Date:: 19 June 2009
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'pipeline/os/file'
|
|
require 'pipeline/util/rage_image'
|
|
require 'pipeline/projectutil/data_extract'
|
|
require 'pipeline/resourcing/path'
|
|
require 'pipeline/config/targets'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
module Pipeline
|
|
module ProjectUtil
|
|
|
|
#-------------------------------------------------------------------------
|
|
# Functions
|
|
#-------------------------------------------------------------------------
|
|
|
|
#
|
|
# == Description
|
|
# A function which takes two image files and creates a new version of the
|
|
# first image without any items which overlap with the second image.
|
|
#
|
|
# If file is only in image1 - adds this file to new image
|
|
# If file is in both images - doesn't add
|
|
# i.e. image1 - image2 = resulting image
|
|
#
|
|
# Compares based on file name. Also appends some log information to an
|
|
# optional output file.
|
|
#
|
|
# === Example Usage
|
|
# The code below would print the name of the new image.
|
|
#
|
|
# ProjectUtil::data_cull_image( ep_branch.project, ep_branch, target, r, root_independent_filename, ep_independent_filename, output_dir, map_log ) do |new_filename|
|
|
# puts new_filename
|
|
# end
|
|
#
|
|
def ProjectUtil::data_cull_image(proj, branch, target, r, image1, image2, output_dir, output_file = "", &block)
|
|
|
|
# Start the builder
|
|
builder = Util::RagebuilderImage.new( proj, branch, branch.targets[target] )
|
|
|
|
# Open the output file and write the name of the file
|
|
log = nil
|
|
count = 0
|
|
unless output_file == ""
|
|
log = File.new(output_file, 'a')
|
|
log.write "#{image1}\n"
|
|
end
|
|
|
|
# Extract the contents of the two images ready for comparison.
|
|
image1_dest = OS::Path::combine( output_dir, 'image1' )
|
|
image2_dest = OS::Path::combine( output_dir, 'image2' )
|
|
image1_fullpath = []
|
|
image2_fullpath = []
|
|
image2_files = []
|
|
ProjectUtil::data_extract_image( r, image1, image1_dest ) do |extracted_filename|
|
|
image1_fullpath << extracted_filename
|
|
end
|
|
ProjectUtil::data_extract_image( r, image2, image2_dest ) do |extracted_filename|
|
|
image2_fullpath << extracted_filename
|
|
image2_files << OS::Path::get_filename( extracted_filename )
|
|
end
|
|
|
|
image_filename = OS::Path::combine( output_dir, OS::Path::get_trailing_directory( image1 ), OS::Path::get_filename( image1 ) )
|
|
builder.start
|
|
|
|
# Iterate over the file lists comparing filenames that match. Images
|
|
# have a flat directory structure so we don't need to worry about
|
|
# sub-directories. If the output file is specified then use this as well.
|
|
image1_fullpath.each do |image1_filename|
|
|
image1_file = OS::Path::get_filename( image1_filename )
|
|
unless ( image2_files.include?( OS::Path::get_filename( image1_file ) ) )
|
|
# Only add this file if it is not present in image2
|
|
builder.add( image1_filename )
|
|
next
|
|
end
|
|
|
|
#If we're not adding this to the image then log it
|
|
if log then
|
|
log.write "\t\t\t#{image1_file}\n"
|
|
count += 1
|
|
end
|
|
|
|
end #image1_fullpath.each
|
|
|
|
builder.save( image_filename )
|
|
builder.close
|
|
if log then
|
|
log.write "\tTOTAL: #{count}\n"
|
|
log.close
|
|
end
|
|
yield( image_filename ) if ( block_given? )
|
|
|
|
# Clean up extracted files
|
|
::FileUtils::rm_r( image1_dest ) if ( ::File::directory?( image1_dest ) )
|
|
::FileUtils::rm_r( image2_dest ) if ( ::File::directory?( image2_dest ) )
|
|
|
|
end #data_cull_image
|
|
|
|
|
|
#
|
|
# == Description
|
|
# A function which takes a cutsprops.img file from one project and
|
|
# compares it to cuts.img and cutsprops.img files from another project,
|
|
# removing the items not used in the cutscenes. Logs output to a file,
|
|
# cutsprops_compare_output.txt, in the output directory.
|
|
#
|
|
# Compares based on file name.
|
|
#
|
|
# === Example Usage
|
|
# The code below would print the name of the new image.
|
|
#
|
|
# ProjectUtil::data_cull_cutsprops( root_branch.project, root_branch, target, r, root_cutsprops, ep_cuts1, ep_cutsprops1, ep_cuts2, ep_cutsprops2, output_dir ) do |new_filename|
|
|
# puts new_filename
|
|
# end
|
|
#
|
|
def ProjectUtil::data_cull_cutsprops(proj, branch, target, r, cutsprops1, cuts1, cutsprops2, cuts2, cutsprops3, output_dir, &block)
|
|
|
|
puts "Output being written to cutsprops_compare_output.txt"
|
|
|
|
# Start the builder
|
|
builder = Util::RagebuilderImage.new( proj, branch, branch.targets[target] )
|
|
|
|
# Set up output file
|
|
log_filename = OS::Path::combine( output_dir, 'cutsprops_compare_output.txt' )
|
|
log = File.new( log_filename, 'w')
|
|
log.write("CUTSPROPS1: #{cutsprops1}\n")
|
|
log.write("CUTSPROPS2: #{cutsprops2}\n\n")
|
|
log.write("CUTSPROPS3: #{cutsprops3}\n\n")
|
|
|
|
# Keep track of cutscenes which have had duplicate files removed
|
|
duplicates = []
|
|
|
|
# Extract the contents of the two images for comparison and get lists of relevant files
|
|
cutsprops1_dest = OS::Path::combine( output_dir, 'cutsprops1' )
|
|
cutsprops2_dest = OS::Path::combine( output_dir, 'cutsprops2' )
|
|
cuts_dest = OS::Path::combine( output_dir, 'cuts' )
|
|
cuts_files = []
|
|
|
|
ProjectUtil::data_extract_image( r, cutsprops1, cutsprops1_dest )
|
|
ProjectUtil::data_extract_image( r, cutsprops2, cutsprops2_dest )
|
|
ProjectUtil::data_extract_image( r, cutsprops3, cutsprops2_dest, true )
|
|
ProjectUtil::data_extract_image( r, cuts1, cuts_dest )
|
|
ProjectUtil::data_extract_image( r, cuts2, cuts_dest )
|
|
cuts_files = OS::FindEx::find_files_recurse( OS::Path::combine( cuts_dest, '*.cut*' ) )
|
|
|
|
image_filename = OS::Path::combine( output_dir, 'cutsprops.img' )
|
|
builder.start( )
|
|
|
|
# Iterate over the .cut files and add required assets to image
|
|
used_assets = []
|
|
cuts_files.each do |cutscene|
|
|
log.write("Parsing cutscene: #{cutscene}\n")
|
|
text = []
|
|
assets = []
|
|
start = 0
|
|
finish = 0
|
|
|
|
# Parse for asset list
|
|
File.open(cutscene, 'r') do
|
|
text = IO.readlines( cutscene )
|
|
start = text.index( "[MODELS]\n" ) + 1
|
|
finish = text.index( "[/MODELS]\n" ) - 1
|
|
assets = text[start..finish]
|
|
end
|
|
|
|
# If this asset is used, add to the builder
|
|
assets.each do |line|
|
|
# Parse each line in the list for the item
|
|
item = ""
|
|
l = line.split[1]
|
|
if l then
|
|
item = l.downcase
|
|
log.write("\t\t\t#{item} - ")
|
|
else
|
|
log.write("\t\t\tNIL - ")
|
|
end
|
|
# Check to see if we should skip this item
|
|
if item == "" then
|
|
log.write("skipped because nil\n")
|
|
next
|
|
end
|
|
if item == "player" then
|
|
log.write("skipped because player\n")
|
|
next
|
|
end
|
|
if used_assets.include?( item ) then
|
|
log.write("skipped because already added\n")
|
|
next
|
|
end
|
|
cutsprops2_files = []
|
|
cutsprops2_files = OS::FindEx::find_files_recurse( OS::Path::combine( cutsprops2_dest, item + ".*" ) )
|
|
unless cutsprops2_files == [] then
|
|
log.write("skipped because in cutsprops2 or 3\n")
|
|
duplicates << cutscene
|
|
next
|
|
end
|
|
# Otherwise, find all the related files and add to the image
|
|
log.write("Searching for '" + OS::Path::combine( cutsprops1_dest, item + ".*" ) + "' " )
|
|
asset_files = OS::FindEx::find_files_recurse( OS::Path::combine( cutsprops1_dest, item + ".*" ) )
|
|
if asset_files == [] then
|
|
log.write("[[ERROR: no asset files found for this item]]\n")
|
|
next
|
|
end
|
|
used_assets << item
|
|
log.write("adding to image:\n")
|
|
asset_files.each do |file|
|
|
log.write("\t\t\t\t\t#{file}\n")
|
|
builder.add( file )
|
|
end
|
|
end #assets.each
|
|
end #cuts_files.each
|
|
|
|
if duplicates == [] then
|
|
log.write("==NO DUPLICATES FOUND\n")
|
|
else
|
|
log.write("==DUPLICATE FILES REMOVED FROM: #{duplicates}\n")
|
|
end
|
|
|
|
log.close
|
|
builder.save( image_filename )
|
|
builder.close( )
|
|
yield( image_filename ) if ( block_given? )
|
|
|
|
# Clean up extracted files
|
|
::FileUtils::rm_r( cutsprops1_dest ) if ( ::File::directory?( cutsprops1_dest ) )
|
|
::FileUtils::rm_r( cutsprops2_dest ) if ( ::File::directory?( cutsprops2_dest ) )
|
|
::FileUtils::rm_r( cuts_dest ) if ( ::File::directory?( cuts_dest ) )
|
|
|
|
end #data_cull_cutsprops
|
|
|
|
|
|
#
|
|
# == Description
|
|
# A function which replaces a given cuts image with a dummy file. The .cut
|
|
# files are replaced with empty files and the .iad files are replaced with a
|
|
# given template. The resulting image is passed to an optional given block.
|
|
#
|
|
# === Example Usage
|
|
# The code below would print the name of the new image.
|
|
#
|
|
# ProjectUtil::data_dummy_cuts( root_branch.project, root_branch, target, r, root_cuts, template_filename, output_dir ) do |new_filename|
|
|
# puts new_filename
|
|
# end
|
|
#
|
|
def ProjectUtil::data_dummy_cuts(proj, branch, target, r, image, template_file, output_dir, &block)
|
|
throw ArgumentError.new( "Invalid target object (#{target.class})." ) \
|
|
unless ( target.is_a?( Pipeline::Target ) )
|
|
throw ArgumentError.new( "Template file does not exist (#{template_file})." ) \
|
|
unless ( File.exist?(template_file) )
|
|
|
|
# Start the builder
|
|
builder = Util::RagebuilderImage.new( proj, branch, target )
|
|
|
|
# Read the template file
|
|
template = IO.read(template_file)
|
|
|
|
# Extract the contents of the image to a temporary folder
|
|
image_dest = OS::Path::combine( output_dir, 'dummy_cuts' )
|
|
image_fullpath = []
|
|
ProjectUtil::data_extract_image( r, image, image_dest ) do |extracted_filename|
|
|
image_fullpath << extracted_filename
|
|
end
|
|
|
|
new_image_filename = OS::Path::combine( output_dir, OS::Path::get_filename( image ) )
|
|
builder.start( )
|
|
|
|
# Iterate over the list of extracted files and replaces them
|
|
image_fullpath.each do |image_filename|
|
|
#target_filename = Resourcing::convert_independent_filename_to_platform( image_filename, target )
|
|
if OS::Path::get_extension( image_filename ) == "cut" then
|
|
f = File.new( image_filename, 'w' )
|
|
f.write( "[CUTSCENE_HEADER]\n1 1 1 1\n[/CUTSCENE_HEADER]\n" )
|
|
f.close
|
|
elsif OS::Path::get_extension( image_filename ) == "iad" then
|
|
f = File.new( image_filename, 'w' )
|
|
f.write( template )
|
|
f.close
|
|
else
|
|
puts "ERROR: #{image_filename} is not a .cut or a .iad file, skipping"
|
|
next
|
|
end
|
|
builder.add( image_filename )
|
|
end #image_fullpath.each
|
|
|
|
builder.save( new_image_filename )
|
|
builder.close( )
|
|
yield( new_image_filename ) if ( block_given? )
|
|
|
|
# Clean up extracted files
|
|
::FileUtils::rm_r( image_dest ) if ( ::File::directory?( image_dest ) )
|
|
|
|
end #data_dummy_cuts
|
|
|
|
|
|
#
|
|
# == Description
|
|
# A function which replaces a given image with a dummy image. All the
|
|
# files inside the image are extracted, replaced with dummies, and then
|
|
# repacked. The resulting image is passed to an optional given block.
|
|
#
|
|
# === Example Usage
|
|
# The code below would print the name of the new image.
|
|
#
|
|
# ProjectUtil::data_dummy_image( root_branch.project, root_branch, target, r, root_cuts, output_dir ) do |new_filename|
|
|
# puts new_filename
|
|
# end
|
|
#
|
|
def ProjectUtil::data_dummy_image(proj, branch, target, r, image, output_dir, &block)
|
|
throw ArgumentError.new( "Invalid target object (#{target.class})." ) \
|
|
unless ( target.is_a?( Pipeline::Target ) )
|
|
|
|
# Start the builder
|
|
builder = Util::RagebuilderImage.new( proj, branch, target )
|
|
|
|
# Extract the contents of the image to a temporary folder
|
|
image_dest = OS::Path::combine( output_dir, 'dummy_image' )
|
|
image_fullpath = []
|
|
ProjectUtil::data_extract_image( r, image, image_dest ) do |extracted_filename|
|
|
image_fullpath << extracted_filename
|
|
end
|
|
|
|
new_image_filename = OS::Path::combine( output_dir, OS::Path::get_filename( image ) )
|
|
builder.start( )
|
|
|
|
# Iterate over the list of extracted files and replaces with with empty target files
|
|
image_fullpath.each do |image_filename|
|
|
target_filename = Resourcing::convert_independent_filename_to_platform( image_filename, target )
|
|
puts target_filename
|
|
f = File.new( target_filename, 'w')
|
|
f.write('x')
|
|
builder.add( target_filename )
|
|
f.close
|
|
end #image_fullpath.each
|
|
|
|
builder.save( new_image_filename )
|
|
builder.close( )
|
|
yield( new_image_filename ) if ( block_given? )
|
|
|
|
# Clean up extracted files
|
|
::FileUtils::rm_r( image_dest ) if ( ::File::directory?( image_dest ) )
|
|
|
|
end #data_dummy_image
|
|
|
|
end # ProjectUtil module
|
|
end # Pipeline module
|
|
|
|
# data_remove.rb |