rrb-common 0.1.6 → 0.1.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25249c7b5e3aa642c23637cc4e3bad8ce62434a1d77962287fe7cab331d016c9
4
- data.tar.gz: 7592bacd9ddfb0d7371bfd24f87a84de502e2500f7a81a5ca3f8bbd5f1d888a5
3
+ metadata.gz: 0ce1791f92b3956911a84c638f8c6b55b1dc41b250321f0ee14a3aa2e70771d0
4
+ data.tar.gz: 1d80809c5a7633e2f379a3c6df03ad0cd278d127775a2ad76fae52c31f4ae534
5
5
  SHA512:
6
- metadata.gz: 58a9a9da24f64061478f46982beb434b6a3e917c494bf36e437b50570593b2b05bb9870ad50bee4fb08cb82bfec4eb90e8377cae5504e513584582ce1030b6bf
7
- data.tar.gz: b4810f557135b53ba88e89850d59076f24650df965ec0b497868ec41d7a47e8d47c635c6b5797c5297d994446335a479e1dad3c0f22da04c810503a571af8460
6
+ metadata.gz: 59abbc5acfb4daad674f5555d23adf9714987a448fbc6c051aee422977672206550973039df89f85dd27adc31b872763b3c700983022bf91333fe46232d7af0b
7
+ data.tar.gz: af50e56189702d9c4820ec9a78e04ec0a4dc042a825ff7015d736938dd6119610d75df3e16792d7329eb2c7cc46f3dc8359fcdc8e2179ff96ec6cc7ceca94819
@@ -0,0 +1,63 @@
1
+ module RuneRb::Cache
2
+ # An archive of data in the Cache.
3
+ class Archive
4
+ include RuneRb::Core::Logging
5
+
6
+ # @!attribute [r] entries
7
+ # @return [Array<Hash>] the entries in the archive
8
+ attr_reader :entries
9
+
10
+ # Constructs a new CacheArchive
11
+ # @param entries [Array<Hash>] the entries in the archive
12
+ def initialize(entries)
13
+ @entries = entries
14
+ end
15
+
16
+ # Decodes an archive from the specified buffer.
17
+ # @param buffer [RuneRb::Core::Buffer] the buffer to decode
18
+ def self.decode(buffer)
19
+ extracted_size = buffer.read(type: :int24)
20
+ size = buffer.read(type: :int24)
21
+ extracted = false
22
+
23
+ if size != extracted_size
24
+ data = buffer.data.slice!(0..size)
25
+ data = StringIO.new(data)
26
+ decompressor = RBzip2.default_adapter::Decompressor.new(data)
27
+ buffer = RuneRb::Core::Buffer.new(mode: 'r')
28
+ buffer << decompressor.read
29
+ extracted = true
30
+ end
31
+
32
+ entry_count = buffer.read(type: :short)
33
+ identifiers = Array.new(entry_count)
34
+ extracted_sizes = Array.new(entry_count)
35
+ sizes = Array.new(entry_count)
36
+
37
+ entry_count.times do |i|
38
+ identifiers[i] = buffer.read(type: :int)
39
+ extracted_sizes[i] = buffer.read(type: :int24)
40
+ sizes[i] = buffer.read(type: :int24)
41
+ end
42
+
43
+ entries = Array.new(entry_count)
44
+ entry_count.times do |entry|
45
+ entry_buffer = RuneRb::Core::Buffer.new(mode: 'r')
46
+
47
+ if extracted == false
48
+ data = buffer.data.slice!(0..sizes[entry])
49
+ data = StringIO.new(data)
50
+ decompressor = RBzip2.default_adapter::Decompressor.new(data)
51
+ entry_buffer << decompressor.read
52
+ else
53
+ data = buffer.data.slice!(0..extracted_sizes[entry])
54
+ entry_buffer << data
55
+ end
56
+
57
+ entries[entry] = { id: identifiers[entry], buffer: entry_buffer }
58
+ end
59
+
60
+ RuneRb::Cache::Archive.new(entries)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,21 @@
1
+ module RuneRb::Cache::Constants
2
+ # The number of archives in the cache.
3
+ # @return [Integer]
4
+ ARCHIVE_COUNT = 0x9
5
+
6
+ # The size of a single index
7
+ # @return [Integer]
8
+ INDEX_SIZE = 0x6
9
+
10
+ # The size of a single data header
11
+ # @return [Integer]
12
+ HEADER_SIZE = 0x8
13
+
14
+ # The size of a chunk of data
15
+ # @return [Integer]
16
+ CHUNK_SIZE = 512
17
+
18
+ # The size of a single data block
19
+ # @return [Integer]
20
+ BLOCK_SIZE = HEADER_SIZE + CHUNK_SIZE;
21
+ end
@@ -0,0 +1,182 @@
1
+ module RuneRb::Cache
2
+ class FileSystem
3
+ include RuneRb::Core::Logging
4
+
5
+ # @attribute [r] cache
6
+ # @return [Hash<FileDescriptor, RuneRb::Cache::Archive>] a map of decoded archives.
7
+ attr_reader :cache
8
+
9
+ # @attribute [r] crc_table
10
+ # @return [RuneRb::Core::Buffer] the CRC table for the cache.
11
+ attr_reader :crc_table
12
+
13
+ # @attribute [r] crc
14
+ # @return [Array<Integer>] the CRC values for the cache.
15
+ attr_reader :crc
16
+
17
+ # @attribute [r] indicies
18
+ # @return [Array<StringIO>] the indicies for the cache.
19
+ attr_reader :indicies
20
+
21
+ # @attribute [r] data_file
22
+ # @return [StringIO] the data file for the cache.
23
+ attr_reader :data_file
24
+
25
+ # Constructs a new FileSystem instance.
26
+ # @param path [String] the path to the cache.
27
+ def initialize(path)
28
+ @indicies = Array.new
29
+ @crc_table = RuneRb::Core::Buffer.new(mode: 'r')
30
+ @crc = Array.new
31
+ @cache = Hash.new
32
+ @data_file = StringIO.new
33
+ read_layout(path)
34
+ end
35
+
36
+ # Retrieves an {RuneRb::Cache::Archive} by the specified {FileDescriptor}.
37
+ # @param type [Integer] the file type.
38
+ # @param file [Integer] the file identifier.
39
+ def archive(type, file)
40
+ descriptor = FileDescriptor.new(type, file)
41
+ cached = @cache[descriptor]
42
+
43
+ if cached == nil
44
+ file = cache_file(descriptor)
45
+ cached = RuneRb::Cache::Archive.decode(file)
46
+ @cache[descriptor] = cached
47
+ end
48
+
49
+ cached
50
+ end
51
+
52
+ # Retrieves a {RuneRb::Core::Buffer} that corresponds to the specified {FileDescriptor} in the cache.
53
+ # @param descriptor [FileDescriptor] the descriptor to retrieve.
54
+ # @raise [RuntimeError] if a Chunk id does not match what is expected during cache file read.
55
+ # @raise [RuntimeError] if a type does not match descriptor type during cache file read.
56
+ # @raise [RuntimeError] if a file identifier does not match descriptor file identifier during cache file read.
57
+ # @return [RuneRb::Core::Buffer] the buffer containing data that corresponds to the specified descriptor.
58
+ def cache_file(descriptor)
59
+ index = index_for(descriptor)
60
+ buffer = RuneRb::Core::Buffer.new(mode: 'r')
61
+
62
+ position = index.block * RuneRb::Cache::BLOCK_SIZE
63
+ read = 0
64
+ size = index.size
65
+ blocks = size / RuneRb::Cache::CHUNK_SIZE
66
+
67
+ if size % RuneRb::Cache::CHUNK_SIZE != 0
68
+ blocks += 1
69
+ end
70
+
71
+ info "Reading #{blocks} blocks from position #{position}."
72
+
73
+ blocks.times do |i|
74
+ @data_file.seek(position)
75
+ header = @data_file.read
76
+ header_data = header.unpack('C*')
77
+
78
+ position += RuneRb::Cache::HEADER_SIZE
79
+
80
+ next_file = header_data[0] << 8 | header_data[1]
81
+ current_chunk = header_data[2] << 8 | header_data[3]
82
+ next_block = header_data[4] << 16 | header_data[5] << 8 | header_data[6]
83
+ next_type = header_data[7]
84
+
85
+ raise "Chunk id mismatch! (Current #{current_chunk}, Expected #{i})" if current_chunk != i
86
+
87
+ chunk_size = size - read
88
+ chunk_size = RuneRb::Cache::CHUNK_SIZE if chunk_size > RuneRb::Cache::CHUNK_SIZE
89
+
90
+ @data_file.seek(position)
91
+ buffer << @data_file.read
92
+
93
+ read += chunk_size
94
+ position = next_block * RuneRb::Cache::BLOCK_SIZE
95
+
96
+ if size > read
97
+ raise "Next type (#{next_type}) does not match descriptor type (#{descriptor.type + 1})." if next_type != descriptor.type + 1
98
+ raise "Next file (#{next_file}) does not match descriptor file (#{descriptor.file})." if next_file != descriptor.file
99
+ end
100
+ end
101
+
102
+ info "Read #{buffer.length} from cache."
103
+
104
+ buffer
105
+ end
106
+
107
+ def index_for(descriptor)
108
+ idx = descriptor.type
109
+ raise "Index out of bounds. (#{idx})" if idx < 0 || idx >= @indicies.length
110
+
111
+ buffer = String.new
112
+ idx_file = @indicies[idx]
113
+ position = descriptor.file * RuneRb::Cache::INDEX_SIZE
114
+ info "Reading index from position #{position}"
115
+
116
+ if position >= 0 && (idx_file.length >= (position + RuneRb::Cache::INDEX_SIZE))
117
+ idx_file.seek(position, IO::SEEK_CUR)
118
+ buffer << idx_file.read
119
+ else
120
+ raise "Could not find index file at position #{position}."
121
+ end
122
+
123
+ info " Length: #{buffer.length}, Index data: #{buffer.bytes}"
124
+
125
+ RuneRb::Cache::Index.decode(buffer)
126
+ end
127
+
128
+ def close
129
+ @indicies.each(&:close)
130
+ @data_file.close
131
+ end
132
+
133
+ # The number of index files in the cache.
134
+ # @return [Integer] the number of index files in the cache.
135
+ def cache_count
136
+ @indicies.length
137
+ end
138
+
139
+ # The number of files in a cache.
140
+ # @param cache [Integer] the cache to check.
141
+ def file_count(cache)
142
+ (@indicies[cache].size / RuneRb::Core::INDEX_SIZE) - 1
143
+ end
144
+
145
+ # Reads the layout of the cache from the specified path.
146
+ # @param path [String] the path to the cache directory.
147
+ # @raise [RuntimeError] if the cache archive is not found.
148
+ def read_layout(path)
149
+ raise "Cache archive not found. Please install them into the #{path} directory." unless check_for_archives(path)
150
+
151
+ # Find how many index files exist
152
+ count = 0.upto(255).each do |i|
153
+ break i unless File.exist?(File.join(path, "main_file_cache.idx#{i}"))
154
+ end
155
+
156
+ # Gather file objects
157
+ @data_file = File.open(File.join(path, "main_file_cache.dat"), "r")
158
+
159
+ count.times do |i|
160
+ data = File.read("#{path}/main_file_cache.idx#{i}")
161
+ @indicies[i] = StringIO.new(data)
162
+ end
163
+ end
164
+
165
+ # Checks for the existence of cache archives in a path.
166
+ # @param path [String] the path to the cache directory.
167
+ def check_for_archives(path)
168
+ return false if path.nil?
169
+ return false unless File.directory?(path)
170
+ return false unless File.exist?(path)
171
+ return false unless File.readable?(path)
172
+ return false if Dir.empty?(path)
173
+ true
174
+ end
175
+
176
+ FileDescriptor = Struct.new(:type, :file) do
177
+ def equals(other)
178
+ other.file == file && other.type == type
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,37 @@
1
+ module RuneRb::Cache
2
+ # An instance of a {CacheIndex} points to a file in the `main_file_cache.dat` file.
3
+ class Index
4
+ include RuneRb::Core::Logging
5
+
6
+ # @!attribute [r] size
7
+ # @return [Integer] the size of the file.
8
+ # @note This attribute is read-only.
9
+ attr_reader :size
10
+
11
+ # @!attribute [r] block
12
+ # @return [Integer] the block of the file.
13
+ # @note This attribute is read-only.
14
+ attr_reader :block
15
+
16
+ # Constructs a new Cache Index given the block size and identifier.
17
+ # @param size [Integer] the size of the block file
18
+ # @param block [Integer] the first block of the file
19
+ def initialize(size, block)
20
+ @size = size
21
+ @block = block
22
+ end
23
+
24
+ # Decodes a buffer into an index.
25
+ # @param buffer [String] the buffer to decode.
26
+ def self.decode(buffer)
27
+ #raise "Unexpected buffer length. Buffer #{buffer.bytesize}, Expected: #{RuneRb::Core::INDEX_SIZE}" unless buffer.bytesize == RuneRb::Core::INDEX_SIZE
28
+
29
+ bytes = buffer.unpack('C*')
30
+ size = bytes[0] << 16 | bytes[1] << 8 | bytes[2]
31
+ block = bytes[3] << 16 | bytes[4] << 8 | bytes[5]
32
+ info "Decoded index: size: #{size}, block: #{block}"
33
+
34
+ RuneRb::Cache::Index.new(size, block)
35
+ end
36
+ end
37
+ end
data/lib/rune/common.rb CHANGED
@@ -35,6 +35,15 @@ module RuneRb
35
35
  autoload :SetRefinements, 'rune/patches/set_refinements'
