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

190 lines
7.5 KiB
Ruby
Executable File

#
# File:: data_merge.rb
# Description:: Functions for merging data.
#
# Author:: Marissa Warner-Wu <marissa.warner-wu@rockstarnorth.com>
# Date:: 12 August 2009
#
#-----------------------------------------------------------------------------
# Uses
#-----------------------------------------------------------------------------
require 'pipeline/os/file'
require 'pipeline/util/rage_image'
require 'pipeline/util/rage_pack'
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 generic pack files and merges them. Any files from
# the first pack file which overlap with the second will be overwritten.
# Supports both IMG and RPF files.
#
# If file is only in pack2 - adds this file to new pack file
# If file is only in pack1 - adds this file to new pack file
# If file is in both pack files - use the file from pack2
#
# 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 pack.
#
# ProjectUtil::data_merge_pack( ep_branch.project, ep_branch, target, r, root_independent_filename, ep_independent_filename, map_log ) do |new_filename|
# puts new_filename
# end
#
def ProjectUtil::data_merge_pack(proj, branch, target, r, pack1, pack2, output_dir, &block)
# Start the builder
builder = Util::RagebuilderImage.new( proj, branch, branch.targets[target] ) if (OS::Path::get_extension( pack1 ) == 'img')
builder = Util::RagebuilderPack.new( proj, branch, branch.targets[target] ) if (OS::Path::get_extension( pack1 ) == 'rpf')
# Extract the contents of the two images, overwriting image1 contents with image2 contents
pack_dest = OS::Path::combine( output_dir, 'extracted_files' )
if (OS::Path::get_extension( pack1 ) == 'img')
ProjectUtil::data_extract_generic( r, r.image, pack1, pack_dest )
ProjectUtil::data_extract_generic( r, r.image, pack2, pack_dest, true )
end
if (OS::Path::get_extension( pack1 ) == 'rpf')
ProjectUtil::data_extract_generic( r, r.pack, pack1, pack_dest )
ProjectUtil::data_extract_generic( r, r.pack, pack2, pack_dest, true )
end
# Construct the new pack filename, preserving the file hierarchy
pack_filename = output_dir
parts = OS::Path::get_parts( pack1 )
maps_found = false
parts.each do |pathpart|
pack_filename = OS::Path::combine( pack_filename, pathpart ) if maps_found
maps_found = true if pathpart.eql? "maps"
end
# If this isn't a map then just put it in the output directory
#pack_filename = OS::Path::combine( output_dir, OS::Path::get_filename( pack1 ) ) unless maps_found
# Repack the files
builder.start
files = OS::FindEx::find_files_recurse( OS::Path::combine( pack_dest, '*.*' ) )
files.each { |file| builder.add( file ) }
builder.save( pack_filename )
builder.close
yield( pack_filename ) if ( block_given? )
# Clean up extracted files
::FileUtils::rm_r( pack_dest ) if ( ::File::directory?( pack_dest ) )
end #data_merge_pack
#
# == Description
# A function which merges the non-image map data from two directories.
#
# .ipl - Uses file from dir2
# .ide - Uses both files, files from dir2 are renamed using the given suffix
#
# Returns an array of the files which have been renamed. Also gives the option
# of ignoring certain files, specified in an array of file basenames.
#
# === Example Usage
# ProjectUtil::data_merge_ide_ipl( "x:/gta/build/dev/independent/", "x:/gta_e2/build/dev/independent/", "x:/merge", "E2" )
# ==> ["x:/merge/independent/data/maps/toolstest_E2.ide", etc.]
#
def ProjectUtil::data_merge_ide_ipl( dir1, dir2, merge_dir, dir2_suffix, exclude_files = [] )
throw ArgumentError.new("Directory 1 (#{dir1}) is not a real directory") unless ( ::File::directory?( dir1 ) )
throw ArgumentError.new("Directory 2 (#{dir2}) is not a real directory") unless ( ::File::directory?( dir2 ) )
puts "Now comparing #{dir1} to #{dir2}..."
# Make the merge directory if it doesn't already exist
::FileUtils::mkdir_p( merge_dir ) unless ( ::File::directory?( merge_dir ) )
# Find the files in both directories
dir1_files = OS::FindEx::find_files_recurse( OS::Path::combine( dir1, '*.*' ) )
dir2_files = OS::FindEx::find_files_recurse( OS::Path::combine( dir2, '*.*' ) )
# Exclude specified files
dir1_files.delete_if { |file| exclude_files.include?( OS::Path::get_basename( file ) ) }
dir2_files.delete_if { |file| exclude_files.include?( OS::Path::get_basename( file ) ) }
# Loop through dir1 files and compare to those in dir2
renamed = []
dir1_files.each do |dir1_file|
# Skip IMG and RPF files
next if OS::Path::get_extension( dir1_file ) == "img"
next if OS::Path::get_extension( dir1_file ) == "rpf"
# Get the matching filenames and path
dir2_file = dir1_file.sub( dir1, dir2 )
merge_file = dir1_file.sub( dir1, merge_dir )
merge_path = OS::Path::remove_filename( merge_file )
::FileUtils::mkdir_p( merge_path ) unless ( ::File::directory?( merge_path ) )
# Merge the files
old_file = ""
new_file = ""
if ( ::File::exist?( dir2_file ) )
# If the dir2 file exists, switch by extension
case OS::Path::get_extension( dir1_file )
when 'ipl'
# If this is an .xpl file, use the dir2 file
old_file = dir2_file
new_file = merge_file
when 'ide'
# If this is an .ide file, use the dir2 file and rename it with the given suffix
new_path = OS::Path::remove_extension( merge_file ) + "_" + dir2_suffix + ".ide"
renamed << new_path
# This is a special case since we need to copy both files
FileUtils::rm( new_path ) if ::File::exist?( new_path )
FileUtils::cp( dir2_file, new_path, :preserve => true )
FileUtils::chmod( 0666, new_path )
puts "Processing: #{dir1_file}"
puts "OLD FILE: #{dir2_file}"
puts "NEW FILE: #{new_path}"
FileUtils::rm( merge_file ) if ::File::exist?( merge_file )
FileUtils::cp( dir1_file, merge_file, :preserve => true )
FileUtils::chmod( 0666, merge_file )
puts "Processing: #{dir1_file}"
puts "OLD FILE: #{dir1_file}"
puts "NEW FILE: #{merge_file}"
next
end #case OS::Path::get_extension( dir1_file )
else
# If the dir2 file doesn't exist, use the dir1 file
old_file = dir1_file
new_file = merge_file
end #if ( ::File::exist?( dir2_file ) )
FileUtils::rm( new_file ) if ::File::exist?( new_file )
FileUtils::cp( old_file, new_file, :preserve => true )
FileUtils::chmod( 0666, new_file )
puts "Processing: #{dir1_file}"
puts "OLD FILE: #{old_file}"
puts "NEW FILE: #{new_file}"
end #dir1_files.each
renamed
end #data_merge_xbox_dirs
end # ProjectUtil module
end # Pipeline module
# data_merge.rb