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.
- data/.gitignore +2 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +18 -0
- data/README.md +28 -0
- data/Rakefile +2 -0
- data/doc/NBT.txt +149 -0
- data/doc/bigtest.nbt +0 -0
- data/doc/test.nbt +0 -0
- data/lib/nbt_utils.rb +19 -0
- data/lib/nbt_utils/file.rb +25 -0
- data/lib/nbt_utils/tag.rb +77 -0
- data/lib/nbt_utils/tag/byte.rb +10 -0
- data/lib/nbt_utils/tag/byte_array.rb +29 -0
- data/lib/nbt_utils/tag/compound.rb +56 -0
- data/lib/nbt_utils/tag/double.rb +10 -0
- data/lib/nbt_utils/tag/end.rb +21 -0
- data/lib/nbt_utils/tag/exceptions.rb +2 -0
- data/lib/nbt_utils/tag/float.rb +10 -0
- data/lib/nbt_utils/tag/int.rb +10 -0
- data/lib/nbt_utils/tag/list.rb +44 -0
- data/lib/nbt_utils/tag/long.rb +10 -0
- data/lib/nbt_utils/tag/short.rb +10 -0
- data/lib/nbt_utils/tag/string.rb +10 -0
- data/lib/nbt_utils/tag_name.rb +13 -0
- data/lib/nbt_utils/version.rb +3 -0
- data/nbt_utils.gemspec +24 -0
- data/script.rb +31 -0
- metadata +122 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
data/doc/NBT.txt
ADDED
@@ -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
|
+
}
|
data/doc/bigtest.nbt
ADDED
Binary file
|
data/doc/test.nbt
ADDED
Binary file
|
data/lib/nbt_utils.rb
ADDED
@@ -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,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,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,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,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
|
data/nbt_utils.gemspec
ADDED
@@ -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
|
data/script.rb
ADDED
@@ -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
|
+
|