36
36
  end
37
37
 
38
+ module Cache
39
+ autoload :Archive, 'rune/cache/archive'
40
+ autoload :Constants, 'rune/cache/constants'
41
+ autoload :FileSystem, 'rune/cache/file_system'
42
+ autoload :Index, 'rune/cache/index'
43
+
44
+ include RuneRb::Cache::Constants
45
+ end
46
+
38
47
  # The Logger utility for the RuneRb framework.
39
48
  # @return [Console::Logger] the logger instance.
40
49
  def self.logger
@@ -3,6 +3,11 @@ module RuneRb::Core
3
3
  # A Buffer encapsulates raw data in a String instance. Depending on the mode, the buffer can be read from or written to.
4
4
  class Buffer
5
5
 
6
+ # @!attribute [r] data
7
+ # @return [String] the data contained in the buffer.
8
+ # @note This attribute is read-only.
9
+ attr_reader :data
10
+
6
11
  # Constructs a new Buffer instance.
7
12
  # @param mode [String] the mode of the buffer.
8
13
  def initialize(mode: 'rw')
@@ -19,6 +19,10 @@ module RuneRb::Core::Constants
19
19
  # @return [Array<Integer>]
20
20
  BIT_MASK_OUT = (0...32).collect { (1 << _1) - 1 }.freeze
