rubycraft 0.1.0 → 0.1.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.
@@ -1,257 +0,0 @@
1
- require 'chunk'
2
-
3
- class LazyChunkDelegate
4
- include ByteConverter
5
- include ZlibHelper
6
-
7
- def initialize(bytes)
8
- @bytes = bytes
9
- @chunk = nil
10
- end
11
-
12
- def each(&block)
13
- _getchunk.each &block
14
- end
15
-
16
- def block_map(&block)
17
- _getchunk.block_map &block
18
- end
19
- def block_type_map(&block)
20
- _getchunk.block_type_map &block
21
- end
22
-
23
- def [](z, x, y)
24
- _getchunk[z, x, y]
25
- end
26
-
27
- def []=(z, x, y, value)
28
- _getchunk[z, x, y] = value
29
- end
30
-
31
- def export
32
- _getchunk.export
33
- end
34
-
35
-
36
- def toNbt
37
- return @bytes if @chunk.nil?
38
- @chunk.toNbt
39
- end
40
-
41
-
42
- # unloacs the loaded chunk. Needed for memory optmization
43
- def _unload
44
- return if @chunk.nil?
45
- @bytes = @chunk.toNbt
46
- @chunk = nil
47
- end
48
-
49
- protected
50
- def _getchunk
51
- if @chunk.nil?
52
- @chunk = Chunk.fromNbt @bytes
53
- end
54
- @chunk
55
- end
56
-
57
- end
58
-
59
- # Enumerable over chunks
60
- class Region
61
- include Enumerable
62
- include ByteConverter
63
- include ZlibHelper
64
-
65
- class RegionWritter
66
- def initialize(io)
67
- @io = io
68
- end
69
-
70
- def pad(count, value = 0)
71
- self << Array.new(count) { value }
72
- end
73
-
74
- def <<(o)
75
- input = o.kind_of?(Array) ? o : [o]
76
- @io << ByteConverter.toByteString(input)
77
- end
78
-
79
- def close
80
- @io.close
81
- end
82
- end
83
-
84
- def self.fromFile(filename)
85
- new ByteConverter.stringToByteArray IO.read filename
86
- end
87
-
88
- def initialize(bytes)
89
- raise "Must be an io" if bytes.kind_of?(String)
90
- @bytes = bytes
91
- @chunks = Array.new(32) { Array.new(32) }
92
- readChunks bytes
93
- end
94
-
95
- def chunk(z, x)
96
- @chunks[z][x]
97
- end
98
-
99
- def unloadChunk(z, x)
100
- @chunks[z][x]._unload
101
- end
102
-
103
- def each(&block)
104
- @chunks.each do |line|
105
- line.each do |chunk|
106
- yield chunk
107
- end
108
- end
109
- end
110
-
111
- def cube(z, y, x, opts = {}, &block)
112
- c = ChunkCube.new(self, [z, y, x], opts[:width], opts[:length], opts[:height])
113
- return c unless block_given?
114
- c.each &block
115
- end
116
-
117
- def exportTo(io)
118
- output = RegionWritter.new io
119
- chunks = getChunks
120
- writeChunkOffsets output, chunks
121
- output.pad blockSize, dummytimestamp
122
- writeChunks output, chunks
123
- output.close
124
- end
125
-
126
- def exportToFile(filename)
127
- File.open(filename, "wb") { |f| exportTo f }
128
- end
129
-
130
-
131
- protected
132
- def readChunks(bytes)
133
- bytes[0..(blockSize - 1)].each_slice(4).each_with_index do |ar, i|
134
- offset = bytesToInt [0] + ar[0..-2]
135
- count = ar.last
136
- if count > 0
137
- @chunks[i / 32][i % 32 ] = readChunk(offset, bytes)
138
- end
139
- end
140
- end
141
-
142
- def readChunk(offset, bytes)
143
- o = offset * blockSize
144
- bytecount = bytesToInt bytes[o..(o + 4)]
145
- o += 5
146
- nbtBytes = bytes[o..(o + bytecount - 2)]
147
- LazyChunkDelegate.new nbtBytes
148
- end
149
-
150
- def chunkSize(chunk)
151
- chunk.size + chunkMetaDataSize
152
- end
153
-
154
- def chunkBlocks(chunk)
155
- ((chunkSize chunk).to_f / blockSize).ceil
156
- end
157
-
158
- def writeChunks(output, chunks)
159
- for chunk in chunks
160
- next if chunk.nil?
161
- output << intBytes(chunk.size + 1)
162
- output << defaultCompressionType
163
- output << chunk
164
- remaining = blockSize - chunkSize(chunk)
165
- output.pad remaining % blockSize
166
- end
167
- end
168
-
169
- def writeChunkOffsets(output, chunks)
170
- lastVacantPosition = 2
171
- for chunk in chunks
172
- if chunk
173
- sizeCount = chunkBlocks chunk
174
- output << intBytes(lastVacantPosition)[1..3]
175
- output << sizeCount
176
- lastVacantPosition += sizeCount
177
- else
178
- output.pad 4
179
- end
180
- end
181
- end
182
-
183
- def getChunks
184
- map do |chunk|
185
- if chunk.nil?
186
- nil
187
- else
188
- chunk.toNbt
189
- end
190
- end
191
- end
192
-
193
- def chunkMetaDataSize
194
- 5
195
- end
196
-
197
- def defaultCompressionType
198
- 2
199
- end
200
-
201
- def dummytimestamp
202
- 0
203
- end
204
-
205
- def blockSize
206
- 4096
207
- end
208
-
209
- end
210
-
211
-
212
- class ChunkCube
213
- include Enumerable
214
-
215
- # width corresponds do z, length to x, and height to y.
216
- def initialize(region, initialPos, width, length, height)
217
- @region = region
218
- @initialPos = initialPos
219
- @width = width || 1
220
- @length = length || 1
221
- @height = height || 1
222
- end
223
-
224
- def each(&block)
225
- z, x, y = @initialPos
226
- firstChunkX = x / chunkSide
227
- firstChunkZ = z / chunkSide
228
- lastChunkX = (x + @length - 1) / chunkSide
229
- lastChunkZ = (z + @width - 1) / chunkSide
230
- for j in firstChunkZ..lastChunkZ
231
- for i in firstChunkX..lastChunkX
232
- iterateOverChunk j, i, &block
233
- end
234
- end
235
- end
236
-
237
- protected
238
- def iterateOverChunk(j, i, &block)
239
- chunk = @region.chunk(j, i)
240
- return if chunk.nil?
241
- z, x, y = @initialPos
242
- chunk.each do |b|
243
- globalZ = b.z + (j * chunkSide)
244
- globalX = b.x + (i * chunkSide)
245
- if globalZ.between?(z, z + @width - 1) and
246
- globalX.between?(x, x + @length - 1) and
247
- b.y.between?(y, y + @height - 1)
248
- yield b, globalZ - z, globalX - x , b.y - y
249
- end
250
- end
251
- @region.unloadChunk(j, i)
252
- end
253
-
254
- def chunkSide
255
- 16
256
- end
257
- end