nwn-lib 0.4.12 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ doc
2
+ pkg
3
+ .yardoc
4
+ Gemfile.lock
@@ -0,0 +1 @@
1
+ --no-private lib/**/*.rb - *.rdoc LICENCE
File without changes
File without changes
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :rubygems
2
+
3
+ # Specify your gem's dependencies in nwn-lib.gemspec
4
+ gemspec
5
+
6
+ gem 'rake', '>= 0.8.7'
7
+
8
+ gem 'rspec', :groups => [:development, :test]
9
+ gem 'yard', :groups => [:development]
File without changes
data/LICENCE ADDED
@@ -0,0 +1,15 @@
1
+ Copyright Bernhard Stoeckner <le@e-ix.net> and contributors. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are
4
+ permitted provided that the following conditions are met:
5
+
6
+ 1. Redistributions of source code must retain the above copyright notice, this list of
7
+ conditions and the following disclaimer.
8
+
9
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
10
+ of conditions and the following disclaimer in the documentation and/or other materials
11
+ provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
14
+ INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15
+ FOR A PARTICULAR PURPOSE.
@@ -31,15 +31,15 @@ They should work with NWN2 just as well, since the file format specifications di
31
31
 
32
32
  ==== Also in the box:
33
33
 
34
- * shell scripts and tools to simplify your life (see BINARIES)
34
+ * shell scripts and tools to simplify your life (see {file:BINARIES})
35
35
  * extensive developer API
36
- * a powerful get-out-of-my-way scripting system for data transformation (see SCRIPTING)
36
+ * a powerful get-out-of-my-way scripting system for data transformation (see {file:SCRIPTING})
37
37
 
38
38
 
39
39
  === Upgrade from 0.3.6 to 0.4.x
40
40
 
41
41
  With the release of 0.4.0, the API changed significantly. Previous yaml dumps made with 0.3.x are INCOMPATIBLE, and so are all scripts.
42
- I can't help you with your API bindings, but for your YAML dumps, a converter script has been provided (see BINARIES).
42
+ I can't help you with your API bindings, but for your YAML dumps, a converter script has been provided (see {file:BINARIES}).
43
43
 
44
44
 
45
45
  === Attention Unicode/UTF-users
@@ -50,25 +50,19 @@ This will be worked around in a future release until the release of ruby 1.9, wh
50
50
 
51
51
  === Quickstart
52
52
 
53
- To use it, simply install the gem (available on rubyforge):
53
+ To use it, simply install the gem:
54
54
 
55
- gem1.8 install nwn-lib
55
+ gem install nwn-lib
56
56
 
57
- And do the following in a script of your own devising:
57
+ And do the following in a script of your own devising (or just use bundler):
58
58
 
59
59
  require 'rubygems'
60
60
  require 'nwn/all'
61
61
 
62
- Also, read BINARIES and HOWTO.
62
+ Also, read {file:BINARIES} and {file:HOWTO}.
63
63
 
64
- For nwn-lib scripts, see SCRIPTING.
64
+ For nwn-lib scripts, see {file:SCRIPTING}.
65
65
 
66
66
  For using the developer API, I suggest you start reading NWN::Gff::Struct.
67
67
 
