# # File:: script/japanese/data_patch_tcls.rb # Description:: # # Author:: David Muir # Date:: 30 May 2013 # #----------------------------------------------------------------------------- # Uses #----------------------------------------------------------------------------- require 'RSG.Base.dll' require 'RSG.Base.Configuration.dll' require 'RSG.Base.Windows.dll' require 'RSG.Pipeline.Core.dll' require 'RSG.Pipeline.Content.dll' require 'RSG.Pipeline.Services.dll' require 'Ionic.Zip.Partial.dll' include RSG::Base::Configuration include RSG::Base::Logging include RSG::Base::Logging::Universal include RSG::Base::OS include RSG::Base::Windows include RSG::Pipeline::Core include RSG::Pipeline::Content include RSG::Pipeline::Services require 'mscorlib' require 'System.Core' require 'System.Xml' require 'System.Xml.Linq.dll' include System::Collections::Generic include System::IO include System::Xml::Linq using_clr_extensions System::Linq require 'pipeline/monkey/object' # This gives you Object.to_seq from the 101samples. require 'pipeline/os/options' include Pipeline #----------------------------------------------------------------------------- # Constants #----------------------------------------------------------------------------- AUTHOR = 'RSGEDI Tools' EMAIL = 'RSGEDI Tools <*tools@rockstarnorth.com>' OPTIONS = [ LongOption::new( 'textures', LongOption::ArgType.Required, 'i', 'Directory for textures.' ) ] #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- # Process component zip. def process_zip( branch, log, ped_basename, zip_filename, output_path ) output_path = Path::Combine( output_path, Path::GetFileNameWithoutExtension( zip_filename ) ) filelist = Zip::GetFileList( zip_filename ) result = Zip::ExtractAll( zip_filename, output_path, true, nil ) textures_path = Path::Combine( "x:\\gta5\\assets_japanese\\characters\\textures", ped_basename ) texture_files = Directory::GetFiles( textures_path ) files = texture_files.to_seq files = files.Select( lambda { |f| Path::GetFileNameWithoutExtension( f ) } ) files = files.to_a changed_zip = false puts "#{filelist.class} #{texture_files.Length}" filelist[1].each do |tcl_filename| next unless ( tcl_filename.EndsWith( '.tcl' ) ) # Skip if we don't have texture overridden. tcl_filename = Path::Combine( output_path, tcl_filename ) tcl_basename = Path::GetFileNameWithoutExtension( tcl_filename ) next unless ( files.Contains( tcl_basename ) ) log.Message( "\t\tPatching: #{tcl_basename} #{tcl_filename}." ) changed_zip = true xmldoc = XDocument.Load( tcl_filename ) parent = xmldoc.Element( XName::Get( 'rage__CTextureConversionSpecification' ) ).Element( XName::Get( 'parent' ) ) parent.Value = parent.Value.Replace( '${RS_ASSETS}', 'x:/gta5/assets_japanese' ) xmldoc.Save( tcl_filename ) end if ( not changed_zip ) then log.Message( "Not changing: #{zip_filename}." ) return (false) end # Zip back up. files = [] filelist[1].each do |filename| input_filename = Path::Combine( output_path, filename ) output_filename = filename files << RSG::Base::Collections::Pair[System::String, System::String]::new( input_filename, output_filename ) end System::IO::File::Delete( zip_filename ) Zip::Create( branch, zip_filename, files.to_clr( RSG::Base::Collections::Pair[System::String, System::String] ) ) log.Message( "Created: #{zip_filename}." ) true end # Process .ped.zip def process_pedzip( branch, log, zip_filename, output_path ) output_path = Path::Combine( output_path, Path::GetFileNameWithoutExtension( zip_filename ), 'parts' ) log.Message( "Extract: #{zip_filename} to #{output_path}." ) filelist = Zip::GetFileList( zip_filename ) result = Zip::ExtractAll( zip_filename, output_path, true, nil ) ped_basename = Path::GetFileNameWithoutExtension( Path::GetFileNameWithoutExtension( zip_filename ) ) changed = false filelist[1].each do |zip| next unless ( zip.EndsWith( '.zip' ) ) changed |= process_zip( branch, log, ped_basename, Path::Combine( output_path, zip ), output_path ) end if ( changed ) then log.Message( "Re-create .ped.zip: #{zip_filename}." ) # Zip back up. files = [] filelist[1].each do |filename| input_filename = Path::Combine( output_path, filename ) output_filename = filename files << RSG::Base::Collections::Pair[System::String, System::String]::new( input_filename, output_filename ) end System::IO::File::Delete( zip_filename ) Zip::Create( branch, zip_filename, files.to_clr( RSG::Base::Collections::Pair[System::String, System::String] ) ) log.Message( "Created: #{zip_filename}." ) end end #----------------------------------------------------------------------------- # Entry-Point #----------------------------------------------------------------------------- if ( __FILE__ == $0 ) then # Initialise log and console output. LogFactory.CreateApplicationConsoleLogTarget( ) g_Log = LogFactory.ApplicationLog g_Options = OS::Options::new( OPTIONS ) begin if ( g_Options.is_enabled?( 'help' ) ) puts "#{__FILE__}" puts "Usage:" puts g_Options.usage() exit( 1 ) end g_Config = g_Options.command_options.Config g_Project = g_Options.command_options.Project g_BranchName = g_Options.has_option?( 'branch' ) ? g_Options.get( 'branch' ) : g_Project.DefaultBranchName g_Branch = g_Project.Branches[g_BranchName] if ( g_Project.Branches.ContainsKey( g_BranchName ) ) if ( g_Branch.nil? ) then g_Log.Error( "Invalid branch '#{g_BranchName}' for project '#{g_Project.UIName}'." ) exit( 1 ) end g_TexturesPath = g_Options.has_option?( 'textures' ) g_Filenames = [] g_Options.trailing.each do |filename| g_Filenames << System::IO::Path.GetFullPath( filename ) end g_TempPath = "c:\\temp" g_Filenames = g_Filenames.to_clr( System::String ) g_Filenames.each do |filename| g_Log.Message( "Processing: #{filename}" ) process_pedzip( g_Branch, g_Log, filename, g_TempPath ) end rescue SystemExit => ex # Show Universal Log output on errors. if ( g_Options.show_popups? and 0 != ex.status ) then command = "#{g_Branch.Environment.Subst(ULOG_VIEWER)} #{LogFactory.ProcessLogDirectory}" g_Log.Message( "Displaying Universal Logs: #{command}" ) system( command ) elsif ( g_Options.show_popups? ) then ## DHM; not sure this is neccessary? ## RSG::Pipeline::Services::MessageBox::Show( "Asset build completed successfully." ) end LogFactory.ApplicationShutdown() exit( ex.status ) rescue Exception => ex g_Log.Exception( ex, "Exception during #{__FILE__}." ) puts "Exception during #{__FILE__}: #{ex.message}" puts ex.backtrace.join("\n") if ( g_Options.show_popups? ) then dlg = RSG::Base::Windows::ExceptionStackTraceDlg::new( ex, g_Config.EmailAddress, AUTHOR, EMAIL ) dlg.ShowDialog( ) end exit( 1 ) end end