Class NWN::Key::Key

  1. lib/nwn/key.rb

Methods

public class

  1. new

Attributes

bif [R] An array of Bif objects contained in this key index. Not needed to access individual files, use Container#content instead.
day_of_year [R]
file_type [R]
file_version [R]
year [R]

Public class methods

new (io, data_path)

Creates a new Key wrapper. The parameters exepected are an IO object pointing to the .key-file, and the base path in which your data/.bif files can be found. (This is usually your NWN directory, NOT the data/ directory).

[show source]
# File lib/nwn/key.rb, line 67
      def initialize io, data_path
        super()

        @root = data_path
        @bif = []

        @file_type, @file_version,
          bif_count, key_count,
          offset_to_file_table, offset_to_key_table,
          @year, @day_of_year, reserved =
          io.e_read(8 + (4 * 6) + 32, "header").unpack("A4 A4 VVVVVV a32")

        io.seek(offset_to_file_table)
        data = io.e_read(12 * bif_count, "bif data")

        # Contains all bifs linked in this key
        i = 0
        @file_table = []
        while (x = data[i, 12]) && x.size == 12
          i += 12
          size, name_offset, name_size, drives = x.unpack("VVvv")
          io.seek(name_offset)
          name = io.e_read(name_size, "name table").unpack("A*")[0]
          name.gsub!("\\", File::SEPARATOR)
          name = File.expand_path(@root + File::SEPARATOR + name)

          _io = File.new(name, "r")
          @bif << Bif.new(self, _io)

          @file_table << [size, name, drives]
        end

        @key_table = {}
        io.seek(offset_to_key_table)
        data = io.e_read(22 * key_count, "key table")
        i = 0
        while (x = data[i, 22]) && x.size == 22
          i += 22
          resref, res_type, res_id = x.unpack("A16 v V")
          @key_table[res_id] = [resref, res_type]
        end

        @fn_to_co = {}
        @key_table.each {|res_id, (resref, res_type)|
          bif_index = res_id >> 20
          bif = @bif[bif_index]
          id = res_id & 0xfffff
          bif.contained[id] or fail "#{bif} does not have #{id}"
          ofs, sz, _rt = bif.contained[id]
          o = NWN::Resources::ContentObject.new(resref, res_type, bif.io, ofs, sz)
          if @fn_to_co[o.filename] && @fn_to_co[o.filename][2] < bif_index
            oo, biff = @fn_to_co[o.filename]
            NWN.log_debug "#{o.filename} in #{biff.io.inspect} shadowed by file of same name in #{bif.io.inspect}"
            @content.delete(oo)
          end
          @fn_to_co[o.filename] = [o, bif, bif_index]
          @content << o
        }
      end