21
21
 
22
+ # The number of archives in the cache.
23
+ # @return [Integer]
24
+ ARCHIVE_COUNT = 0x9
25
+
22
26
  # The size of a single index
23
27
  # @return [Integer]
24
28
  INDEX_SIZE = 0x6
@@ -41,4 +45,4 @@ module RuneRb::Core::Constants
41
45
  BIG: [0, 1, 2].freeze,
42
46
  LITTLE: [2, 1, 0].freeze
43
47
  }.freeze
44
- end
48
+ end
@@ -10,11 +10,7 @@ module RuneRb::Core
10
10
  @cc = 0
11
11
  @mm = []
12
12
  @randrsl = Array.new(256, 0)
13
-
14
- seed.each_with_index do |element, i|
15
- @randrsl[i] = element
16
- end
17
-
13
+ seed.each_with_index { |element, i| @randrsl[i] = element }
18
14
  randinit
19
15
  end
20
16
 
@@ -52,18 +52,14 @@ module RuneRb::Core::WriteableBuffer
52
52
  # @param value [Integer] the medium value to write.
53
53
  # @param mutation [String] the mutation made to the byte.
54
54
  # @param order [String] the order in which bytes will be written.
55
- def write_int24(value, mutation: :STD, signed: false, order: :BIG)
55
+ def write_int24(value, mutation: :STD, order: :BIG)
56
56
  case order
