diff --git a/lib/mikunyan/asset.rb b/lib/mikunyan/asset.rb index 72a7f6f..5e32a21 100644 --- a/lib/mikunyan/asset.rb +++ b/lib/mikunyan/asset.rb @@ -10,7 +10,7 @@ module Mikunyan # @attr_reader [Array] add_ids ? # @attr_reader [Array] references reference data class Asset - attr_reader :name, :format, :generator_version, :target_platform, :endian, :klasses, :objects, :add_ids, :references + attr_reader :name, :format, :generator_version, :target_platform, :endian, :klasses, :objects, :add_ids, :references, :res_s # Struct for representing Asset class definition # @attr [Integer] class_id class ID @@ -40,9 +40,10 @@ module Mikunyan # Load Asset from binary string # @param [String] bin binary data # @param [String] name Asset name + # @param [String] res_s resS data # @return [Mikunyan::Asset] deserialized Asset object - def self.load(bin, name) - r = Asset.new(name) + def self.load(bin, name, res_s = nil) + r = Asset.new(name, res_s) r.send(:load, bin) r end @@ -123,9 +124,10 @@ module Mikunyan private - def initialize(name) + def initialize(name, res_s = nil) @name = name @endian = :big + @res_s = res_s end def load(bin) @@ -245,6 +247,9 @@ module Mikunyan else r.value = parse_object_private(br, children[0]).value end + elsif node.type == 'StreamingInfo' + children.each{|child| r[child[:name]] = parse_object_private(br, child)} + r.value = @res_s.byteslice(r['offset'].value, r['size'].value) if r['path'].value == "archive:/#{name}/#{name}.resS" else children.each do |child| r[child[:name]] = parse_object_private(br, child) diff --git a/lib/mikunyan/asset_bundle.rb b/lib/mikunyan/asset_bundle.rb index 97899ee..60b54fc 100644 --- a/lib/mikunyan/asset_bundle.rb +++ b/lib/mikunyan/asset_bundle.rb @@ -84,11 +84,13 @@ module Mikunyan asset_count = head.i32u asset_count.times{ asset_blocks << {:offset => head.i64u, :size => head.i64u, :status => head.i32, :name => head.cstr} } - raw_data = '' + raw_data = String.new blocks.each{|b| raw_data << uncompress(br.read(b[:c]), b[:u], b[:f])} asset_blocks.each do |b| - asset = Asset.load(raw_data.byteslice(b[:offset], b[:size]), b[:name]) + next if b[:name].end_with?('.resS') + res_s = asset_blocks.find{|e| e[:name] == "#{b[:name]}.resS"} + asset = Asset.load(raw_data.byteslice(b[:offset], b[:size]), b[:name], res_s && raw_data.byteslice(res_s[:offset], res_s[:size])) @assets << asset end end diff --git a/lib/mikunyan/decoders/image_decoder.rb b/lib/mikunyan/decoders/image_decoder.rb index 105736b..fb2949f 100644 --- a/lib/mikunyan/decoders/image_decoder.rb +++ b/lib/mikunyan/decoders/image_decoder.rb @@ -23,6 +23,11 @@ module Mikunyan bin = bin.value fmt = fmt.value + if bin.size == 0 && object['m_StreamData'] + bin = object['m_StreamData'].value + return nil unless bin + end + case fmt when 1 decode_a8(width, height, bin) diff --git a/lib/mikunyan/type_tree.rb b/lib/mikunyan/type_tree.rb index 4ea2d01..d0ad4ad 100644 --- a/lib/mikunyan/type_tree.rb +++ b/lib/mikunyan/type_tree.rb @@ -22,7 +22,8 @@ module Mikunyan node_count = br.i32u buffer_size = br.i32u node_count.times do - nodes << Node.new(br.i16u, br.i8u, br.i8u != 0, br.i32, br.i32, br.i32, br.i32u, br.i32u) + node = Node.new(br.i16u, br.i8u, br.i8u != 0, br.i32, br.i32, br.i32, br.i32u, br.i32u) + nodes << node end buffer = br.read(buffer_size) nodes.each do |n|