238 lines
8.6 KiB
Ruby
Executable File
238 lines
8.6 KiB
Ruby
Executable File
#
|
|
# File:: dlc_global_sig_checker.rb
|
|
# Description:: Checks that DLC scripts only use certain global blocks.
|
|
# Checks all .global_block.txt files against a text file of hashes for global blocks
|
|
# If the text file specifies a hash value for a global block then all .global_block.txt files that list that global block must have that exact hash value
|
|
# If the text file has a hash of 0 for a global block then the .global_block.txt files don't have to have a specific hash value. The hash should still be the same across all .global_block.txt files,
|
|
# but that value doesn't have to match a value specified in the text file.
|
|
# If the text file doesn't list a global block index then the .global_block.txt files can't contain that global block
|
|
|
|
# Author:: Graeme Williamson - copied from Derek Ward's global_sig_checker.rb
|
|
# Date:: 15 January 2014
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
|
|
require 'RSG.Base.Configuration.dll'
|
|
require 'RSG.Base.dll'
|
|
require 'System.Core'
|
|
require 'mscorlib'
|
|
require 'RSG.Pipeline.Core.dll'
|
|
|
|
require 'RSG.Base.Windows.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
|
|
require 'pipeline/os/options'
|
|
include Pipeline
|
|
|
|
require 'fileutils'
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Constants
|
|
#-----------------------------------------------------------------------------
|
|
AUTHOR = 'RSGEDI Tools'
|
|
EMAIL = 'RSGEDI Tools <*tools@rockstarnorth.com>'
|
|
OPTIONS = [
|
|
LongOption::new( 'source_folder', LongOption::ArgType.Required, 's', 'source_folder' ),
|
|
LongOption::new( 'text_file', LongOption::ArgType.Required, 't', 'text_file' ),
|
|
LongOption::new( 'wildcard', LongOption::ArgType.Required, 'w', 'wildcard' ),
|
|
LongOption::new( 'email', LongOption::ArgType.Required, 'e', 'email' ),
|
|
]
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Functions
|
|
#-----------------------------------------------------------------------------
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Entry-Point
|
|
#-----------------------------------------------------------------------------
|
|
|
|
if ( __FILE__ == $0 ) then
|
|
|
|
puts "#{$0} #{$*}"
|
|
hdr = "INFO_MSG: "
|
|
|
|
g_Options = OS::Options::new( OPTIONS )
|
|
|
|
begin
|
|
|
|
retcode = 0
|
|
|
|
if ( g_Options.is_enabled?( 'help' ) )
|
|
puts "#{__FILE__}"
|
|
puts "Usage:"
|
|
puts g_Options.usage()
|
|
exit( 1 )
|
|
end
|
|
|
|
LogFactory.CreateApplicationConsoleLogTarget( )
|
|
g_Log = LogFactory.CreateUniversalLog("dlc_global_sig_checker")
|
|
g_LogFile = LogFactory.CreateUniversalLogFile("dlc_global_sig_checker", g_Log) # as UniversalLogFile
|
|
|
|
g_Config = RSG::Base::Configuration::ConfigFactory::CreateConfig( )
|
|
|
|
source_folder = g_Options.get( 'source_folder' ) unless g_Options.get( 'source_folder' ).nil?
|
|
|
|
text_file = g_Options.get( 'text_file' ) unless g_Options.get( 'text_file' ).nil?
|
|
wildcard = g_Options.get( 'wildcard' ) unless g_Options.get( 'wildcard' ).nil?
|
|
email = g_Options.get( 'email' ) unless g_Options.get( 'email' ).nil?
|
|
|
|
g_Log.Message("#{hdr} ")
|
|
g_Log.Message("#{hdr}************************")
|
|
g_Log.Message("#{hdr}*** DlcGlobalSigChecker ***")
|
|
g_Log.Message("#{hdr}************************")
|
|
g_Log.Message("#{hdr} ")
|
|
g_Log.Message("#{hdr}Source folder : #{source_folder}")
|
|
g_Log.Message("#{hdr}Text file : #{text_file}")
|
|
g_Log.Message("#{hdr}Wildcard : #{wildcard}");
|
|
g_Log.Message("#{hdr} ")
|
|
|
|
if (!File.exist?(text_file))
|
|
g_Log.Warning("text file doesn't exist #{text_file}" )
|
|
exit ( 0 )
|
|
end
|
|
|
|
regex = /^\s*(\d*)\s*=\s*(\d*)\s*$/i
|
|
|
|
expected_block_hash = {}
|
|
|
|
File.open(text_file) do |textfile|
|
|
textfile.each_line do |line|
|
|
|
|
# eg.
|
|
# 0=2357115215,5=2198626599,10=0
|
|
|
|
entries = line.split(',')
|
|
|
|
entries.each do |entry|
|
|
if (entry=~regex)
|
|
block_idx = $1
|
|
block_hash_value = $2
|
|
if expected_block_hash.key?(block_idx)
|
|
g_Log.Error("#{hdr}\t\tText file #{text_file} contains more than one entry for global index #{block_idx}")
|
|
else
|
|
expected_block_hash[block_idx] = block_hash_value
|
|
g_Log.Message("\tEstablished block hash \t#{block_idx} = #{block_hash_value}\t from text file #{text_file}")
|
|
end
|
|
else
|
|
g_Log.Message("\t\t?Unexpected entry when reading from text file #{text_file} : #{entry}")
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
|
|
if (!File.directory? source_folder)
|
|
g_Log.Warning("directory doesnt exist #{source_folder}" )
|
|
exit ( 0 )
|
|
end
|
|
|
|
|
|
|
|
files = System::IO::Directory.GetFiles(source_folder, wildcard)
|
|
if (files == nil || files.Length==0)
|
|
g_Log.Warning("no files found in #{source_folder}" )
|
|
exit ( 0 )
|
|
end
|
|
|
|
num_files = files.size
|
|
g_Log.Message("#{hdr}------ Checking #{num_files} files --------")
|
|
|
|
|
|
inconsistencies = 0
|
|
files.each do |filename|
|
|
short_filename = File.basename(filename)
|
|
File.open(filename) do |file|
|
|
file.each_line do |line|
|
|
|
|
# eg.
|
|
# x:\Barry1,0=4260798006,1=3808128351,3=3921368841,4=3624207664,5=340217310,6=1588498831,8=2978757849,9=3874559245
|
|
|
|
entries = line.split(',')
|
|
line_filename = entries.shift
|
|
|
|
entries.each do |entry|
|
|
if (entry=~regex)
|
|
block_idx = $1
|
|
block_hash_value = $2
|
|
if expected_block_hash.key?(block_idx)
|
|
expected_value = expected_block_hash[block_idx]
|
|
if (expected_value != "0") && (expected_value != block_hash_value)
|
|
g_Log.Error("#{hdr}\t\t Hash #{block_hash_value} for global block #{block_idx} in #{short_filename}(#{line_filename}) doesn't match with the expected value #{expected_value} in #{text_file}")
|
|
inconsistencies += 1
|
|
end
|
|
else
|
|
g_Log.Error("#{hdr}\t\t #{short_filename}(#{line_filename}) can't use variables in global block #{block_idx}. That block is not listed in #{text_file}")
|
|
inconsistencies += 1
|
|
end
|
|
else
|
|
g_Log.Message("\t\t?Unexpected entry : #{entry} when reading from #{short_filename}(#{line_filename})")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
g_Log.Message("#{hdr}-------------------------------")
|
|
g_Log.Message("#{hdr} ")
|
|
g_Log.Message("#{hdr}---------- Summary ------------")
|
|
g_Log.Message("#{hdr}Checked files : #{num_files}")
|
|
g_Log.Message("#{hdr}Inconsistencies : #{inconsistencies}")
|
|
g_Log.Message("#{hdr}-------------------------------")
|
|
g_Log.Message("#{hdr} ")
|
|
|
|
retcode = -1 if (inconsistencies>0)
|
|
|
|
if (email=="true" && retcode == -1)
|
|
g_Log.Error("Flushing logfile with error, retcode is #{retcode}")
|
|
subject = "DLC Global Sig Differences detected in #{source_folder}\\#{wildcard}"
|
|
body = "See attached log file"
|
|
recipients = []
|
|
#recipients << "graeme.williamson@rockstarnorth.com"
|
|
#recipients << "ben.rollinson@rockstarnorth.com"
|
|
recipients << "derek.ward@rockstarnorth.com"
|
|
recipients << "liam.anderson@rockstarnorth.com"
|
|
|
|
g_Log.Message("Sending Email : {0} : {1}", subject, recipients.join(","))
|
|
|
|
recipients = recipients.to_clr( System::String )
|
|
attachments = [System::Net::Mail::Attachment.new(g_LogFile.Filename)]
|
|
attachments = attachments.to_clr( System::Net::Mail::Attachment )
|
|
RSG::Base::Configuration::Email::Email.SendEmail(g_Config, recipients, subject, body, attachments)
|
|
end
|
|
|
|
g_Log.Message("#{hdr}dlc_global_sig_checker exiting with #{retcode}")
|
|
exit retcode
|
|
|
|
rescue SystemExit => sex
|
|
|
|
LogFactory.ApplicationShutdown()
|
|
exit( sex.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
|
|
|
|
# dlc_global_sig_checker.rb
|