57
57
  when :BIG
58
58
  write_byte(value >> 16)
59
59
  write_byte(value >> 8)
60
- write_byte(value, mutation: mutation, signed: signed)
61
- when :MIDDLE
62
- write_byte(value >> 8)
63
- write_byte(value, mutation: mutation, signed: signed)
64
- write_byte(value >> 16)
60
+ write_byte(value, mutation: mutation)
65
61
  when :LITTLE
66
- write_byte(value, mutation: mutation, signed: signed)
62
+ write_byte(value, mutation: mutation)
67
63
  write_byte(value >> 8)
68
64
  write_byte(value >> 16)
69
65
  else raise "Unrecognized byte order: #{order}"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rrb-common
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick W.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-09 00:00:00.000000000 Z
11
+ date: 2024-04-28 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rbzip2
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: dotenv
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +170,10 @@ executables: []
156
170
  extensions: []
157
171
  extra_rdoc_files: []
158
172
  files:
173
+ - lib/rune/cache/archive.rb
174
+ - lib/rune/cache/constants.rb
175
+ - lib/rune/cache/file_system.rb
176
+ - lib/rune/cache/index.rb
159
177
  - lib/rune/common.rb
160
178
  - lib/rune/core/archive.rb
161
179
  - lib/rune/core/buffer.rb
@@ -187,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
205
  - !ruby/object:Gem::Version
188
206
  version: '0'
189
207
  requirements: []
190
- rubygems_version: 3.4.10
208
+ rubygems_version: 3.5.3
191
209
  signing_key:
192
210
  specification_version: 4
193
211
  summary: Common utilities for RuneRb.