68
- === Latest code & developer contact
69
-
70
- The latest source is available through git[http://git.swordcoast.net/?p=nwn/nwn-lib.git;a=summary].
71
-
72
- All stable releases are tagged properly.
73
-
74
- You can reach me via email[mailto:elven@swordcoast.net].
68
+ The latest source is available through git[https://github.com/niv/nwn-lib].
data/Rakefile CHANGED
@@ -1,97 +1,8 @@
1
- require "rake"
2
- require "rake/clean"
3
- require "rake/gempackagetask"
4
- require "hanna/rdoctask" rescue require "rake/rdoctask"
5
- require "fileutils"
6
- include FileUtils
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rspec/core/rake_task'
4
+ require 'yard'
7
5
 
8
- ##############################################################################
9
- # Configuration
10
- ##############################################################################
11
- NAME = "nwn-lib"
12
- VERS = "0.4.12"
13
- CLEAN.include ["**/.*.sw?", "pkg", ".config", "rdoc", "coverage"]
14
- RDOC_OPTS = ["--quiet", "--line-numbers", "--inline-source", '--title', \
15
- 'nwn-lib: a ruby library for accessing NWN resource files', \
16
- '--main', 'README']
6
+ YARD::Rake::YardocTask.new
17
7
 
18
- DOCS = ["README", "BINARIES", "HOWTO", "SCRIPTING", "SETTINGS", "CHEATSHEET", "CHANGELOG", "COPYING"]
19
-
20
- Rake::RDocTask.new do |rdoc|
21
- rdoc.rdoc_dir = "rdoc"
22
- rdoc.options += RDOC_OPTS
23
- rdoc.rdoc_files.add DOCS + ["doc/*.rdoc", "lib/**/*.rb"]
24
- end
25
-
26
- desc "Packages up nwn-lib"
27
- task :package => [:clean]
28
-
29
- spec = Gem::Specification.new do |s|
30
- s.name = NAME
31
- s.rubyforge_project = 'nwn-lib'
32
- s.version = VERS
33
- s.platform = Gem::Platform::RUBY
34
- s.has_rdoc = true
35
- s.extra_rdoc_files = DOCS + Dir["doc/*.rdoc"]
36
- s.rdoc_options += RDOC_OPTS + ["--exclude", "^(examples|extras)\/"]
37
- s.summary = "a ruby library for accessing Neverwinter Nights resource files"
38
- s.description = s.summary
39
- s.author = "Bernhard Stoeckner"
40
- s.email = "elven@swordcoast.net"
41
- s.homepage = "http://nwn-lib.elv.es"
42
- s.executables = ["nwn-gff", "nwn-erf", "nwn-dsl", "nwn-irb"]
43
- s.required_ruby_version = ">= 1.8.4"
44
- s.files = %w(COPYING CHANGELOG README Rakefile) + Dir.glob("{bin,doc,spec,lib,tools,scripts,data}/**/*")
45
- s.require_path = "lib"
46
- s.bindir = "bin"
47
- end
48
-
49
- Rake::GemPackageTask.new(spec) do |p|
50
- p.need_tar = true
51
- p.gem_spec = spec
52
- end
53
-
54
- desc "Install nwn-lib gem"
55
- task :install do
56
- sh %{rake package}
57
- sh %{sudo gem1.8 install pkg/#{NAME}-#{VERS}}
58
- end
59
-
60
- desc "Install nwn-lib gem without docs"
61
- task :install_no_docs do
62
- sh %{rake package}
63
- sh %{sudo gem1.8 install pkg/#{NAME}-#{VERS} --no-rdoc --no-ri}
64
- end
65
-
66
- desc "Uninstall nwn-lib gem"
67
- task :uninstall => [:clean] do
68
- sh %{sudo gem1.8 uninstall #{NAME}}
69
- end
70
-
71
- require "spec/rake/spectask"
72
-
73
- desc "Run specs with coverage"
74
- Spec::Rake::SpecTask.new("spec") do |t|
75
- t.spec_files = FileList["spec/*_spec.rb"]
76
- t.spec_opts = ["--format s"]
77
- t.rcov = true
78
- end
79
-
80
- desc "Run specs without coverage"
81
- task :default => [:spec_no_cov]
82
- Spec::Rake::SpecTask.new("spec_no_cov") do |t|
83
- t.spec_files = FileList["spec/*_spec.rb"]
84
- t.spec_opts = ["--format s"]
85
- end
86
-
87
- desc "Run rcov only"
88
- Spec::Rake::SpecTask.new("rcov") do |t|
89
- t.spec_files = FileList["spec/*_spec.rb"]
90
- t.spec_opts = ["--format s"]
91
- t.rcov = true
92
- end
93
-
94
- desc "check documentation coverage"
95
- task :dcov do
96
- sh "find lib -name '*.rb' | xargs dcov"
97
- end
8
+ RSpec::Core::RakeTask.new(:spec)
File without changes
File without changes
@@ -164,7 +164,7 @@ case $action
164
164
  puts File.basename(a) if $verbose
165
165
  raise ArgumentError, "#{File.basename(a)} already present in erf." if
166
166
  !$allow_duplicates && erf.has?(a)
167
- erf.add_file a
167
+ erf.add_file File.basename(a), File.open(a, "r")
168
168
  }
169
169
  output {|f| erf.write_to(f) }
170
170
 
@@ -181,7 +181,7 @@ case $action
181
181
  when :a
182
182
  raise ArgumentError, "#{File.basename(arg)} already present in erf." if
183
183
  !$allow_duplicates && erf.has?(arg)
184
- erf.add_file arg
184
+ erf.add_file File.basename(arg), File.open(arg, "r")
185
185
 
186
186
  when :r
187
187
  erf.content.reject! {|con|
@@ -1,4 +1,5 @@
1
1
  require 'stringio'
2
+ require 'nwn/version'
2
3
  require 'nwn/io'
3
4
  require 'nwn/twoda'
4
5
  require 'nwn/settings'
@@ -133,12 +133,12 @@ module NWN
133
133
  [c.resref, @content.index(c), c.res_type, 0].pack("a#{fnlen} V v v")
134
134
  }.join("")
135
135
 
136
- pre_offset = 160 + locstr.size + keylist.size + 8 * @content.size
136
+ offset = 160 + locstr.size + keylist.size + 8 * @content.size
137
137
 
138
138
  reslist = @content.map {|c|
139
- offset = pre_offset +
140
- @content[0, @content.index(c)].inject(0) {|sum,x| sum + x.size }
141
- [offset, c.size].pack("V V")
139
+ r = [offset, c.size].pack("V V")
140
+ offset += c.size
141
+ r
142
142
  }.join("")
143
143
 
144
144
  offset_to_locstr = 160
@@ -124,7 +124,7 @@ module NWN
124
124
  extension = File.extname(filename.downcase)[1..-1]
125
125
  matches = FileFormatGuesses.select {|fmt,rx| extension =~ rx }
126
126
  if matches.size == 1
127
- matches[0][0]
127
+ matches.keys[0]
128
128
  else
129
129
  nil
130
130
  end
@@ -103,10 +103,11 @@ module NWN::Gff::Field
103
103
  return if field_type == :struct
104
104
 
105
105
  field_klass_name = field_type.to_s.capitalize
106
- field_klass = NWN::Gff.const_defined?(field_klass_name) ?
107
- NWN::Gff.const_get(field_klass_name) : nil
108
- field_value_klass = NWN::Gff.const_defined?(field_klass_name + 'Value') ?
109
- NWN::Gff.const_get(field_klass_name + 'Value') : nil
106
+
107
+ field_klass = NWN::Gff.const_defined?(field_klass_name, false) ?
108
+ NWN::Gff.const_get(field_klass_name, false) : nil
109
+ field_value_klass = NWN::Gff.const_defined?(field_klass_name + 'Value', false) ?
110
+ NWN::Gff.const_get(field_klass_name + 'Value', false) : nil
110
111
 
111
112
  self.extend(field_klass) unless field_klass.nil? ||
112
113
  self.is_a?(field_klass)
@@ -227,15 +228,24 @@ module NWN::Gff::Field
227
228
  element.extend_meta_classes
228
229
  case element.field_type
229
230
  when :cexolocstr
231
+ mod = {}
230
232
  element.field_value.each {|x,y|
231
- element.field_value[x.to_i] = NWN.iconv_native_to_gff(element.field_value.delete(x))
233
+ mod[x] = NWN.iconv_native_to_gff(y)
234
+ }
235
+ mod.each {|x,y|
236
+ element.field_value.delete(x)
237
+ element.field_value[x.to_i] = y
232
238
  }
233
239
  when :cexostr
234
240
  element.field_value = NWN.iconv_native_to_gff(element.field_value)
235
241
 
236
242
  when :list
243
+ mod = {}
237
244
  element.field_value.each_with_index {|x,idx|
238
- element.field_value[idx] = NWN::Gff::Struct.unbox!(x, element)
245
+ mod[idx] = NWN::Gff::Struct.unbox!(x, element)
246
+ }
247
+ mod.each {|x,y|
248
+ element.field_value[x] = y
239
249
  }
240
250
  when :struct
241
251
  element.field_value = NWN::Gff::Struct.unbox!(element.field_value, element)
@@ -47,6 +47,7 @@ class NWN::Gff::Reader
47
47
  @io.seek(label_offset)
48
48
  @labels = @io.e_read(label_len, "labels")
49
49
  @labels = @labels.unpack("A16" * label_count)
50
+ @labels.map! {|l| l.encode("ASCII") }
50
51
 
51
52
  @io.seek(field_data_offset)
52
53
  @field_data = @io.e_read(field_data_count, "field_data")
@@ -74,6 +75,9 @@ class NWN::Gff::Reader
74
75
  raise GffError, "struct index #{index} outside of struct_array" if
75
76
  index * 3 + 3 > @structs.size + 1
76
77
 
78
+ file_type = file_type.encode('ASCII') if file_type
79
+ file_version = file_version.encode('ASCII') if file_version
80
+
77
81
  struct.struct_id = type
78
82
  struct.data_type = file_type
79
83
  struct.data_version = file_version
@@ -155,11 +159,11 @@ class NWN::Gff::Reader
155
159
 
156
160
  when :cexostr
157
161
  len = @field_data[data_or_offset, 4].unpack("V")[0]
158
- @field_data[data_or_offset + 4, len]
162
+ @field_data[data_or_offset + 4, len].encode(NWN.setting :in_encoding)
159
163
 
160
164
  when :resref
161
165
  len = @field_data[data_or_offset, 1].unpack("C")[0]
162
- @field_data[data_or_offset + 1, len]
166
+ @field_data[data_or_offset + 1, len].encode(NWN.setting :in_encoding)
163
167
 
164
168
  when :cexolocstr
165
169
  exostr = {}
@@ -172,7 +176,7 @@ class NWN::Gff::Reader
172
176
 
173
177
  str_count.times {
174
178
  id, len = all.unpack("VV")
175
- str = all[8, len].unpack("a*")[0]
179
+ str = all[8, len].unpack("a*")[0].encode(NWN.setting :in_encoding)
176
180
  all = all[(8 + len)..-1]
177
181
  exostr[id] = str
178
182
  }
@@ -181,7 +185,7 @@ class NWN::Gff::Reader
181
185
 
182
186
  when :void
183
187
  len = @field_data[data_or_offset, 4].unpack("V")[0]
184
- @field_data[data_or_offset + 4, len].unpack("H*")[0]
188
+ @field_data[data_or_offset + 4, len].unpack("a*")[0]
185
189
 
186
190
  when :struct
187
191
  read_struct data_or_offset, nil, field.parent.data_version
@@ -19,7 +19,7 @@ module NWN::Gff::Struct
19
19
  attr_reader :element
20
20
 
21
21
  def path
22
- if @element
22
+ if defined?(@element) && !@element.nil?
23
23
  @element.path
24
24
  else
25
25
  "/"
@@ -41,13 +41,15 @@ module NWN::Gff::Struct
41
41
  # Overrides the data type (used by the built-in file format readers).
42
42
  def data_type= k
43
43
  k = nil if k == ""
44
- NWN.log_debug("Setting explicit data_type for parented element") if k && @element
44
+ NWN.log_debug("Setting explicit data_type for parented element") if k &&
45
+ defined?(@element) && !@element.nil?
45
46
  @data_type = k
46
47
  end
47
48
 
48
49
  def element= e #:nodoc:
49
50
  @element = e
50
- NWN.log_debug("Re-parenting a struct with explicit data_type #{@data_type.inspect}") if e && @data_type
51
+ NWN.log_debug("Re-parenting a struct with explicit data_type #{@data_type.inspect}") if !e.nil? &&
52
+ defined?(@data_type) && !@data_type.nil?
51
53
  end
52
54
 
53
55
  # Dump this struct as GFF binary data.
@@ -106,7 +108,7 @@ module NWN::Gff::Struct
106
108
 
107
109
  def method_missing meth, *av, &block # :nodoc:
108
110
  if meth.to_s =~ /^add_(.+)$/
109
- if NWN::Gff::Types.index($1.to_sym)
111
+ if NWN::Gff::Types.key($1.to_sym)
110
112
  av.size >= 1 || av.size <= 2 or raise(NoMethodError,
111
113
  "undefined method #{meth} (requires two arguments to infer add_any)")
112
114
  t = $1.to_sym
@@ -42,7 +42,7 @@ private
42
42
 
43
43
  def add_data_field type, label, content
44
44
  label_id = get_label_id_for_label label
45
- @fields.push Types.index(type), label_id, content
45
+ @fields.push Types.key(type), label_id, content
46
46
  (@fields.size - 1) / 3
47
47
  end
48
48
 
@@ -129,7 +129,7 @@ private
129
129
  v.field_value % (2**32)
130
130
  ].pack("II")
131
131
  when :void
132
- [ v.field_value.size / 2, v.field_value ].pack("VH*")
132
+ [ v.field_value.size, v.field_value ].pack("Va*")
133
133
  else
134
134
  [v.field_value].pack(format)
135
135
  end
@@ -87,8 +87,8 @@ module NWN
87
87
  size, name_offset, name_size, drives = x.unpack("VVvv")
88
88
  io.seek(name_offset)
89
89
  name = io.e_read(name_size, "name table").unpack("A*")[0]
90
- name.gsub!("\\", "/")
91
- name = File.expand_path(@root + "/" + name)
90
+ name.gsub!("\\", File::SEPARATOR)
91
+ name = File.expand_path(@root + File::SEPARATOR + name)
92
92
 
93
93
  _io = File.new(name, "r")
94
94
  @bif << Bif.new(self, _io)
@@ -50,6 +50,8 @@ module NWN::Gff::Handler::Kivinen
50
50
  yield(path + "/", path)
51
51
  yield(path + "/ ____struct_type", field.field_value.struct_id)
52
52
  when :cexolocstr
53
+ when :void
54
+ yield(path, field.field_value.unpack("H*")[0])
53
55
  else
54
56
  yield(path, field.field_value)
55
57
  end
@@ -57,7 +59,7 @@ module NWN::Gff::Handler::Kivinen
57
59
  yield(path + ". ____string_ref",field.str_ref) if
58
60
  field.has_str_ref? || field.field_type == :cexolocstr
59
61
 
60
- yield(path + ". ____type", NWN::Gff::Types.index(field.field_type)) if
62
+ yield(path + ". ____type", NWN::Gff::Types.key(field.field_type)) if
61
63
  types_too
62
64
 
63
65
  end
@@ -55,7 +55,7 @@ module NWN
55
55
 
56
56
  # Get the extension of this object.
57
57
  def extension
58
- NWN::Resources::Extensions.index(@res_type)
58
+ NWN::Resources::Extensions.key(@res_type)
59
59
  end
60
60
  end
61
61
 
@@ -115,7 +115,7 @@ module NWN
115
115
  def initialize path
116
116
  super()
117
117
  @path = path
118
- Dir[path + "/*.*"].each {|x|
118
+ Dir[path + File::SEPARATOR + "*.*"].each {|x|
119
119
  begin add_file x
120
120
  rescue ArgumentError => e
121
121
  NWN.log_debug e.to_s