nwn-lib 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6039060ff0d0c726c6b7fa44dd7be8c624c3cf98
4
+ data.tar.gz: 82b2a9eea724b7d9b5b52a254d3b672b126affe8
5
+ SHA512:
6
+ metadata.gz: 2288b34809225b00cb6b95c26a4d2360c31c8360d045ef8cbf5b69341cff2936d7f01aeeced4fa6e9ebbfad313578cfad7459da4f4896b4d0d6b042d888c66b5
7
+ data.tar.gz: 69c551f0f7e19d64a2bbed798d10f75a8c8b6c78df91b7103a6759cd1fb34cc47fd22020042883e655c9eb283bb24aabef57848d694ab1e72e5481d6a178dd95
data/.gitignore CHANGED
@@ -1,4 +1,4 @@
1
- doc
2
- pkg
3
- .yardoc
4
- Gemfile.lock
1
+ /doc/
2
+ /pkg/
3
+ /.yardoc/
4
+ /Gemfile.lock
data/Gemfile CHANGED
@@ -1,9 +1,12 @@
1
- source :rubygems
1
+ source 'https://rubygems.org/'
2
2
 
3
3
  # Specify your gem's dependencies in nwn-lib.gemspec
4
4
  gemspec
5
5
 
6
6
  gem 'rake', '>= 0.8.7'
7
7
 
8
+ gem 'json', :group => :json
9
+ gem 'libxml-ruby', :group => :xml
10
+
8
11
  gem 'rspec', :groups => [:development, :test]
9
12
  gem 'yard', :groups => [:development]
@@ -1,13 +1,16 @@
1
1
  == A library for Neverwinter Nights 1/2 resource files
2
2
 
