rrb-common 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 339ea3353a55193acc1cbe6fcb8dc51f9731f72e9ffffeb864c10f4167c1cd84
4
+ data.tar.gz: eff3b5a43e2efaed07990b15be1dfb42547bfbdc16cd980f6589f193cc91b258
5
+ SHA512:
6
+ metadata.gz: 7e2a4ccef86a0fbea08fc8c2ab5a143e350225df42d6d1a8ca56e1d97723429c8294fc2c1802c5dbde2b683e7c5f09e88989f829e0ef73a8c23b03e6d0a2083d
7
+ data.tar.gz: 58aca74385f3e52b34d9252954481ddc388bcadd47b2203a58ca46033db0f851efba59fc6fb11193f3e9ad7726d6cbe2155b0f328e31c7b1f105d41374566725
@@ -0,0 +1,75 @@
1
+ module RuneRb::Network
2
+
3
+ # A Buffer encapsulates raw data in a String instance. Depending on the mode, the buffer can be read from or written to.
4
+ class Buffer
5
+
6
+ # Constructs a new Buffer instance.
7
+ # @param capacity [Integer] the capacity of the buffer.
8
+ # @param mode [String] the mode of the buffer.
9
+ def initialize(mode: 'rw')
10
+ @data = String.new
11
+ @mode = mode
12
+ raise StandardError, 'Buffer mode must include "r" or "w".' unless @mode.include?('r') || @mode.include?('w')
13
+
14
+ enable_readable if @mode.include?('r')
15
+ enable_writeable if @mode.include?('w')
16
+ end
17
+
18
+ # Returns a snapshot of the buffer.
19
+ # @return [String] a snapshot of the buffer.
20
+ def snapshot
21
+ @data.dup
22
+ end
23
+
24
+ # Returns the limit of the buffer.
25
+ # @return [Integer] the limit of the buffer.
26
+ def length
27
+ @data.bytesize
28
+ end
29
+
30
+ # Adds raw data to the buffer. Flips the buffer if it is readable.
31
+ # @param data [String] the data to add.
32
+ def <<(data)
33
+ @data << data
34
+ end
35
+
36
+ # Is the <Buffer> instance readable?
37
+ # @return [Boolean] true if the <Buffer> instance is readable, false otherwise.
38
+ def readable?
39
+ @mode.include?('r')
40
+ end
41
+
42
+ # Is the <Buffer> instance writeable?
43
+ # @return [Boolean] true if the <Buffer> instance is writeable, false otherwise.
44
+ def writeable?
45
+ @mode.include?('w')
46
+ end
47
+
48
+ # Mutates the value according to the passed mutation
49
+ # @param value [Integer] the value to mutate
50
+ # @param mutation [Symbol] the mutation to apply to the value.
51
+ def mutate(value, mutation)
52
+ case mutation
53
+ when :STD then value
54
+ when :ADD then value + 128
55
+ when :NEG then -value
56
+ when :SUB then value - 128
57
+ else mutate(value, :STD)
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ # Enables read functions on the buffer instance. Bit Access is disabled by default. Sets the bit position to 0.
64
+ def enable_readable
65
+ singleton_class.include(RuneRb::Network::Readable)
66
+ @bit_access = false
67
+ @bit_position = 0
68
+ end
69
+
70
+ # Enables write functions on the buffer instance.
71
+ def enable_writeable
72
+ singleton_class.include(RuneRb::Network::Writeable)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,21 @@
1
+ module RuneRb::Network::Constants
2
+ # Acceptable byte orders in which multi-byte values can be read.
3
+ # @return [Array<Symbol>]
4
+ BYTE_ORDERS = %i[BIG MIDDLE INVERSE_MIDDLE LITTLE].freeze
5
+
6
+ # The size of one byte
7
+ # @return [Integer]
8
+ BYTE_SIZE = 8
9
+
10
+ # Valid byte mutations
11
+ # @return [Array<Symbol>]
12
+ BYTE_MUTATIONS = %i[ADD NEG SUB STD].freeze
13
+
14
+ # Valid types for reading/writing
15
+ # @return [Array<Symbol>]
16
+ RW_TYPES = %i[bits bit byte bytes medium int long reverse_bytes short smart string].freeze
17
+
18
+ # Bit masks for bit packing
19
+ # @return [Array<Integer>]
20
+ BIT_MASK_OUT = (0...32).collect { (1 << _1) - 1 }.freeze
21
+ end
@@ -0,0 +1,219 @@
1
+ module RuneRb::Network
2
+ # An implementation of an ISAAC cipher used to generate random numbers for message interchange.
3
+ class ISAAC
4
+ using RuneRb::Patches::IntegerRefinements
5
+
6
+ # Called when a new ISAAC Cipher is created.
7
+ def initialize(seed)
8
+ @aa = 0
9
+ @bb = 0
10
+ @cc = 0
11
+ @mm = []
12
+ @randrsl = Array.new(256, 0)
13
+
14
+ seed.each_with_index do |element, i|
15
+ @randrsl[i] = element
16
+ end
17
+
18
+ randinit
19
+ end
20
+
21
+ # Gets the next random value.
22
+ # If 256 cycles have occurred, the results array is regenerated.
23
+ def next_value
24
+ if @randcnt.zero?
25
+ isaac
26
+ @randcnt = 256
27
+ end
28
+ @randcnt -= 1
29
+ @randrsl[@randcnt].signed(:i)
30
+ end
31
+
32
+ private
33
+
34
+ # Generates 256 new results.
35
+ def isaac
36
+ r = @randrsl
37
+ aa = @aa
38
+ @cc += 1
39
+ bb = (@bb + (@cc)) & 0xffffffff
40
+ x = y = 0
41
+
42
+ (0...256).step(4) do |i|
43
+ x = @mm[i]
44
+ aa = ((aa ^ (aa << 13)) + @mm[(i + 128) & 0xff])
45
+ aa &= 0xffffffff
46
+ @mm[i] = y = (@mm[(x >> 2) & 0xff] + aa + bb) & 0xffffffff
47
+ r[i] = bb = (@mm[(y >> 10) & 0xff] + x) & 0xffffffff
48
+ x = @mm[i + 1]
49
+ aa = ((aa ^ (0x03ffffff & (aa >> 6))) + @mm[(i + 1 + 128) & 0xff])
50
+ aa &= 0xffffffff
51
+ @mm[i + 1] = y = (@mm[(x >> 2) & 0xff] + aa + bb) & 0xffffffff
52
+ r[i + 1] = bb = (@mm[(y >> 10) & 0xff] + x) & 0xffffffff
53
+ x = @mm[i + 2]
54
+ aa = ((aa ^ (aa << 2)) + @mm[(i + 2 + 128) & 0xff])
55
+ aa &= 0xffffffff
56
+ @mm[i + 2] = y = (@mm[(x >> 2) & 0xff] + aa + bb) & 0xffffffff
57
+ r[i + 2] = bb = (@mm[(y >> 10) & 0xff] + x) & 0xffffffff
58
+ x = @mm[i + 3]
59
+ aa = ((aa ^ (0x0000ffff & (aa >> 16))) + @mm[(i + 3 + 128) & 0xff])
60
+ aa &= 0xffffffff
61
+ @mm[i + 3] = y = (@mm[(x >> 2) & 0xff] + aa + bb) & 0xffffffff
62
+ r[i + 3] = bb = (@mm[(y >> 10) & 0xff] + x) & 0xffffffff
63
+ end
64
+
65
+ @bb = bb
66
+ @aa = aa
67
+ end
68
+
69
+ # Initializes the memory array.
70
+ def randinit
71
+ c = d = e = f = g = h = j = k = 0x9e3779b9
72
+ r = @randrsl
73
+
74
+ 4.times do
75
+ c = c ^ (d << 11)
76
+ f += c
77
+ d += e
78
+ d = d ^ (0x3fffffff & (e >> 2))
79
+ g += d
80
+ e += f
81
+ e = e ^ (f << 8)
82
+ h += e
83
+ f += g
84
+ f = f ^ (0x0000ffff & (g >> 16))
85
+ j += f
86
+ g += h
87
+ g = g ^ (h << 10)
88
+ k += g
89
+ h += j
90
+ h = h ^ (0x0fffffff & (j >> 4))
91
+ c += h
92
+ j += k
93
+ j = j ^ (k << 8)
94
+ d += j
95
+ k += c
96
+ k = k ^ (0x007fffff & (c >> 9))
97
+ e += k
98
+ c += d
99
+ end
100
+
101
+ (0...256).step(8) do |i|
102
+ c += r[i]
103
+ d += r[i + 1]
104
+ e += r[i + 2]
105
+ f += r[i + 3]
106
+ g += r[i + 4]
107
+ h += r[i + 5]
108
+ j += r[i + 6]
109
+ k += r[i + 7]
110
+ c = c ^ (d << 11)
111
+ f += c
112
+ d += e
113
+ d = d ^ (0x3fffffff & (e >> 2))
114
+ g += d
115
+ e += f
116
+ e = e ^ (f << 8)
117
+ h += e
118
+ f += g
119
+ f = f ^ (0x0000ffff & (g >> 16))
120
+ j += f
121
+ g += h
122
+ g = g ^ (h << 10)
123
+ k += g
124
+ h += j
125
+ h = h ^ (0x0fffffff & (j >> 4))
126
+ c += h
127
+ j += k
128
+ j = j ^ (k << 8)
129
+ d += j
130
+ k += c
131
+ k = k ^ (0x007fffff & (c >> 9))
132
+ e += k
133
+ c += d
134
+ @mm[i] = c
135
+ @mm[i + 1] = d
136
+ @mm[i + 2] = e
137
+ @mm[i + 3] = f
138
+ @mm[i + 4] = g
139
+ @mm[i + 5] = h
140
+ @mm[i + 6] = j
141
+ @mm[i + 7] = k
142
+ end
143
+
144
+ (0...256).step(8) do |i|
145
+ c += @mm[i]
146
+ d += @mm[i + 1]
147
+ e += @mm[i + 2]
148
+ f += @mm[i + 3]
149
+ g += @mm[i + 4]
150
+ h += @mm[i + 5]
151
+ j += @mm[i + 6]
152
+ k += @mm[i + 7]
153
+ c = c ^ (d << 11)
154
+ f += c
155
+ d += e
156
+ d = d ^ (0x3fffffff & (e >> 2))
157
+ g += d
158
+ e += f
159
+ e = e ^ (f << 8)
160
+ h += e
161
+ f += g
162
+ f = f ^ (0x0000ffff & (g >> 16))
163
+ j += f
164
+ g += h
165
+ g = g ^ (h << 10)
166
+ k += g
167
+ h += j
168
+ h = h ^ (0x0fffffff & (j >> 4))
169
+ c += h
170
+ j += k
171
+ j = j ^ (k << 8)
172
+ d += j
173
+ k += c
174
+ k = k ^ (0x007fffff & (c >> 9))
175
+ e += k
176
+ c += d
177
+ @mm[i] = c
178
+ @mm[i + 1] = d
179
+ @mm[i + 2] = e
180
+ @mm[i + 3] = f
181
+ @mm[i + 4] = g
182
+ @mm[i + 5] = h
183
+ @mm[i + 6] = j
184
+ @mm[i + 7] = k
185
+ end
186
+
187
+ isaac
188
+ @randcnt = 256
189
+ end
190
+ end
191
+ end
192
+
193
+ # Copyright (c) 2021, Patrick W.
194
+ # All rights reserved.
195
+ #
196
+ # Redistribution and use in source and binary forms, with or without
197
+ # modification, are permitted provided that the following conditions are met:
198
+ #
199
+ # * Redistributions of source code must retain the above copyright notice, this
200
+ # list of conditions and the following disclaimer.
201
+ #
202
+ # * Redistributions in binary form must reproduce the above copyright notice,
203
+ # this list of conditions and the following disclaimer in the documentation
204
+ # and/or other materials provided with the distribution.
205
+ #
206
+ # * Neither the name of the copyright holder nor the names of its
207
+ # contributors may be used to endorse or promote products derived from
208
+ # this software without specific prior written permission.
209
+ #
210
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
211
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
212
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
213
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
214
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
215
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
216
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
217
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
218
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
219
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,220 @@
1
+ # The Readable module contains the functions used to read data from a {Buffer} object.
2
+ module RuneRb::Network::Readable
3
+ using RuneRb::Patches::IntegerRefinements
4
+
5
+ # @!attribute [r] bit_access
6
+ # @return [Boolean] is {bit_access} enabled?
7
+ attr_reader :bit_access
8
+
9
+ # @!attribute [r] bit_position
10
+ # @return [Integer] the current bit position.
11
+ attr_reader :bit_position
12
+
13
+
14
+ # Read data from the payload according to the option parameter.
15
+ # @param type [Symbol] the type of database to read
16
+ # @param mutation [Symbol] an option mutation to apply to the read value.
17
+ def read(type: :byte, signed: false, mutation: :STD, order: :BIG, options: nil)
18
+ case type
19
+ when :bits then read_bits(options[:amount])
20
+ when :byte then read_byte(signed:, mutation:)
21
+ when :bytes then read_bytes(options[:amount] || 1, mutation:)
22
+ when :short then read_short(signed:, mutation:, order:)
23
+ when :int24 then read_int24(signed:, mutation:, order:)
24
+ when :int then read_int(signed:, mutation:, order:)
25
+ when :long then read_long(signed:, mutation:, order:)
26
+ when :smart then read_smart(signed:, mutation:)
27
+ when :string then read_string
28
+ when :reverse_bytes then read_bytes_reverse(options[:amount] || 1, mutation:)
29
+ else raise "Unrecognized read type! #{type}"
30
+ end
31
+ end
32
+
33
+ # Enables or Disables bit reading by setting the {Buffer#bit_access} variable.
34
+ def switch_access
35
+ @bit_access = !@bit_access
36
+ end
37
+
38
+ # Completes a bit access by setting the {Buffer#bit_position} to the start of the next byte, then toggling {bit_access}.
39
+ def finish_access
40
+ @bit_position = (@bit_position + 7) / 8
41
+ switch_access
42
+ end
43
+
44
+ private
45
+
46
+ # Read multiple bytes from the {Buffer#data}
47
+ # @param amount [Integer] the amount of bytes to read
48
+ # @param mutation [Symbol] the mutation to apply to read bytes.
49
+ def read_bytes(amount, mutation)
50
+ amount.times.each_with_object([]) { |_idx, arr| arr << read_byte(signed: false, mutation:) }
51
+ end
52
+
53
+ # Probably did this wrong
54
+ # @param amount [Integer] the amount of bytes to read
55
+ # @param mutation [Symbol] an optional mutation to apply to the result.
56
+ def read_bytes_reverse(amount, mutation)
57
+ @data.flip
58
+ value = amount.times.each_with_object([]) { value << read_byte(signed: false, mutation:) }
59
+ @data.flip
60
+ value
61
+ end
62
+
63
+ # Read a byte value from the {Buffer#data}
64
+ # @param signed [Boolean] should the value be signed.
65
+ # @param mutation [Symbol] mutation that should be applied to the byte value.
66
+ # @return [Integer] the read byte value.
67
+ def read_byte(mutation: :STD, signed: false)
68
+ directive = signed ? 'c' : 'C'
69
+ value = @data.slice!(0).unpack1(directive)
70
+ mutate(value, mutation)
71
+ end
72
+
73
+ # Reads a short value from the {Buffer#data}
74
+ # @param signed [Boolean] should the value be signed.
75
+ # @param mutation [String] mutation that should be applied to the short value
76
+ # @param order [Symbol] they byte order to read the short value
77
+ def read_short(signed: false, mutation: :STD, order: :BIG)
78
+ directive = "#{signed ? 's' : 'S'}"
79
+ directive << case order
80
+ when :BIG then '>'
81
+ when :LITTLE then '<'
82
+ else ''
83
+ end
84
+ value = @data.slice!(0..1).unpack1(directive)
85
+ mutate(value, mutation)
86
+ end
87
+
88
+ # Reads a 24-Bit Integer value from the {Buffer#data}
89
+ # @param signed [Boolean] should the value be signed.
90
+ # @param mutation [Symbol] mutation that should be applied to the value
91
+ # @param order [String] they byte order to read the value
92
+ def read_int24(signed: false, mutation: :STD, order: :BIG)
93
+ unpacked = @data.slice!(0..2).unpack('C3')
94
+ case order
95
+ when :BIG
96
+ if signed
97
+ value = (unpacked[0] << 16) | (unpacked[1] << 8) | unpacked[2]
98
+ unpacked[0] & 0x80 != 0 ? value - 0x10000 : value
99
+ else
100
+ (unpacked[0] << 16) | (unpacked[1] << 8) | unpacked[2]
101
+ end
102
+ when :MIDDLE
103
+ if signed
104
+ value = (unpacked[1] << 16) | (unpacked[2] << 8) | unpacked[0]
105
+ unpacked[1] & 0x80 != 0 ? value - 0x10000 : value
106
+ else
107
+ (unpacked[1] << 16) | (unpacked[2] << 8) | unpacked[0]
108
+ end
109
+ when :LITTLE
110
+ if signed
111
+ value = (unpacked[2] << 16) | (unpacked[1] << 8) | unpacked[0]
112
+ unpacked[0] & 0x80 != 0 ? value - 0x10000 : value
113
+ else
114
+ (unpacked[2] << 16) | (unpacked[1] << 8) | unpacked[0]
115
+ end
116
+ else read_int24(signed:, mutation:, order: :BIG)
117
+ end
118
+ end
119
+
120
+ # Reads a integer value from the {Buffer#data}
121
+ # @param signed [Boolean] should the value be signed.
122
+ # @param mutation [Symbol] mutation that should be applied to the integer value
123
+ # @param order [String] they byte order to read the integer value
124
+ def read_int(signed: false, mutation: :STD, order: :BIG)
125
+ case order
126
+ when :BIG
127
+ directive = signed ? 'l>' : 'L>'
128
+ value = @data.slice!(0..3).unpack1(directive)
129
+ mutate(value, mutation)
130
+ when :MIDDLE
131
+ (read_byte(signed:) << 8) | read_byte(signed:, mutation:) | (read_byte(signed:) << 24) | (read_byte(signed:) << 16)
132
+ when :INVERSE_MIDDLE
133
+ (read_byte(signed:) << 16) | (read_byte(signed:) << 24) | read_byte(signed:, mutation:) | (read_byte(signed:) << 8)
134
+ when :LITTLE
135
+ directive = signed ? 'l<' : 'L<'
136
+ value = @data.slice!(0..3).unpack1(directive)
137
+ mutate(value, mutation)
138
+ else read_int(signed:, mutation:, order: :BIG)
139
+ end
140
+ end
141
+
142
+ # Reads a long value from the {Buffer#data}
143
+ # @param signed [Boolean] should the value be signed.
144
+ # @param mutation [Symbol] mutation that should be applied to the long value
145
+ # @param order [String] they byte order to read the long value
146
+ def read_long(signed: false, mutation: :STD, order: :BIG)
147
+ case order
148
+ when :BIG
149
+ directive = signed ? 'q>' : 'Q>'
150
+ value = @data.slice!(0..7).unpack1(directive)
151
+ mutate(value, mutation)
152
+ when :LITTLE
153
+ directive = signed ? 'q<' : 'Q<'
154
+ value = @data.slice!(0..7).unpack1(directive)
155
+ mutate(value, mutation)
156
+ else read_long(signed:, mutation:, order: :BIG)
157
+ end
158
+ end
159
+
160
+ # Read a smart value from the {Buffer#data}
161
+ # @param signed [Boolean] should the value be signed.
162
+ # @param mutation [Symbol] mutation that should be applied to the long value
163
+ def read_smart(signed: false, mutation: :STD)
164
+ peek = read_byte(signed:, mutation:)
165
+
166
+ if signed
167
+ if peek < 128
168
+ read_byte(signed:, mutation:) - 64
169
+ else
170
+ read_short(signed:, mutation:, order: :BIG) - 49_152
171
+ end
172
+ else
173
+ if peek < 128
174
+ read_byte(mutation:, signed:)
175
+ else
176
+ read_short(mutation:, signed:, order: :BIG) - 32_768
177
+ end
178
+ end
179
+ end
180
+
181
+ # Reads a string from the {Buffer#data}
182
+ # @return [String] the resulting string.
183
+ def read_string
184
+ val = ''
185
+ while (res = @data.slice!(0))
186
+ break if res == "\n"
187
+
188
+ val << res
189
+ end
190
+ val
191
+ end
192
+ end
193
+
194
+ # Copyright (c) 2021, Patrick W.
195
+ # All rights reserved.
196
+ #
197
+ # Redistribution and use in source and binary forms, with or without
198
+ # modification, are permitted provided that the following conditions are met:
199
+ #
200
+ # * Redistributions of source code must retain the above copyright notice, this
201
+ # list of conditions and the following disclaimer.
202
+ #
203
+ # * Redistributions in binary form must reproduce the above copyright notice,
204
+ # this list of conditions and the following disclaimer in the documentation
205
+ # and/or other materials provided with the distribution.
206
+ #
207
+ # * Neither the name of the copyright holder nor the names of its
208
+ # contributors may be used to endorse or promote products derived from
209
+ # this software without specific prior written permission.
210
+ #
211
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
212
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
213
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
214
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
215
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
216
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
217
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
218
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
219
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
220
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,224 @@
1
+ # The Writeable module contains functions for writing data to a {Buffer} object.
2
+ module RuneRb::Network::Writeable
3
+
4
+ # Write data to the payload.
5
+ # @param value [Integer, String, Message, Array] the value to write.
6
+ # @param type [Symbol] the type of value to write.
7
+ # @param mutation [Symbol] an option mutation to apply to the value.
8
+ # @param order [Symbol] the byte order to write the value.
9
+ def write(value, type: :byte, mutation: :STD, signed: false, order: :BIG, options: {})
10
+ case type
11
+ when :bits then write_bits(value, options[:amount] || 1)
12
+ when :bit then write_bit(value)
13
+ when :byte then write_byte(value, mutation: mutation)
14
+ when :bytes then write_bytes(value)
15
+ when :short then write_short(value, mutation: mutation, order: order)
16
+ when :int24 then write_int24(value, mutation: mutation, order: order)
17
+ when :int then write_int(value, mutation: mutation, order: order)
18
+ when :long then write_long(value, mutation: mutation, order: order)
19
+ when :smart then write_smart(value, mutation: mutation, signed: signed)
20
+ when :string then write_string(value)
21
+ when :reverse_bytes then write_reverse_bytes(value)
22
+ else raise "Unrecognized write type! #{type}"
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ # Write a byte value to the payload.
29
+ # @param value [Integer] the byte value to write.
30
+ # @param mutation [String] mutations made to the byte.
31
+ def write_byte(value, mutation: :STD, signed: false)
32
+ @data << [mutate(value, mutation)].pack(signed ? 'c' : 'C')
33
+ end
34
+
35
+ # Write a short value to the payload.
36
+ # @param value [Integer] the short value to write.
37
+ # @param mutation [String] the type of byte to write.
38
+ # @param order [String] the order in which bytes will be written.
39
+ def write_short(value, mutation: :STD, signed: false, order: :BIG)
40
+ case order
41
+ when :BIG
42
+ write_byte(value >> 8)
43
+ write_byte(value, mutation: mutation, signed: signed)
44
+ when :LITTLE
45
+ write_byte(value, mutation: mutation, signed: signed)
46
+ write_byte(value >> 8)
47
+ else raise "Unrecognized bit order: #{order}"
48
+ end
49
+ end
50
+
51
+ # Write a int24 value to the payload.
52
+ # @param value [Integer] the medium value to write.
53
+ # @param mutation [String] the mutation made to the byte.
54
+ # @param order [String] the order in which bytes will be written.
55
+ def write_int24(value, mutation: :STD, signed: false, order: :BIG)
56
+ case order
57
+ when :BIG
58
+ write_byte(value >> 16)
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)
65
+ when :LITTLE
66
+ write_byte(value, mutation: mutation, signed: signed)
67
+ write_byte(value >> 8)
68
+ write_byte(value >> 16)
69
+ else raise "Unrecognized byte order: #{order}"
70
+ end
71
+ end
72
+
73
+ # Write a integer value to the payload.
74
+ # @param value [Integer] the integer value to write.
75
+ # @param mutation [String] the type of byte to write.
76
+ # @param order [String] the order in which bytes will be written.
77
+ def write_int(value, mutation: :STD, signed: false, order: :BIG)
78
+ case order
79
+ when :BIG
80
+ write_byte(value >> 24)
81
+ write_byte(value >> 16)
82
+ write_byte(value >> 8)
83
+ write_byte(value, mutation: mutation, signed: signed)
84
+ when :MIDDLE
85
+ write_byte(value >> 8)
86
+ write_byte(value, mutation: mutation, signed: signed)
87
+ write_byte(value >> 24)
88
+ write_byte(value >> 16)
89
+ when :INVERSE_MIDDLE
90
+ write_byte(value >> 16)
91
+ write_byte(value >> 24)
92
+ write_byte(value, mutation: mutation, signed: signed)
93
+ write_byte(value >> 8)
94
+ when :LITTLE
95
+ write_byte(value, mutation: mutation, signed: signed)
96
+ write_byte(value >> 8)
97
+ write_byte(value >> 16)
98
+ write_byte(value >> 24)
99
+ else raise "Unrecognized byte order: #{order}"
100
+ end
101
+ end
102
+
103
+ # Write a long value to the payload.
104
+ # @param value [Integer] the long value to write.
105
+ # @param mutation [String] the type of byte to write.
106
+ # @param order [String] the order in which bytes will be written.
107
+ def write_long(value, mutation: :STD, signed: false, order: :BIG)
108
+ case order
109
+ when :BIG
110
+ (RuneRb::Network::BYTE_SIZE * 7).downto(0) { |div| ((div % 8).zero? and div.positive?) ? write_byte(value >> div) : next }
111
+ write_byte(value, mutation: mutation, signed: signed)
112
+ when :LITTLE
113
+ write_byte(value, mutation: mutation, signed: signed)
114
+ (0).upto(RuneRb::Network::BYTE_SIZE * 7) { |div| ((div % 8).zero? and div.positive?) ? write_byte(value >> div) : next }
115
+ else raise "Unrecognized byte order: #{order}"
116
+ end
117
+ end
118
+
119
+ # Write a string value to the payload. This will be escaped/terminated with a \n[10] value.
120
+ # @param string [String, StringIO] the byte to write to the payload.
121
+ def write_string(string)
122
+ send(:<<, string)
123
+ send(:<<, [10].pack('C'))
124
+ end
125
+
126
+ # Write a 'smart' value to the payload.
127
+ #
128
+ # @param value [Integer] the smart value to write.
129
+ # @param mutation [String] an optional mutation to apply to the written smart value.
130
+ def write_smart(value, mutation: :STD, signed: false)
131
+ case signed
132
+ when true
133
+ value > 128 ? write_byte(value + 64, mutation: mutation, signed: signed) : write_short(value + 49_152, mutation: mutation, signed: signed)
134
+ when false
135
+ value > 128 ? write_byte(value, mutation: mutation, signed: signed) : write_short(value + 32_768, mutation: mutation, signed: signed)
136
+ end
137
+ end
138
+
139
+ # Writes multiple bytes to the payload.
140
+ # @param values [String, Array, Rune::Network::Buffer] the values whose bytes will be written.
141
+ def write_bytes(values)
142
+ case values
143
+ when Array then values.each { |byte| write_byte(byte.to_i) }
144
+ when RuneRb::Network::Packet then send(:put, values.snapshot)
145
+ when RuneRb::Network::Buffer then send(:put, values)
146
+ when String then send(:<<, values)
147
+ end
148
+ end
149
+
150
+ # Write a collection of bytes in reverse. *Not sure if I did this right.
151
+ # @param values [Array, String] the values to write.
152
+ def write_reverse_bytes(values)
153
+ case values
154
+ when Array then write(values.reverse, type: :bytes)
155
+ when String then write(values.bytes.reverse, type: :bytes)
156
+ end
157
+ end
158
+
159
+ # Write a single bit with a value of 1 or 0 depending on the flag parameter.
160
+ # @param flag [Boolean] the flag
161
+ def write_bit(flag)
162
+ write_bits(flag == true ? 1 : 0, 1)
163
+ self
164
+ end
165
+
166
+ # Write multiple bits to the payload
167
+ # @param amount [Integer] the amount of bits to occupy.
168
+ # @param value [Integer] the value to write.
169
+ def write_bits(value, amount)
170
+ byte_pos = @bit_position >> 3
171
+ bit_offset = 8 - (@bit_position & 7)
172
+ @bit_position += amount
173
+
174
+ while amount > bit_offset
175
+ @buffer[byte_pos] = [0].pack('c') if @buffer[byte_pos].nil?
176
+ @buffer[byte_pos] = [(@buffer[byte_pos].unpack1('c') & ~RuneRb::Network::BIT_MASK_OUT[bit_offset])].pack('c')
177
+ @buffer[byte_pos] = [(@buffer[byte_pos].unpack1('c') | (value >> (amount - bit_offset)) & RuneRb::Network::BIT_MASK_OUT[bit_offset])].pack('c')
178
+ byte_pos += 1
179
+ amount -= bit_offset
180
+ bit_offset = 8
181
+ end
182
+
183
+ @buffer[byte_pos] = [0].pack('c') if @buffer[byte_pos].nil?
184
+
185
+ if amount == bit_offset
186
+ @buffer[byte_pos] = [(@buffer[byte_pos].unpack1('c') & ~RuneRb::Network::BIT_MASK_OUT[bit_offset])].pack('c')
187
+ @buffer[byte_pos] = [(@buffer[byte_pos].unpack1('c') | (value & Rune::Network::BIT_MASK_OUT[bit_offset]))].pack('c')
188
+ else
189
+ @buffer[byte_pos] = [(@buffer[byte_pos].unpack1('c') & ~(RuneRb::Network::BIT_MASK_OUT[amount] << (bit_offset - amount)))].pack('c')
190
+ @buffer[byte_pos] = [(@buffer[byte_pos].unpack1('c') | ((value & RuneRb::Network::BIT_MASK_OUT[amount]) << (bit_offset - amount)))].pack('c')
191
+ end
192
+ end
193
+ end
194
+
195
+ ############################################################################################################
196
+ # Copyright (c) 2023, Patrick W. #
197
+ # All rights reserved. #
198
+ # #
199
+ # Redistribution and use in source and binary forms, with or without #
200
+ # modification, are permitted provided that the following conditions are met: #
201
+ # #
202
+ # * Redistributions of source code must retain the above copyright notice, this #
203
+ # list of conditions and the following disclaimer. #
204
+ # #
205
+ # * Redistributions in binary form must reproduce the above copyright notice, #
206
+ # this list of conditions and the following disclaimer in the documentation #
207
+ # and/or other materials provided with the distribution. #
208
+ # #
209
+ # * Neither the name of the copyright holder nor the names of its #
210
+ # contributors may be used to endorse or promote products derived from #
211
+ # this software without specific prior written permission. #
212
+ # #
213
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" #
214
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE #
215
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE #
216
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE #
217
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL #
218
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR #
219
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER #
220
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, #
221
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #
222
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #
223
+ # #
224
+ ############################################################################################################
@@ -0,0 +1,123 @@
1
+ # A module adding overflow functions to integers to mimic the behavior of Java primitive overflow behavior.
2
+ module RuneRb::Patches::IntegerRefinements
3
+ refine Integer do
4
+ # Returns a binary representation in the form of an array of 1's and 0's in their respective digits.
5
+ # @return [Array] the binary representation
6
+ def binary_representation
7
+ to_s(2).chars.map(&:to_i)
8
+ end
9
+
10
+ alias_method :brep, :binary_representation
11
+
12
+ # Returns a base 10 numeric from the passed array representation
13
+ # @param representation [Array] the representation used to generate the numeric
14
+ # @returns [Integer] the base 10 numeric of the representation.
15
+ def from_binary_rep(representation)
16
+ res = 0
17
+ representation.each_with_index do |bit, idx|
18
+ res += bit * (2**idx)
19
+ end
20
+ res
21
+ end
22
+
23
+ alias_method :from_brep, :from_binary_rep
24
+
25
+ # Adjusts the value of the Integer to be unsigned.
26
+ # @param type [Symbol] the type of primitive the value will be returned as
27
+ def unsigned(type)
28
+ return 0 if negative?
29
+ case type
30
+ when :Byte, :byte, :b, :B then to_i > 0xFF ? 0xFF : to_i
31
+ when :Short, :short, :s, :S then to_i > 0xFFFF ? 0xFFFF : to_i
32
+ when :Integer, :Int, :int, :integer, :i, :I then to_i > 0xFFFFFFFF ? 0xFFFFFFFF : to_i
33
+ when :Long, :long, :l, :L then to_i > 0xFFFFFFFFFFFFFFFF ? 0xFFFFFFFFFFFFFFFF : to_i
34
+ else unsigned(:int)
35
+ end
36
+ end
37
+
38
+ alias_method :u, :unsigned
39
+
40
+ # Adjusts the value of the Integer to be signed.
41
+ # @param type [Symbol] the type of primitive the value will be returned as
42
+ def signed(type)
43
+ case type
44
+ when :Byte, :byte, :b, :B then adjust(:byte)
45
+ when :Short, :short, :s, :S then adjust(:short)
46
+ when :Integer, :Int, :int, :integer, :i, :I then adjust(:integer)
47
+ when :Long, :long, :l, :L then adjust(:long)
48
+ else adjust(:integer)
49
+ end
50
+ end
51
+
52
+ alias_method :s, :signed
53
+
54
+ def nibble
55
+ adjust(:nibble)
56
+ end
57
+
58
+ # Returns a string with a formatted representation of the Integer as a timestamp.
59
+ def to_ftime
60
+ mm, ss = divmod(60)
61
+ hh, mm = mm.divmod(60)
62
+ dd, hh = hh.divmod(24)
63
+ format('%d days, %d hours, %d minutes, and %d seconds', dd, hh, mm, ss)
64
+ end
65
+
66
+ private
67
+
68
+ # Adjusts the integer based on the passed type
69
+ # @param type [Symbol] the type of adjustment to make to the integer.
70
+ def adjust(type)
71
+ case type
72
+ when :Byte, :byte, :b, :B
73
+ primitive_max = 2**7 - 1
74
+ primitive_min = -2**7
75
+ when :Short, :short, :s, :S
76
+ primitive_max = 2**15 - 1
77
+ primitive_min = -2**15
78
+ when :Integer, :Int, :int, :i, :I
79
+ primitive_max = 2**31 - 1
80
+ primitive_min = -2**31
81
+ when :Long, :long, :l, :L
82
+ primitive_max = 2**63 - 1
83
+ primitive_min = -2**63
84
+ when :Nibble, :nibble, :n, :N
85
+ primitive_max = 2**4
86
+ primitive_min = -2**4
87
+ else
88
+ primitive_max = 2**31 - 1
89
+ primitive_min = -2**31
90
+ end
91
+ self < -primitive_max ? -1 * (-self & primitive_max) : self
92
+ self > primitive_min ? (self & primitive_max) : self
93
+ end
94
+ end
95
+ end
96
+
97
+ # Copyright (c) 2021, Patrick W.
98
+ # All rights reserved.
99
+ #
100
+ # Redistribution and use in source and binary forms, with or without
101
+ # modification, are permitted provided that the following conditions are met:
102
+ #
103
+ # * Redistributions of source code must retain the above copyright notice, this
104
+ # list of conditions and the following disclaimer.
105
+ #
106
+ # * Redistributions in binary form must reproduce the above copyright notice,
107
+ # this list of conditions and the following disclaimer in the documentation
108
+ # and/or other materials provided with the distribution.
109
+ #
110
+ # * Neither the name of the copyright holder nor the names of its
111
+ # contributors may be used to endorse or promote products derived from
112
+ # this software without specific prior written permission.
113
+ #
114
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
115
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
116
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
117
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
118
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
119
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
120
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
121
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
122
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
123
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,43 @@
1
+ # Refinements made to the Set class of the ruby Core module.
2
+ module RuneRb::Patches::SetRefinements
3
+ refine Set do
4
+ # Consumes elements as they're passed to execution block.
5
+ # @param _ [Proc] the execution block
6
+ def each_consume(&_)
7
+ raise 'Nil block passed to Set#each_consume.' unless block_given?
8
+
9
+ each do |item|
10
+ yield(item)
11
+ delete(item)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ # Copyright (c) 2021, Patrick W.
18
+ # All rights reserved.
19
+ #
20
+ # Redistribution and use in source and binary forms, with or without
21
+ # modification, are permitted provided that the following conditions are met:
22
+ #
23
+ # * Redistributions of source code must retain the above copyright notice, this
24
+ # list of conditions and the following disclaimer.
25
+ #
26
+ # * Redistributions in binary form must reproduce the above copyright notice,
27
+ # this list of conditions and the following disclaimer in the documentation
28
+ # and/or other materials provided with the distribution.
29
+ #
30
+ # * Neither the name of the copyright holder nor the names of its
31
+ # contributors may be used to endorse or promote products derived from
32
+ # this software without specific prior written permission.
33
+ #
34
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
35
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
37
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
38
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
40
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
41
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
43
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/lib/rune.rb ADDED
@@ -0,0 +1,29 @@
1
+ Dir[File.dirname(__FILE__)].each { |file| $LOAD_PATH.unshift(file) if File.directory? file }
2
+
3
+ require 'nio/bytebuffer'
4
+
5
+ # <h1>RuneRb</h1>
6
+ # <p>A game server written in Ruby targeting the 2006 era (or the 317-377 protocols) of the popular MMORPG, RuneScape.</p>
7
+ #
8
+ #
9
+ # @author Patrick W.
10
+ # @since 0.0.1
11
+ module RuneRb
12
+
13
+ # The Network module contains all common network related classes and modules.
14
+ module Network
15
+ autoload :Buffer, 'rune/network/buffer'
16
+ autoload :Constants, 'rune/network/constants'
17
+ autoload :ISAAC, 'rune/network/isaac'
18
+ autoload :Readable, 'rune/network/readable'
19
+ autoload :Writeable, 'rune/network/writeable'
20
+
21
+ include Constants
22
+ end
23
+
24
+ # The Patches module contains all common patches to core classes.
25
+ module Patches
26
+ autoload :IntegerRefinements, 'rune/patches/integer_refinements'
27
+ autoload :SetRefinements, 'rune/patches/set_refinements'
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rrb-common
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Patrick W.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nio4r
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.5.9
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.5.9
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: benchmark
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.19'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.19'
97
+ - !ruby/object:Gem::Dependency
98
+ name: terminal-table
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ description: A set of common classes, modules, and functions for Rune.rb.
112
+ email: Sickday@pm.me
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - lib/rune.rb
118
+ - lib/rune/network/buffer.rb
119
+ - lib/rune/network/constants.rb
120
+ - lib/rune/network/isaac.rb
121
+ - lib/rune/network/readable.rb
122
+ - lib/rune/network/writeable.rb
123
+ - lib/rune/patches/integer_refinements.rb
124
+ - lib/rune/patches/set_refinements.rb
125
+ homepage:
126
+ licenses:
127
+ - BSD-3-Clause
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: 3.1.0
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubygems_version: 3.4.10
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Common utilities for RuneRb.
148
+ test_files: []