nbt_utils 0.0.1

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,2 @@
1
+ .bundle/
2
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,18 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ nbt_utils (0.0.1)
5
+ bindata (~> 1.2)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ bindata (1.2.1)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bindata (~> 1.2)
17
+ bundler (>= 1.0.0)
18
+ nbt_utils!
@@ -0,0 +1,28 @@
1
+ nbt_utils
2
+ =========
3
+
4
+ Some classes for handling Minecraft .nbt files.
5
+
6
+ See http://www.minecraft.net/docs/NBT.txt for specification info, also mirred in the doc directory.
7
+
8
+ Installation
9
+ ============
10
+
11
+ Requires ruby 1.9 minimum. Tested with 1.9.2.
12
+
13
+ gem install nbt_utils
14
+
15
+ Use
16
+ ===
17
+
18
+ require 'nbt_utils'
19
+
20
+ @tag = NBTUtils::File.new.read('some_nbt_file.nbt')
21
+ puts @tag.to_s
22
+
23
+ Copyright
24
+ =========
25
+
26
+ Copyright (c) 2010 Michael Dungan, mpd@jesters-court.net, released under the MIT license.
27
+
28
+ The files `NBT.txt`, `test.nbt`, and `bigtest.nbt` in the `doc` directory are mirred from the Minecraft website.
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,149 @@
1
+ Named Binary Tag specification
2
+
3
+ NBT (Named Binary Tag) is a tag based binary format designed to carry large amounts of binary data with smaller amounts of additional data.
4
+ An NBT file consists of a single GZIPped Named Tag of type TAG_Compound.
5
+
6
+ A Named Tag has the following format:
7
+
8
+ byte tagType
9
+ TAG_String name
10
+ [payload]
11
+
12
+ The tagType is a single byte defining the contents of the payload of the tag.
13
+
14
+ The name is a descriptive name, and can be anything (eg "cat", "banana", "Hello World!"). It has nothing to do with the tagType.
15
+ The purpose for this name is to name tags so parsing is easier and can be made to only look for certain recognized tag names.
16
+ Exception: If tagType is TAG_End, the name is skipped and assumed to be "".
17
+
18
+ The [payload] varies by tagType.
19
+
20
+ Note that ONLY Named Tags carry the name and tagType data. Explicitly identified Tags (such as TAG_String above) only contains the payload.
21
+
22
+
23
+ The tag types and respective payloads are:
24
+
25
+ TYPE: 0 NAME: TAG_End
26
+ Payload: None.
27
+ Note: This tag is used to mark the end of a list.
28
+ Cannot be named! If type 0 appears where a Named Tag is expected, the name is assumed to be "".
29
+ (In other words, this Tag is always just a single 0 byte when named, and nothing in all other cases)
30
+
31
+ TYPE: 1 NAME: TAG_Byte
32
+ Payload: A single signed byte (8 bits)
33
+
34
+ TYPE: 2 NAME: TAG_Short
35
+ Payload: A signed short (16 bits, big endian)
36
+
37
+ TYPE: 3 NAME: TAG_Int
38
+ Payload: A signed short (32 bits, big endian)
39
+
40
+ TYPE: 4 NAME: TAG_Long
41
+ Payload: A signed long (64 bits, big endian)
42
+
43
+ TYPE: 5 NAME: TAG_Float
44
+ Payload: A floating point value (32 bits, big endian, IEEE 754-2008, binary32)
45
+
46
+ TYPE: 6 NAME: TAG_Double
47
+ Payload: A floating point value (64 bits, big endian, IEEE 754-2008, binary64)
48
+
49
+ TYPE: 7 NAME: TAG_Byte_Array
50
+ Payload: TAG_Int length
51
+ An array of bytes of unspecified format. The length of this array is <length> bytes
52
+
53
+ TYPE: 8 NAME: TAG_String
54
+ Payload: TAG_Short length
55
+ An array of bytes defining a string in UTF-8 format. The length of this array is <length> bytes
56
+
57
+ TYPE: 9 NAME: TAG_List
58
+ Payload: TAG_Byte tagId
59
+ TAG_Int length
60
+ A sequential list of Tags (not Named Tags), of type <typeId>. The length of this array is <length> Tags
61
+ Notes: All tags share the same type.
62
+
63
+ TYPE: 10 NAME: TAG_Compound
64
+ Payload: A sequential list of Named Tags. This array keeps going until a TAG_End is found.
65
+ TAG_End end
66
+ Notes: If there's a nested TAG_Compound within this tag, that one will also have a TAG_End, so simply reading until the next TAG_End will not work.
67
+ The names of the named tags have to be unique within each TAG_Compound
68
+ The order of the tags is not guaranteed.
69
+
70
+
71
+
72
+
73
+
74
+ Decoding example:
75
+ (Use http://www.minecraft.net/docs/test.nbt to test your implementation)
76
+
77
+
78
+ First we start by reading a Named Tag.
79
+ After unzipping the stream, the first byte is a 10. That means the tag is a TAG_Compound (as expected by the specification).
80
+
81
+ The next two bytes are 0 and 11, meaning the name string consists of 11 UTF-8 characters. In this case, they happen to be "hello world".
82
+ That means our root tag is named "hello world". We can now move on to the payload.
83
+
84
+ From the specification, we see that TAG_Compound consists of a series of Named Tags, so we read another byte to find the tagType.
85
+ It happens to be an 8. The name is 4 letters long, and happens to be "name". Type 8 is TAG_String, meaning we read another two bytes to get the length,
86
+ then read that many bytes to get the contents. In this case, it's "Bananrama".
87
+
88
+ So now we know the TAG_Compound contains a TAG_String named "name" with the content "Bananrama"
89
+
90
+ We move on to reading the next Named Tag, and get a 0. This is TAG_End, which always has an implied name of "". That means that the list of entries
91
+ in the TAG_Compound is over, and indeed all of the NBT file.
92
+
93
+ So we ended up with this:
94
+
95
+ TAG_Compound("hello world"): 1 entries
96
+ {
97
+ TAG_String("name"): Bananrama
98
+ }
99
+
100
+
101
+
102
+ For a slightly longer test, download http://www.minecraft.net/docs/bigtest.nbt
103
+ You should end up with this:
104
+
105
+ TAG_Compound("Level"): 11 entries
106
+ {
107
+ TAG_Short("shortTest"): 32767
108
+ TAG_Long("longTest"): 9223372036854775807
109
+ TAG_Float("floatTest"): 0.49823147
110
+ TAG_String("stringTest"): HELLO WORLD THIS IS A TEST STRING ���!
111
+ TAG_Int("intTest"): 2147483647
112
+ TAG_Compound("nested compound test"): 2 entries
113
+ {
114
+ TAG_Compound("ham"): 2 entries
115
+ {
116
+ TAG_String("name"): Hampus
117
+ TAG_Float("value"): 0.75
118
+ }
119
+ TAG_Compound("egg"): 2 entries
120
+ {
121
+ TAG_String("name"): Eggbert
122
+ TAG_Float("value"): 0.5
123
+ }
124
+ }
125
+ TAG_List("listTest (long)"): 5 entries of type TAG_Long
126
+ {
127
+ TAG_Long: 11
128
+ TAG_Long: 12
129
+ TAG_Long: 13
130
+ TAG_Long: 14
131
+ TAG_Long: 15
132
+ }
133
+ TAG_Byte("byteTest"): 127
134
+ TAG_List("listTest (compound)"): 2 entries of type TAG_Compound
135
+ {
136
+ TAG_Compound: 2 entries
137
+ {
138
+ TAG_String("name"): Compound tag #0
139
+ TAG_Long("created-on"): 1264099775885
140
+ }
141
+ TAG_Compound: 2 entries
142
+ {
143
+ TAG_String("name"): Compound tag #1
144
+ TAG_Long("created-on"): 1264099775885
145
+ }
146
+ }
147
+ TAG_Byte_Array("byteArrayTest (the first 1000 values of (n*n*255+n*7)%100, starting with n=0 (0, 62, 34, 16, 8, ...))"): [1000 bytes]
148
+ TAG_Double("doubleTest"): 0.4931287132182315
149
+ }
Binary file
Binary file
@@ -0,0 +1,19 @@
1
+ require 'zlib'
2
+ require 'bindata'
3
+
4
+ require File.expand_path('nbt_utils/tag/exceptions', File.dirname(__FILE__))
5
+
6
+ require File.expand_path('nbt_utils/file', File.dirname(__FILE__))
7
+ require File.expand_path('nbt_utils/tag_name', File.dirname(__FILE__))
8
+ require File.expand_path('nbt_utils/tag', File.dirname(__FILE__))
9
+ require File.expand_path('nbt_utils/tag/end', File.dirname(__FILE__))
10
+ require File.expand_path('nbt_utils/tag/byte', File.dirname(__FILE__))
11
+ require File.expand_path('nbt_utils/tag/short', File.dirname(__FILE__))
12
+ require File.expand_path('nbt_utils/tag/int', File.dirname(__FILE__))
13
+ require File.expand_path('nbt_utils/tag/long', File.dirname(__FILE__))
14
+ require File.expand_path('nbt_utils/tag/float', File.dirname(__FILE__))
15
+ require File.expand_path('nbt_utils/tag/double', File.dirname(__FILE__))
16
+ require File.expand_path('nbt_utils/tag/byte_array', File.dirname(__FILE__))
17
+ require File.expand_path('nbt_utils/tag/string', File.dirname(__FILE__))
18
+ require File.expand_path('nbt_utils/tag/list', File.dirname(__FILE__))
19
+ require File.expand_path('nbt_utils/tag/compound', File.dirname(__FILE__))
@@ -0,0 +1,25 @@
1
+ module NBTUtils
2
+ class File
3
+ def initialize(path = nil)
4
+ @path = path
5
+ end
6
+
7
+ def read(path = @path)
8
+ Zlib::GzipReader.open(path) do |f|
9
+ # ostensibly this will always be a single TAG_Compound, per the spec
10
+ last_byte = f.read(1).bytes.first
11
+ klass = NBTUtils::Tag.tag_type_to_class(last_byte)
12
+
13
+ @tag = klass.new(f, true)
14
+ end
15
+
16
+ @tag
17
+ end
18
+
19
+ def write(path = @path, tag = @tag)
20
+ Zlib::GzipWriter.open(path) do |gz|
21
+ gz.write tag.to_nbt_string
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,77 @@
1
+ module NBTUtils
2
+ module Tag
3
+ attr_reader :name
4
+ attr_reader :payload
5
+
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ def initialize(io, named = true)
11
+ read_name(io) if named
12
+ @payload = self.class.payload_class.new.read(io)
13
+ end
14
+
15
+ def type_id
16
+ self.class.type_id
17
+ end
18
+
19
+ def binary_type_id
20
+ # I hope i'm doing this wrong.
21
+ byte = ::BinData::Int8be.new
22
+ byte.value = type_id
23
+ byte.to_binary_s
24
+ end
25
+
26
+ def to_s(indent = 0)
27
+ klass = self.class.to_s.split('::').last
28
+ (' ' * indent) + "TAG_#{klass}#{@name ? "(\"#{@name}\")" : ''}: #{@payload.value}"
29
+ end
30
+
31
+ def to_nbt_string(named = true)
32
+ result = named ? binary_type_id + name_to_nbt_string : ''
33
+ result + @payload.to_binary_s
34
+ end
35
+
36
+ def read_name(io)
37
+ @name = NBTUtils::TagName.new.read(io).data
38
+ end
39
+
40
+ def name_to_nbt_string
41
+ nm = NBTUtils::TagName.new
42
+ nm.data = @name
43
+ nm.to_binary_s
44
+ end
45
+
46
+ def tag_type_to_class(tag_type)
47
+ NBTUtils::Tag.tag_type_to_class(tag_type)
48
+ end
49
+
50
+ module ClassMethods
51
+ def type_id(new_id = nil)
52
+ if new_id
53
+ @type_id = new_id
54
+ NBTUtils::Tag.add_tag_type(new_id, self)
55
+ end
56
+
57
+ @type_id
58
+ end
59
+
60
+ def payload_class(new_klass = nil)
61
+ @payload_class = new_klass if new_klass
62
+ @payload_class
63
+ end
64
+ end
65
+
66
+ def self.tag_type_to_class(tag_type)
67
+ @tag_types[tag_type.to_i]
68
+ end
69
+
70
+ protected
71
+
72
+ def self.add_tag_type(index, tag_type)
73
+ @tag_types ||= []
74
+ @tag_types[index] = tag_type
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Byte # signed, per spec
4
+ include NBTUtils::Tag
5
+
6
+ type_id 1
7
+ payload_class ::BinData::Int8be
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class ByteArray
4
+ include NBTUtils::Tag
5
+
6
+ type_id 7
7
+
8
+ def initialize(io, named = true)
9
+ read_name(io) if named
10
+
11
+ len = ::BinData::Int32be.new.read(io).value
12
+ # signedness of the bytes in the array is not defined in the spec.
13
+ @payload = ::BinData::Array.new(:type => :uint8, :initial_length => len).read(io)
14
+ end
15
+
16
+ def to_s(indent = 0)
17
+ (' ' * indent) + "TAG_Byte_Array#{@name ? "(\"#{@name}\")" : ''}: [#{@payload.length} bytes]"
18
+ end
19
+
20
+ def to_nbt_string(named = true)
21
+ result = named ? binary_type_id + name_to_nbt_string : ''
22
+ len = ::BinData::Int32be.new
23
+ len.value = @payload.length
24
+ result += len.to_binary_s
25
+ result + @payload.to_binary_s
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Compound
4
+ include NBTUtils::Tag
5
+
6
+ type_id 10
7
+
8
+ def initialize(io, named = true)
9
+ @payload = []
10
+ @tag_names = []
11
+ read_name(io) if named
12
+
13
+ until (last_byte = io.read(1).bytes.first) == NBTUtils::Tag::End.type_id
14
+ klass = tag_type_to_class(last_byte)
15
+ add_tag klass.new(io, true)
16
+ end
17
+ end
18
+
19
+ def to_s(indent = 0)
20
+ ret = (' ' * indent) + "TAG_Compound#{@name ? "(\"#{@name}\")" : ''}: #{@payload.length} entries\n"
21
+ ret += (' ' * indent) + "{\n"
22
+ @payload.each do |load|
23
+ ret += "#{load.to_s(indent + 2)}\n"
24
+ end
25
+ ret += (' ' * indent) + "}"
26
+
27
+ ret
28
+ end
29
+
30
+ def to_nbt_string(named = true)
31
+ result = named ? binary_type_id + name_to_nbt_string : ''
32
+
33
+ result = @payload.inject(result) do |r, load|
34
+ r + load.to_nbt_string(true)
35
+ end
36
+
37
+ result + NBTUtils::Tag::End.new(nil).to_nbt_string
38
+ end
39
+
40
+ def find_tag(name)
41
+ @payload.detect { |tag| tag.name =~ /#{name}/ }
42
+ end
43
+
44
+ def find_tags(name)
45
+ @payload.select { |tag| tag.name =~ /#{name}/ }
46
+ end
47
+
48
+ def add_tag(tag)
49
+ raise MissingCompoundPayloadTagNameError if tag.name.nil?
50
+ raise DuplicateCompoundPayloadTagNameError if @tag_names.include?(tag.name)
51
+ @tag_names << tag.name
52
+ @payload << tag
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Double # signed, per spec
4
+ include NBTUtils::Tag
5
+
6
+ type_id 6
7
+ payload_class ::BinData::DoubleBe
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,21 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class End
4
+ include NBTUtils::Tag
5
+
6
+ type_id 0
7
+
8
+ def initialize(input, named = false)
9
+ @name = ''
10
+ end
11
+
12
+ def to_s(indent = 0)
13
+ ''
14
+ end
15
+
16
+ def to_nbt_string(named = false)
17
+ binary_type_id
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,2 @@
1
+ class DuplicateCompoundPayloadTagNameError < StandardError; end
2
+ class MissingCompoundPayloadTagNameError < StandardError; end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Float # signed, per spec
4
+ include NBTUtils::Tag
5
+
6
+ type_id 5
7
+ payload_class ::BinData::FloatBe
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Int # signed, per spec
4
+ include NBTUtils::Tag
5
+
6
+ type_id 3
7
+ payload_class ::BinData::Int32be
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,44 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class List
4
+ include NBTUtils::Tag
5
+
6
+ type_id 9
7
+
8
+ def initialize(io, named = true)
9
+ @payload = []
10
+ read_name(io) if named
11
+
12
+ tag_id = io.read(1).bytes.first.to_i
13
+ @tag_type = NBTUtils::Tag.tag_type_to_class(tag_id)
14
+ len = ::BinData::Int32be.new.read(io).value
15
+ len.times do
16
+ @payload << @tag_type.new(io, false)
17
+ end
18
+ end
19
+
20
+ def to_s(indent = 0)
21
+ ret = (' ' * indent) + "TAG_List#{@name ? "(\"#{@name}\")" : ''}: #{@payload.length} entries of type TAG_#{@tag_type.to_s.split('::').last}\n"
22
+ ret += (' ' * indent) + "{\n"
23
+ @payload.each do |load|
24
+ ret += "#{load.to_s(indent + 2)}\n"
25
+ end
26
+ ret += (' ' * indent) + "}"
27
+ ret
28
+ end
29
+
30
+ def to_nbt_string(named = true)
31
+ result = named ? binary_type_id + name_to_nbt_string : ''
32
+ type =::BinData::Int8be.new
33
+ type.value = @tag_type.type_id
34
+ result += type.to_binary_s
35
+ len = ::BinData::Int32be.new
36
+ len.value = @payload.length
37
+ result += len.to_binary_s
38
+ @payload.inject(result) do |r, load|
39
+ r + load.to_nbt_string(false)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Long # signed, per spec
4
+ include NBTUtils::Tag
5
+
6
+ type_id 4
7
+ payload_class ::BinData::Int64be
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class Short # signed, per spec
4
+ include NBTUtils::Tag
5
+
6
+ type_id 2
7
+ payload_class ::BinData::Int16be
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module NBTUtils
2
+ module Tag
3
+ class String
4
+ include NBTUtils::Tag
5
+
6
+ type_id 8
7
+ payload_class NBTUtils::TagName
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ module NBTUtils
2
+ class TagName < ::BinData::Record
3
+ # Spec says this is a TAG_Short, which is signed. Staying strict
4
+ # though this may really be unsigned in practice.
5
+ int16be :len, :value => Proc.new { data.length }
6
+ string :data, :read_length => :len
7
+
8
+ # things break for some reason if you just call the string :value
9
+ def value
10
+ data
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module NBTUtils
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/nbt_utils/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "nbt_utils"
6
+ s.version = NBTUtils::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ['Michael Dungan']
9
+ s.email = ['mpd@jesters-court.net']
10
+ s.homepage = "http://rubygems.org/gems/nbt_utils"
11
+ s.summary = "Set of classes to read and write Minecraft .nbt files"
12
+ s.description = "Some classes to read and write Minecraft .nbt files. See http://www.minecraft.net/docs/NBT.txt for format description."
13
+
14
+ s.required_rubygems_version = ">= 1.3.6"
15
+
16
+ s.add_dependency "bindata", "~> 1.2"
17
+ s.add_development_dependency "bundler", ">= 1.0.0"
18
+
19
+ s.required_ruby_version = "~> 1.9"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
23
+ s.require_path = 'lib'
24
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'bundler'
4
+ Bundler.require :default
5
+
6
+ require File.expand_path('./lib/nbt_utils', File.dirname(__FILE__))
7
+ require 'zlib'
8
+
9
+ @compound = nil
10
+
11
+ file = NBTUtils::File.new('doc/test.nbt')
12
+ @compound = file.read
13
+
14
+ puts @compound.to_s
15
+
16
+ #puts @compound.to_nbt_string
17
+ #Zlib::GzipWriter.open('lolwut.nbt') do |gz|
18
+ # gz.write @compound.to_nbt_string
19
+ #end
20
+
21
+ @compound = NBTUtils::File.new.read('doc/bigtest.nbt')
22
+ puts @compound.to_s
23
+
24
+ #puts @compound.to_nbt_string
25
+ #Zlib::GzipWriter.open('biglolwut.nbt') do |gz|
26
+ # gz.write @compound.to_nbt_string
27
+ #end
28
+
29
+ puts @compound.find_tag('Test')
30
+ #puts @compound.find_tags(/(?:byte|int)Test/)
31
+ #puts @compound.find_tags 'intasdf'
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nbt_utils
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - Michael Dungan
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-23 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bindata
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 2
31
+ version: "1.2"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: bundler
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 0
45
+ - 0
46
+ version: 1.0.0
47
+ type: :development
48
+ version_requirements: *id002
49
+ description: Some classes to read and write Minecraft .nbt files. See http://www.minecraft.net/docs/NBT.txt for format description.
50
+ email:
51
+ - mpd@jesters-court.net
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - Gemfile
61
+ - Gemfile.lock
62
+ - README.md
63
+ - Rakefile
64
+ - doc/NBT.txt
65
+ - doc/bigtest.nbt
66
+ - doc/test.nbt
67
+ - lib/nbt_utils.rb
68
+ - lib/nbt_utils/file.rb
69
+ - lib/nbt_utils/tag.rb
70
+ - lib/nbt_utils/tag/byte.rb
71
+ - lib/nbt_utils/tag/byte_array.rb
72
+ - lib/nbt_utils/tag/compound.rb
73
+ - lib/nbt_utils/tag/double.rb
74
+ - lib/nbt_utils/tag/end.rb
75
+ - lib/nbt_utils/tag/exceptions.rb
76
+ - lib/nbt_utils/tag/float.rb
77
+ - lib/nbt_utils/tag/int.rb
78
+ - lib/nbt_utils/tag/list.rb
79
+ - lib/nbt_utils/tag/long.rb
80
+ - lib/nbt_utils/tag/short.rb
81
+ - lib/nbt_utils/tag/string.rb
82
+ - lib/nbt_utils/tag_name.rb
83
+ - lib/nbt_utils/version.rb
84
+ - nbt_utils.gemspec
85
+ - script.rb
86
+ has_rdoc: true
87
+ homepage: http://rubygems.org/gems/nbt_utils
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options: []
92
+
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ~>
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 1
102
+ - 9
103
+ version: "1.9"
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ segments:
110
+ - 1
111
+ - 3
112
+ - 6
113
+ version: 1.3.6
114
+ requirements: []
115
+
116
+ rubyforge_project:
117
+ rubygems_version: 1.3.7
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Set of classes to read and write Minecraft .nbt files
121
+ test_files: []
122
+