3
- This package provides a library for reading, changing, and writing common file formats that are found with NWN[http://nwn.bioware.com/], a Bioware game.
3
+ This package provides a library for reading, changing, and writing common file
4
+ formats that are found with NWN[http://nwn.bioware.com/], a Bioware game.
4
5
 
5
- They should work with NWN2 just as well, since the file format specifications did not change.
6
+ They should work with NWN2 just as well, since the file format specifications
7
+ did not change.
6
8
 
7
9
 
8
10
  === Features of nwn-lib
9
11
 
10
- ==== nwn-lib reads and writes the following file formats (hopefully bug-free!), both with an API and useful command-line tools:
12
+ ==== nwn-lib reads and writes the following file formats (hopefully bug-free!),
13
+ both with an API and useful command-line tools:
11
14
 
12
15
  * GFF 3.2 (are, git, gic, dlg, itp, ifo, jrl, fac, ssf, ut*, among others)
13
16
  * ERF (mod, hak, erf, among others)
@@ -31,36 +34,39 @@ They should work with NWN2 just as well, since the file format specifications di
31
34
 
32
35
  ==== Also in the box:
33
36
 
34
- * shell scripts and tools to simplify your life (see {file:BINARIES})
37
+ * shell scripts and tools to simplify your life (see BINARIES)
35
38
  * extensive developer API
36
- * a powerful get-out-of-my-way scripting system for data transformation (see {file:SCRIPTING})
39
+ * a powerful get-out-of-my-way scripting system for data transformation (see SCRIPTING)
37
40
 
38
41
 
39
42
  === Upgrade from 0.3.6 to 0.4.x
40
43
 
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 {file:BINARIES}).
44
+ With the release of 0.4.0, the API changed significantly. Previous yaml dumps
45
+ made with 0.3.x are INCOMPATIBLE, and so are all scripts.
46
+ I can't help you with your API bindings, but for your YAML dumps, a converter
47
+ script has been provided (see BINARIES).
43
48
 
44
49
 
45
50
  === Upgrade from 0.4.x to 0.5.x
46
51
 
47
- All with version 0.4.x produced files should be compatible with 0.5.0. Your application might require some porting to ruby 1.9.
52
+ All with version 0.4.x produced files should be compatible with 0.5.0.
53
+ Your application might require some porting to ruby 1.9.
48
54
 
55
+ === Upgrade from 0.5.x to 0.6.x
49
56
 
50
- === Quickstart
51
-
52
- To use it, simply install the gem:
57
+ YAML dumps will need to be converted due to the internal parser/generator used
58
+ by ruby being replaced (syck to psych).
59
+ There is a converter packaged in tools/ along with the gem distribution.
53
60
 
54
- gem install nwn-lib
61
+ === Quickstart
55
62
 
56
- And do the following in a script of your own devising (or just use bundler):
63
+ To use it, simply add the following to your Gemfile:
57
64
 
58
- require 'rubygems'
59
- require 'nwn/all'
65
+ gem 'nwn-lib'
60
66
 
61
- Also, read {file:BINARIES} and {file:HOWTO}.
67
+ Also, read BINARIES for the packaged executable scripts, and HOWTO.
62
68
 
63
- For nwn-lib scripts, see {file:SCRIPTING}.
69
+ For nwn-lib scripts, see SCRIPTING.
64
70
 
65
71
  For using the developer API, I suggest you start reading NWN::Gff::Struct.
66
72
 
@@ -8,8 +8,9 @@ Under linux, just add them to your shell environment (usually .bashrc), like so:
8
8
 
9
9
  == NWN_LIB_IN_ENCODING
10
10
 
11
- The character encoding your local data (gff) files are in. Defaults to ISO-8859-1.
12
- Extended dump formats like yaml, xml are always format-specific, usually UTF-8.
11
+ The character encoding your local data (gff) files are in. Defaults to windows-1252.
12
+ Extended dump formats like yaml, xml are always format-specific.
13
+ YAML and json, for example, are always UTF-8.
13
14
 
14
15
  == NWN_LIB_PRETTY_JSON
15
16
 
@@ -1,26 +1,27 @@
1
1
  require 'stringio'
2
- require 'nwn/version'
3
- require 'nwn/io'
4
- require 'nwn/twoda'
5
- require 'nwn/settings'
6
- require 'nwn/res'
7
- require 'nwn/gff'
8
- require 'nwn/tlk'
9
- require 'nwn/key'
10
- require 'nwn/erf'
11
- require 'nwn/yaml_support'
2
+ require_relative 'io'
3
+ require_relative 'twoda'
4
+ require_relative 'settings'
5
+ require_relative 'res'
6
+ require_relative 'gff'
7
+ require_relative 'tlk'
8
+ require_relative 'key'
9
+ require_relative 'erf'
10
+
11
+ require_relative 'yaml_support'
12
+
12
13
  begin
13
14
  require 'json'
14
- require 'nwn/json_support'
15
+ require_relative 'json_support'
15
16
  rescue LoadError => e
16
- NWN.log_debug "json support not available, install json or json_pure to enable"
17
+ # NWN.log_debug "json support not available, install json or json_pure to enable"
17
18
  end
18
- require 'nwn/kivinen_support'
19
+ require_relative 'kivinen_support'
19
20
  begin
20
21
  require 'xml'
21
- require 'nwn/xml_support'
22
+ require_relative 'xml_support'
22
23
  rescue LoadError => e
23
- NWN.log_debug "nxml and modpacker support not available, install libxml-ruby to enable"
24
+ # NWN.log_debug "nxml and modpacker support not available, install libxml-ruby to enable"
24
25
  end
25
26
 
26
- require 'nwn/scripting'
27
+ require_relative 'scripting'
@@ -148,9 +148,9 @@ module NWN
148
148
  end
149
149
  end
150
150
 
151
- require 'nwn/gff/struct'
152
- require 'nwn/gff/cexolocstr'
153
- require 'nwn/gff/field'
154
- require 'nwn/gff/list'
155
- require 'nwn/gff/reader'
156
- require 'nwn/gff/writer'
151
+ require_relative 'gff/struct'
152
+ require_relative 'gff/cexolocstr'
153
+ require_relative 'gff/field'
154
+ require_relative 'gff/list'
155
+ require_relative 'gff/reader'
156
+ require_relative 'gff/writer'
@@ -18,9 +18,11 @@ class NWN::Gff::Reader
18
18
  read_all
19
19
  end
20
20
 
21
- private
21
+ private
22
22
 
23
23
  def read_all
24
+ initial_seek = @io.pos
25
+
24
26
  type, version,
25
27
  struct_offset, struct_count,
26
28
  field_offset, field_count,
@@ -37,27 +39,27 @@ class NWN::Gff::Reader
37
39
  field_len = field_count * 16
38
40
  label_len = label_count * 16
39
41
 
40
- @io.seek(struct_offset)
42
+ @io.seek(initial_seek + struct_offset)
41
43
  @structs = @io.e_read(struct_len, "structs")
42
44
  @structs = @structs.unpack("V*")
43
45
 
44
- @io.seek(field_offset)
46
+ @io.seek(initial_seek + field_offset)
45
47
  @fields = @io.e_read(field_len, "fields")
46
48
  @fields = @fields.unpack("V*")
47
49
 
48
- @io.seek(label_offset)
50
+ @io.seek(initial_seek + label_offset)
49
51
  @labels = @io.e_read(label_len, "labels")
50
52
  @labels = @labels.unpack("A16" * label_count)
51
53
  @labels.map! {|l| l.force_encoding("ASCII") }
52
54
 
53
- @io.seek(field_data_offset)
55
+ @io.seek(initial_seek + field_data_offset)
54
56
  @field_data = @io.e_read(field_data_count, "field_data")
55
57
 
56
- @io.seek(field_indices_offset)
58
+ @io.seek(initial_seek + field_indices_offset)
57
59
  @field_indices = @io.e_read(field_indices_count, "field_indices")
58
60
  @field_indices = @field_indices.unpack("V*")
59
61
 
60
- @io.seek(list_indices_offset)
62
+ @io.seek(initial_seek + list_indices_offset)
61
63
  @list_indices = @io.e_read(list_indices_count, "list_indices")
62
64
  @list_indices = @list_indices.unpack("V*")
63
65
 
@@ -1,6 +1,6 @@
1
1
  module NWN
2
2
  SETTING_DEFAULT_VALUES = {
3
- 'NWN_LIB_IN_ENCODING' => 'ISO-8859-1'
3
+ 'NWN_LIB_IN_ENCODING' => 'windows-1252'
4
4
  }
5
5
 
6
6
  # This writes a internal warnings and debug messages to stderr.
@@ -1,3 +1,5 @@
1
+ require 'base64'
2
+
1
3
  class NWN::Gff::Handler::XML
2
4
 
3
5
  private
@@ -65,6 +67,9 @@ private
65
67
  e << struct_to_xml(ee)
66
68
  }
