class Gnosis::Translators::RGSS3A
Provides a translator for RGSS3A
encrypted archives as used by RPG Maker VX Ace. This class provides the implementation-specific {#scan_files} method as used by an {Archive Archive} instance.
Public Class Methods
@raise [InvalidArchiveError] if the parent object’s archive is not a
valid RGSS3A encrypted archive
@param [Archive] parent the archive which contains this translator
# File lib/gnosis/translators/rgss3a.rb, line 14 def initialize(parent) unless File.read(parent.archive, 8).unpack('a6U*').join == 'RGSSAD03' raise InvalidArchiveError, parent.archive end @parent = parent end
Public Instance Methods
Builds a hash of file information stored in an encrypted archive. Keys are filenames, values contain a hash of information regarding file encryption (namely its position in the archive, size in bytes, and the subkey needed to decrypt the file).
@return [Hash{String => Hash{Symbol => Number}}] a hash of files with
associated encryption information
# File lib/gnosis/translators/rgss3a.rb, line 28 def scan_files hash = {} File.open(@parent.archive) do |archive| archive.seek(8) # Skip archive version information. key = (archive.read(4).unpack('V').first * 9 + 3) & 0xFFFFFFFF loop do info = archive.read(16).unpack('V4').map { |i| i ^ key } break if info.first.zero? file = translate_file(archive.read(info[3]), key) hash[file] = { position: info[0], size: info[1], subkey: info[2] } end end hash end
Private Instance Methods
Translates an encrypted binary filename within the archive to a UTF-8 string.
@param [String] bytes string of encrypted bytes @param [Number] key subkey used to decrypt the given bytes @return [String] a decrypted UTF-8 string
# File lib/gnosis/translators/rgss3a.rb, line 50 def translate_file(bytes, key) bytes.scan(/.{1,4}/m).map! do |word| [word.ljust(4, "\x00").unpack('V')[0] ^ key].pack('V')[0...word.size] end.join.force_encoding('utf-8').gsub!(/\\/, '/') end
Overwrite of {RGSSAD#translate_int} to raise a ‘NotImplementedError`, as RGSS3A
archives do not make use of this method.
@param [String] bytes string of encrypted bytes @raise [NotImplementedError] if called
# File lib/gnosis/translators/rgss3a.rb, line 61 def translate_int(bytes) raise NotImplementedError, 'RGSS3A archives do not use encrypted ints' end