Files
2025-09-29 00:52:08 +02:00

240 lines
10 KiB
Ruby
Executable File

# File:: data_compare_merge.rb
# Description:: Functions for merging the data of two projects.
#
# Author:: Marissa Warner-Wu <marissa.warner-wu@rockstarnorth.com>
#
# Date:: 12 August 2009
#
#-----------------------------------------------------------------------------
# Uses
#-----------------------------------------------------------------------------
require 'pipeline/projectutil/data_merge'
require 'pipeline/projectutil/data_extract'
require 'pipeline/util/environment'
require 'pipeline/util/rage_pack'
#-----------------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------------
module Pipeline
module ProjectUtil
#
# == Description
# Function which compares and merges map IDE/IPL files from a root control
# project (e.g. GTA4) with files from an episodic project (e.g. GTA4 E2).
#
# IMG/RPF files - uses the root file
# IPL files - uses the episodic file
# IDE files - uses the episodic file, which is also given the suffix "_E2"
#
# After being processed, the directory which stores the merged files and the path
# to the renamed file list is passed back to an optional code block.
#
# == Example Usage
# See \util\compare\data_compare_merge_ide_ipl.rb.
#
def ProjectUtil::data_compare_merge_ide_ipl( root_branch, ep_branch, outputDir, exclude_files = [], &block )
throw RuntimeError.new( "Invalid root project branch, #{root_proj_branch.class}." ) unless ( root_branch.is_a?( Pipeline::Branch ) )
throw RuntimeError.new( "Invalid episodic project branch, #{ep_proj_branch.class}." ) unless ( ep_branch.is_a?( Pipeline::Branch ) )
# Set up paths
root_dir = OS::Path::combine( root_branch.independent, 'data', 'maps' )
ep_dir = OS::Path::combine( ep_branch.independent, 'data', 'maps' )
# Merge the root files with the episodic files, getting the list of files which have been renamed
merge_dir = OS::Path::combine( outputDir, 'ide_ipl_merge' )
ep_suffix = 'E2'
renamed = ProjectUtil::data_merge_ide_ipl( root_dir, ep_dir, merge_dir, ep_suffix, exclude_files )
# Write the renamed files to a .txt file
output_file = OS::Path::combine( outputDir, "renamed_files.txt" )
::FileUtils::rm( output_file ) if File.exist?( output_file )
log = File.new( output_file, 'w' )
log.write( "#Renamed map files from #{ep_branch.project.name}\n" )
renamed.each do |file|
# Reformat the path for inclusion in a .dat file
new_path = file.split( merge_dir )[1]
new_path.upcase!
new_path = "IDE platform:" + new_path
log.write( new_path + "\n" )
end #renamed.each
yield( merge_dir, output_file ) if ( block_given? )
end #data_compare_merge_ide_ipl
#
# == Description
# Function which compares and merges map images from a root control
# project (e.g. GTA4) with map images from an episodic project (e.g. GTA4 E2).
# Includes the option to exclude files based on an array of given file
# basenames.
#
# After being processed, files are passed back to an optional code block.
#
# == Example Usage
# See \util\compare\data_compare_merge_images.rb.
#
def ProjectUtil::data_compare_merge_maps_images( root_branch, ep_branch, target, output_dir, exclude_files = [], image = nil, &block )
# Check that given branches are valid
throw RuntimeError.new( "Invalid root project branch, #{root_proj_branch.class}." ) \
unless ( root_branch.is_a?( Pipeline::Branch ) )
throw RuntimeError.new( "Invalid episodic project branch, #{ep_proj_branch.class}." ) \
unless ( ep_branch.is_a?( Pipeline::Branch ) )
throw RuntimeError.new( "Invalid project target, #{target}." ) \
unless ( root_branch.targets.has_key?( target ) and ( ep_branch.targets.has_key?( target ) ) )
c = Pipeline::Config::instance( )
r = RageUtils.new( root_branch.project, root_branch.name )
t = root_branch.targets[target]
# Set target platform
root_platform = ''
ep_platform = ''
#root_branch.targets[target].in_env do |e|
#root_platform = e.subst( '$(target)' )
#end
ep_branch.targets[target].in_env do |e|
ep_platform = e.subst( '$(target)' )
end
root_independent_files = []
ep_independent_files = []
if ( image.nil? )
root_independent_files = OS::FindEx::find_files_recurse( OS::Path::combine( root_branch.independent, 'data', 'maps', '*.img' ) )
ep_independent_files = OS::FindEx::find_files_recurse( OS::Path::combine( ep_branch.independent, 'data', 'maps', '*.img' ) )
else
root_independent_files = OS::FindEx::find_files_recurse( OS::Path::combine( root_branch.independent, 'data', 'maps', image ) )
ep_independent_files = OS::FindEx::find_files_recurse( OS::Path::combine( ep_branch.independent, 'data', 'maps', image ) )
end
# Exclude specified files
root_independent_files.delete_if { |file| exclude_files.include?( OS::Path::get_basename( file ) ) }
# Loop through all the files in the root project and compare
# them to the episodic project
root_independent_files.each do |root_filename|
puts "Processing: #{root_filename}"
# Fetch episodic project filename
ep_filename = root_filename.sub( root_branch.independent, ep_branch.independent )
unless ( ::File::exist?( ep_filename ) )
# if the episodic file doesn't exist, use the given block to process the root file
yield( root_filename, root_filename ) if ( block_given? )
next
end
# If the episodic file exists, merge it with the root file
ProjectUtil::data_merge_pack( ep_branch.project, ep_branch, target, r, root_filename, ep_filename, output_dir ) do |merge_filename|
yield( root_filename, merge_filename ) if ( block_given? )
end
end #loop through root files
end #data_compare_merge_maps_images
#
# == Description
# Post-processing step for data_compare_merge_maps_images() which
# removes duplicate files from the images.
#
# == Example Usage
# See \util\compare\data_compare_merge_images.rb.
#
def ProjectUtil::data_compare_merge_remove_duplicates( branch, target, output_path, remove_hash )
# Temporary destination to extract to
pack_dest = OS::Path::combine( output_path, 'extracted_files' )
r = RageUtils.new( branch.project, branch.name )
# Go through each item in the hash
remove_hash.each do |filepath, items|
# Reconstruct the filepath
new_filepath = filepath.gsub( 'platformimg:', output_path )
throw RuntimeError.new( "Unable to find file #{new_filepath}" ) unless ::File::exist? new_filepath
# If the file exists, unpack it
extracted_files = []
if (OS::Path::get_extension( new_filepath ) == 'img')
ProjectUtil::data_extract_generic( r, r.image, new_filepath, pack_dest ) do |filename|
extracted_files << filename
end
end
if (OS::Path::get_extension( new_filepath ) == 'rpf')
ProjectUtil::data_extract_generic( r, r.pack, new_filepath, pack_dest ) do |filename|
extracted_files << filename
end
end
# Remove each of the duplicate items
puts "Removing items from #{OS::Path::get_filename(filepath)}:"
items.each do |item|
item_extension = OS::Path::get_extension( item )
item_extension[0] = 105 if item_extension[0] == 120 # replace 'x' with 'i'
independent_filename = OS::Path::get_basename( item ) + '.' + item_extension
item_path = OS::Path::combine( pack_dest, independent_filename )
if File::exist? item_path
::FileUtils::rm( item_path )
puts item
else
puts "Skipping #{item}, not found in this image"
end
end
# Start the builder
builder = Util::RagebuilderImage.new( branch.project, branch, branch.targets[target] ) if (OS::Path::get_extension( new_filepath ) == 'img')
builder = Util::RagebuilderPack.new( branch.project, branch, branch.targets[target] ) if (OS::Path::get_extension( new_filepath ) == 'rpf')
# Repack the files
::FileUtils::rm( new_filepath )
builder.start
extracted_files.each { |file| builder.add( file ) }
builder.save( new_filepath )
builder.close
# Clean up extracted files
::FileUtils::rm_r( pack_dest ) if ( ::File::directory?( pack_dest ) )
end #remove_hash.each
end #data_compare_merge_remove_duplicates
#
# == Description
# Function which compares and merges cutsprops images from two projects.
# In this case the "ep project" is whatever project we want to overwrite the
# files in the "root project".
#
# After being processed, files are passed back to an optional code block.
#
# == Example Usage
# See \util\compare\data_compare_merge_cutsprops.rb.
#
def ProjectUtil::data_compare_merge_cutsprops( root_branch, ep_branch, target, output_dir, &block )
# Check that given branches are valid
throw RuntimeError.new( "Invalid root project branch, #{root_proj_branch.class}." ) \
unless ( root_branch.is_a?( Pipeline::Branch ) )
throw RuntimeError.new( "Invalid episodic project branch, #{ep_proj_branch.class}." ) \
unless ( ep_branch.is_a?( Pipeline::Branch ) )
throw RuntimeError.new( "Invalid project target, #{target}." ) \
unless ( root_branch.targets.has_key?( target ) and ( ep_branch.targets.has_key?( target ) ) )
r = RageUtils.new( root_branch.project, root_branch.name )
# Define paths for files
root_cutsprops = OS::Path::combine( root_branch.independent, 'anim', 'cutsprops.img' )
ep_cutsprops = OS::Path::combine( ep_branch.independent, 'anim', 'cutsprops.img' )
# If the episodic file exists, merge it with the root file
ProjectUtil::data_merge_pack( ep_branch.project, ep_branch, target, r, root_cutsprops, ep_cutsprops, output_dir ) do |merge_filename|
yield( root_cutsprops, merge_filename ) if ( block_given? )
end
end #data_compare_merge_cutsprops
end # ProjectUtil module
end # Pipeline module
# data_compare_merge.rb