67
69
 
70
+ when :void
71
+ e['value'] = Base64::strict_encode64(field.field_value)
72
+
68
73
  else
69
74
  e['value'] = field.field_value.to_s
70
75
  end
@@ -128,8 +133,10 @@ private
128
133
  v.to_i
129
134
  when :float, :double
130
135
  v.to_f
131
- when :void, :resref
136
+ when :resref
132
137
  v
138
+ when :void
139
+ Base64::strict_decode64(v)
133
140
  else
134
141
  raise ArgumentError, "Invalid field type #{type.inspect}. Bug."
135
142
  end
@@ -1,103 +1,61 @@
1
- # This file contains all YAML-specific loading and dumping code.
2
- require 'yaml'
3
- Psych::ENGINE.yamler = 'syck'
1
+ require 'psych'
4
2
 
5
3
  module NWN::Gff::Handler::YAML
6
4
  # These field types can never be inlined in YAML.
7
5
  NonInlineableFields = [:struct, :list, :cexolocstr]
8
6
 
9
7
  # See http://www.taguri.org/ for the exact meaning of this.
10
- Domain = "nwn-lib.elv.es,2008-12"
8
+ Domain = "nwn-lib.elv.es,2013-07"
11
9
 
12
10
  def self.load io
13
- YAML.load(io)
11
+ Psych.load(io)
14
12
  end
13
+
15
14
  def self.dump data, io
16
- d = data.to_yaml
17
- io.puts d
18
- d.size
15
+ str = Psych.dump(data)
16
+ io.write(str)
17
+ str.size
19
18
  end
20
19
  end
21
20
 
22
- #:stopdoc:
23
- class Array
24
- attr_accessor :to_yaml_style
25
- end
26
- class Hash
27
- attr_accessor :to_yaml_style
28
- end
29
-
30
- class Hash
31
- # Replacing the to_yaml function so it'll serialize hashes sorted (by their keys)
32
- # Original function is in /usr/lib/ruby/1.8/yaml/rubytypes.rb
33
- def to_yaml(opts = {})
34
- YAML::quick_emit(nil, opts) do |out|
35
- out.map(taguri, to_yaml_style) do |map|
36
- if keys.map {|v| v.class }.size > 0
37
- each do |k, v|
38
- map.add(k, v)
39
- end
40
- else
41
- sort.each do |k, v|
42
- map.add(k, v)
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
21
+ NWN::Gff::Handler.register :yaml, /^(y|yml|yaml)$/, NWN::Gff::Handler::YAML
49
22
 
50
23
  module NWN::Gff::Struct
51
- def to_yaml_type
52
- "!#{NWN::Gff::Handler::YAML::Domain}/struct"
53
- end
54
-
55
- def to_yaml(opts = {})
56
- YAML::quick_emit(nil, opts) do |out|
57
- out.map(taguri, to_yaml_style) do |map|
58
- # Inline certain structs that are small enough.
59
- map.style = :inline if self.size <= 1 &&
60
- self.values.select {|x|
61
- NWN::Gff::Handler::YAML::NonInlineableFields.index(x['type'])
62
- }.size == 0
63
-
64
- map.add('__' + 'data_type', @data_type) if @data_type
65
- map.add('__' + 'data_version', @data_version) if @data_version && @data_version != DEFAULT_DATA_VERSION
66
- map.add('__' + 'struct_id', @struct_id) if @struct_id
67
-
68
- sort.each {|k,v|
69
- map.add(k,v)
70
- }
71
- end
24
+ def encode_with out
25
+ out.map("!#{NWN::Gff::Handler::YAML::Domain}:struct") do |map|
26
+ # Inline certain structs that are small enough.
27
+ map.style = Psych::Nodes::Mapping::FLOW if self.size <= 1 &&
28
+ self.values.select {|x|
29
+ NWN::Gff::Handler::YAML::NonInlineableFields.index(x['type'])
30
+ }.size == 0
31
+
32
+ map.add('__' + 'data_type', @data_type) if @data_type
33
+ map.add('__' + 'data_version', @data_version) if
34
+ @data_version && @data_version != DEFAULT_DATA_VERSION
35
+ map.add('__' + 'struct_id', @struct_id) if @struct_id != nil
36
+
37
+ sort.each {|k, v|
38
+ map.add(k, v)
39
+ }
72
40
  end
73
41
  end
74
42
  end
75
43
 
76
44
  module NWN::Gff::Field
77
-
78
- def to_yaml(opts = {})
79
- YAML::quick_emit(nil, opts) do |out|
80
- out.map(taguri, to_yaml_style) do |map|
81
- map.style = :inline unless NWN::Gff::Handler::YAML::NonInlineableFields.index(self['type'])
82
- map.add('type', self['type'])
83
- map.add('str_ref', self['str_ref']) if has_str_ref?
84
- map.add('value', case self['type']
85
- when :resref, :cexostr
86
- self['value'].encode('utf-8')
87
- when :cexolocstr
88
- Hash[self['value'].map {|lang,str|
89
- [lang, str.encode('utf-8')]
90
- }]
91
- else
92
- self['value']
93
- end)
94
- end
45
+ def encode_with out
46
+ out.map do |map|
47
+ map.tag = nil
48
+ map.style = Psych::Nodes::Mapping::FLOW unless
49
+ NWN::Gff::Handler::YAML::NonInlineableFields.index(self['type'])
50
+ map.add('type', self['type'].to_s)
51
+ map.add('str_ref', self['str_ref']) if has_str_ref?
52
+ map.add('value', self['value'])
95
53
  end
96
54
  end
97
55
  end
98
56
 
99
57
  # This parses the struct and extends all fields with their proper type.
100
- YAML.add_domain_type(NWN::Gff::Handler::YAML::Domain,'struct') {|t,hash|
58
+ Psych.add_domain_type(NWN::Gff::Handler::YAML::Domain,'struct') {|t,hash|
101
59
  struct = {}
102
60
  struct.extend(NWN::Gff::Struct)
103
61
 
@@ -107,7 +65,8 @@ YAML.add_domain_type(NWN::Gff::Handler::YAML::Domain,'struct') {|t,hash|
107
65
  struct.data_version = hash.delete('__data_version')
108
66
  struct.data_version ||= NWN::Gff::Struct::DEFAULT_DATA_VERSION
109
67
 
110
- raise NWN::Gff::GffError, "no struct_id set for struct at #{struct.path}." if struct.struct_id.nil?
68
+ raise NWN::Gff::GffError, "no struct_id set for struct at #{struct.path}." if
69
+ struct.struct_id.nil?
111
70
 
112
71
  hash.each {|label,element|
113
72
  label.freeze
@@ -115,11 +74,14 @@ YAML.add_domain_type(NWN::Gff::Handler::YAML::Domain,'struct') {|t,hash|
115
74
  element.extend(NWN::Gff::Field)
116
75
  element.field_label = label
117
76
  element.parent = struct
118
- element.str_ref ||= NWN::Gff::Field::DEFAULT_STR_REF if element.respond_to?('str_ref=')
77
+ element.str_ref ||= NWN::Gff::Field::DEFAULT_STR_REF if
78
+ element.respond_to?('str_ref=')
119
79
 
120
80
  element.extend_meta_classes
121
81
 
122
- element.field_value.element = element if element.field_value.is_a?(NWN::Gff::Struct)
82
+ element.field_value.element = element if
83
+ element.field_value.is_a?(NWN::Gff::Struct)
84
+
123
85
  element.validate
124
86
 
125
87
  struct[label] = element
@@ -128,4 +90,3 @@ YAML.add_domain_type(NWN::Gff::Handler::YAML::Domain,'struct') {|t,hash|
128
90
  struct
129
91
  }
130
92
 
131
- NWN::Gff::Handler.register :yaml, /^(y|yml|yaml)$/, NWN::Gff::Handler::YAML
@@ -1,5 +1,4 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/nwn/version', __FILE__)
3
2
 
4
3
  Gem::Specification.new do |gem|
5
4
  gem.authors = ["Bernhard Stoeckner"]
@@ -13,6 +12,6 @@ Gem::Specification.new do |gem|
13
12
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
13
  gem.name = "nwn-lib"
15
14
  gem.require_paths = ["lib"]
16
- gem.version = NWN::VERSION
17
- gem.required_ruby_version = '>= 1.9.1'
15
+ gem.version = "0.6.0"
16
+ gem.required_ruby_version = '>= 1.9.3'
18
17
  end
@@ -23,10 +23,11 @@ describe "Gff::Field" do
23
23
 
24
24
  describe ":void" do
25
25
  it "stores data in binary" do
26
+ void = "\xde\xad\xbe\xef".force_encoding("ASCII-8BIT")
26
27
  gff = Gff::Struct.new do |root|
27
- root.add_void 'Test', "\xde\xad\xbe\xef"
28
+ root.add_void 'Test', void
28
29
  end.to_gff
29
- gff.index("\xde\xad\xbe\xef").should_not be_nil
30
+ gff.index(void).should_not be_nil
30
31
  end
31
32
  end
32
33
  end
@@ -6,6 +6,12 @@ describe "Gff.read/write API" do
6
6
  g = Gff.read(i, :gff)
7
7
  end
8
8
 
9
+ it "reads from IO with offsets correctly" do
10
+ i = StringIO.new "a" + WELLFORMED_GFF
11
+ i.seek(1)
12
+ g = Gff.read(i, :gff)
13
+ end
14
+
9
15
  it "writes correctly" do
10
16
  i = StringIO.new WELLFORMED_GFF
11
17
  gff = Gff.read(i, :gff)
@@ -1,4 +1,5 @@
1
- require 'rubygems'
1
+ Bundler.setup(:default, :test)
2
+
2
3
  require 'tempfile'
3
4
  require 'fileutils'
4
5
  require 'open3'
@@ -206,29 +207,23 @@ module BinHelper
206
207
  old = Dir.pwd
207
208
  Dir.chdir(@tmpdir) if defined?(@tmpdir)
208
209
  begin
209
- Open3.popen3(
210
- "ruby", "-rubygems", "-I#{incl}",
211
- binary,
212
- *va
213
- ) do |i,o,e|
214
- yield i, o, e
215
- end
210
+ return Open3.capture2e(
211
+ "ruby", "-rubygems", "-I#{incl}",
212
+ binary,
213
+ *va
214
+ )
216
215
  ensure
216
+ Dir.chdir(old)
217
217
  end
218
- Dir.chdir(old)
219
218
  end
220
219
 
221
220
  def run *va
222
- puts "run: #{va.inspect}"
223
- run_bin *va do |i, o, e|
224
- e = e.read
225
- e.should == ""
226
- end
221
+ stdout_str, ret = run_bin *va
222
+ ret.should == 0
227
223
  end
228
224
 
229
225
  def run_fail *va
230
- run_bin *va do |i, o, e|
231
- e.read.size.should > 0
232
- end
226
+ stdout_str, ret = run_bin *va
227
+ ret.should_not == 0
233
228
  end
234
229
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nwn-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
5
- prerelease:
4
+ version: 0.6.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Bernhard Stoeckner
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-28 00:00:00.000000000 Z
11
+ date: 2013-11-16 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: Neverwinter Nights 1/2 file formats ruby library
15
14
  email:
@@ -55,7 +54,6 @@ files:
55
54
  - lib/nwn/settings.rb
56
55
  - lib/nwn/tlk.rb
57
56
  - lib/nwn/twoda.rb
58
- - lib/nwn/version.rb
59
57
  - lib/nwn/xml_support.rb
60
58
  - lib/nwn/yaml_support.rb
61
59
  - nwn-lib.gemspec
@@ -88,27 +86,26 @@ files:
88
86
  - tools/verify.sh
89
87
  homepage: https://github.com/niv/nwn-lib
90
88
  licenses: []
89
+ metadata: {}
91
90
  post_install_message:
92
91
  rdoc_options: []
93
92
  require_paths:
94
93
  - lib
95
94
  required_ruby_version: !ruby/object:Gem::Requirement
96
- none: false
97
95
  requirements:
98
- - - ! '>='
96
+ - - '>='
99
97
  - !ruby/object:Gem::Version
100
- version: 1.9.1
98
+ version: 1.9.3
101
99
  required_rubygems_version: !ruby/object:Gem::Requirement
102
- none: false
103
100
  requirements:
104
- - - ! '>='
101
+ - - '>='
105
102
  - !ruby/object:Gem::Version
106
103
  version: '0'
107
104
  requirements: []
108
105
  rubyforge_project:
109
- rubygems_version: 1.8.23
106
+ rubygems_version: 2.0.2
110
107
  signing_key:
111
- specification_version: 3
108
+ specification_version: 4
112
109
  summary: Neverwinter Nights 1/2 file formats ruby library
113
110
  test_files:
114
111
  - spec/bin_dsl_spec.rb
@@ -1,3 +0,0 @@
1
- module NWN
2
- VERSION = "0.5.1"
3
- end