chichilku3 14.0.3 → 15.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.
- checksums.yaml +4 -4
- data/bin/chichilku3 +1 -0
- data/bin/chichilku3-server +1 -0
- data/lib/client/chichilku3.rb +3 -1
- data/lib/client/client.rb +112 -59
- data/lib/client/client_cfg.rb +2 -1
- data/lib/client/gui.rb +219 -197
- data/lib/client/img/stick128/arm64/arm0.png +0 -0
- data/lib/client/img/stick128/arm64/arm1.png +0 -0
- data/lib/client/img/stick128/arm64/arm2.png +0 -0
- data/lib/client/img/stick128/arm64/arm3.png +0 -0
- data/lib/client/img/stick128/noarms/stick0.png +0 -0
- data/lib/client/img/stick128/noarms/stick1.png +0 -0
- data/lib/client/img/stick128/noarms/stick2.png +0 -0
- data/lib/client/img/stick128/noarms/stick3.png +0 -0
- data/lib/client/img/stick128/noarms/stick4.png +0 -0
- data/lib/client/img/stick128/noarms/stick5.png +0 -0
- data/lib/client/keys.rb +29 -0
- data/lib/client/particles.rb +54 -0
- data/lib/client/scoreboard.rb +29 -27
- data/lib/{client → external/gosu}/text.rb +29 -38
- data/lib/external/rubyzip/recursive.rb +58 -0
- data/lib/server/chichilku3_server.rb +169 -64
- data/lib/server/gamelogic.rb +107 -51
- data/lib/server/server_cfg.rb +2 -0
- data/lib/share/config.rb +21 -7
- data/lib/share/console.rb +22 -5
- data/lib/share/game_map.rb +279 -0
- data/lib/share/math.rb +14 -0
- data/lib/share/network.rb +47 -42
- data/lib/share/player.rb +168 -105
- data/lib/share/projectile.rb +97 -98
- data/lib/share/string.rb +24 -0
- data/server.json +3 -2
- metadata +49 -23
- data/lib/client/img/battle1024x576.png +0 -0
- data/lib/client/img/grass1024x512.png +0 -0
- data/lib/client/img/stick128/stick_noarms.png +0 -0
- data/lib/client/test.rb +0 -39
data/lib/share/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'os'
|
3
5
|
require 'fileutils'
|
@@ -7,7 +9,7 @@ class Config
|
|
7
9
|
attr_reader :data, :chichilku3_dir
|
8
10
|
|
9
11
|
def initialize(console, file)
|
10
|
-
@chichilku3_dir =
|
12
|
+
@chichilku3_dir = ''
|
11
13
|
if OS.linux?
|
12
14
|
@chichilku3_dir = "#{ENV['HOME']}/.chichilku/chichilku3/"
|
13
15
|
elsif OS.mac?
|
@@ -15,13 +17,24 @@ class Config
|
|
15
17
|
# elsif OS.windows?
|
16
18
|
# @chichilku3_dir = "%APPDATA%\\chichilku\\chichilku3\\"
|
17
19
|
else
|
18
|
-
puts
|
20
|
+
puts 'os not supported.'
|
19
21
|
exit
|
20
22
|
end
|
21
|
-
puts "path:
|
23
|
+
puts "path: #{@chichilku3_dir}"
|
22
24
|
FileUtils.mkdir_p @chichilku3_dir
|
23
25
|
FileUtils.mkdir_p "#{@chichilku3_dir}recordings"
|
26
|
+
FileUtils.mkdir_p "#{@chichilku3_dir}maps_b64"
|
27
|
+
FileUtils.mkdir_p "#{@chichilku3_dir}downloadedmaps"
|
28
|
+
FileUtils.mkdir_p "#{@chichilku3_dir}tmp"
|
29
|
+
unless File.directory? "#{@chichilku3_dir}maps"
|
30
|
+
if File.directory? 'maps'
|
31
|
+
FileUtils.cp_r 'maps', "#{@chichilku3_dir}maps"
|
32
|
+
else
|
33
|
+
FileUtils.mkdir_p "#{@chichilku3_dir}maps"
|
34
|
+
end
|
35
|
+
end
|
24
36
|
create_default_cfg(file, "#{@chichilku3_dir}/#{file}")
|
37
|
+
@source_file = file
|
25
38
|
@file = @chichilku3_dir + file
|
26
39
|
@console = console
|
27
40
|
@data = load
|
@@ -31,7 +44,7 @@ class Config
|
|
31
44
|
return if File.file?(to)
|
32
45
|
|
33
46
|
tmp = JSON.parse(File.read(from))
|
34
|
-
File.open(to,
|
47
|
+
File.open(to, 'w') do |f|
|
35
48
|
f.write(tmp.to_json)
|
36
49
|
end
|
37
50
|
end
|
@@ -41,13 +54,14 @@ class Config
|
|
41
54
|
end
|
42
55
|
|
43
56
|
def load
|
57
|
+
defaults = JSON.parse(File.read(@source_file))
|
44
58
|
data = JSON.parse(File.read(@file))
|
45
|
-
data =
|
46
|
-
data
|
59
|
+
data = defaults.merge(data)
|
60
|
+
sanitize_data(data)
|
47
61
|
end
|
48
62
|
|
49
63
|
def save
|
50
|
-
File.open(@file,
|
64
|
+
File.open(@file, 'w') do |f|
|
51
65
|
f.write(JSON.pretty_generate(data))
|
52
66
|
end
|
53
67
|
end
|
data/lib/share/console.rb
CHANGED
@@ -1,22 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'string'
|
1
4
|
DEBUG = false
|
5
|
+
DEBUG_PHYSICS = true
|
2
6
|
|
3
7
|
# Console used by Client and Server
|
4
8
|
class Console
|
5
9
|
def log(message)
|
6
|
-
|
7
|
-
puts format("[%02d:%02d:%02d][log] %s", t.hour, t.min, t.sec, message)
|
10
|
+
log_type('log', message)
|
8
11
|
end
|
9
12
|
|
10
13
|
def err(message)
|
11
|
-
|
12
|
-
|
14
|
+
log_type('error'.red, message)
|
15
|
+
end
|
16
|
+
|
17
|
+
def wrn(message)
|
18
|
+
log_type('warning'.yellow, message)
|
13
19
|
end
|
14
20
|
|
15
21
|
def dbg(message)
|
16
22
|
return unless DEBUG
|
17
23
|
|
24
|
+
log_type('debug'.pink, message)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def log_type(type, message)
|
18
30
|
t = Time.now
|
19
|
-
puts format(
|
31
|
+
puts format('[%<hour>02d:%<min>02d:%<sec>02d][%<type>s] %<msg>s',
|
32
|
+
hour: t.hour,
|
33
|
+
min: t.min,
|
34
|
+
sec: t.sec,
|
35
|
+
type: type,
|
36
|
+
msg: message)
|
20
37
|
end
|
21
38
|
end
|
22
39
|
|
@@ -0,0 +1,279 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base64'
|
4
|
+
require 'digest/sha1'
|
5
|
+
require 'zip'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
require_relative '../external/rubyzip/recursive'
|
9
|
+
|
10
|
+
MAX_UNZIP_SIZE = 1024**2 # 1MiB
|
11
|
+
MAP_VERSION = 1
|
12
|
+
MAP_FILES = [
|
13
|
+
'background.png',
|
14
|
+
'gametiles.txt',
|
15
|
+
'metadata.json'
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
# GameMap class handles the game_map file format
|
19
|
+
class GameMap
|
20
|
+
attr_reader :gametiles, :grass_rows, :ready, :metadata
|
21
|
+
|
22
|
+
def initialize(console, cfg, mapname, callback = nil, checksum = nil)
|
23
|
+
@console = console
|
24
|
+
@cfg = cfg
|
25
|
+
@mapname = mapname
|
26
|
+
@b64_size = -1
|
27
|
+
@b64_data = ''
|
28
|
+
@sha1sum = checksum
|
29
|
+
@gametiles = []
|
30
|
+
# grass_rows
|
31
|
+
# array of hashes containing connected grass tiles
|
32
|
+
# a row of grass from x 0 to x 10 at the height 2 would look like this
|
33
|
+
# {x1: 0, x2: 10, y: 2}
|
34
|
+
@grass_rows = []
|
35
|
+
@ready = false
|
36
|
+
@metadata = nil
|
37
|
+
|
38
|
+
# client
|
39
|
+
@callback = callback
|
40
|
+
@progress = 0
|
41
|
+
@tmpfile = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def checksum
|
45
|
+
@sha1sum
|
46
|
+
end
|
47
|
+
|
48
|
+
def name
|
49
|
+
@mapname
|
50
|
+
end
|
51
|
+
|
52
|
+
# TODO: fix this rubocop
|
53
|
+
# rubocop:disable Naming/AccessorMethodName
|
54
|
+
def set_name(name)
|
55
|
+
raise unless @mapname.nil?
|
56
|
+
|
57
|
+
@mapname = name
|
58
|
+
end
|
59
|
+
|
60
|
+
def size
|
61
|
+
@b64_size
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_size(size)
|
65
|
+
raise unless @b64_size == -1
|
66
|
+
|
67
|
+
@b64_size = size
|
68
|
+
end
|
69
|
+
# rubocop:enable Naming/AccessorMethodName
|
70
|
+
|
71
|
+
def load_gametiles(map_dir)
|
72
|
+
gamefile = "#{map_dir}/gametiles.txt"
|
73
|
+
unless File.exist? gamefile
|
74
|
+
@console.err "could not load gametiles '#{gamefile}'"
|
75
|
+
exit 1
|
76
|
+
end
|
77
|
+
|
78
|
+
is_skip = true
|
79
|
+
@gametiles = []
|
80
|
+
@grass_rows = []
|
81
|
+
File.readlines(gamefile).each_with_index do |data, i|
|
82
|
+
gamerow = data[0..-2] # cut off newline
|
83
|
+
is_skip = !is_skip if gamerow =~ /\+-+\+/
|
84
|
+
gamerow = gamerow.match(/\|(.*)\|/)
|
85
|
+
next if gamerow.nil?
|
86
|
+
|
87
|
+
gamerow = gamerow[1]
|
88
|
+
next if is_skip
|
89
|
+
|
90
|
+
if gamerow.length != MAP_WIDTH
|
91
|
+
@console.err "invalid gametiles row=#{i} size=#{gamerow.length}/#{MAP_WIDTH}"
|
92
|
+
exit 1
|
93
|
+
end
|
94
|
+
@gametiles << gamerow
|
95
|
+
end
|
96
|
+
if @gametiles.length != MAP_HEIGHT
|
97
|
+
@console.err "invalid gametiles rows=#{@gametiles.length}/#{MAP_HEIGHT}"
|
98
|
+
exit 1
|
99
|
+
end
|
100
|
+
y = 0
|
101
|
+
grass = {}
|
102
|
+
@gametiles.each do |gamerow|
|
103
|
+
x = 0
|
104
|
+
gamerow.chars.each do |tile|
|
105
|
+
if tile == 'i'
|
106
|
+
grass[:x2] = x * TILE_SIZE + TILE_SIZE
|
107
|
+
grass[:y] = y * TILE_SIZE + TILE_SIZE / 2 + 2
|
108
|
+
grass[:x1] = x * TILE_SIZE if grass[:x1].nil?
|
109
|
+
else
|
110
|
+
@grass_rows.push(grass) unless grass == {}
|
111
|
+
grass = {}
|
112
|
+
end
|
113
|
+
x += 1
|
114
|
+
end
|
115
|
+
y += 1
|
116
|
+
end
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
120
|
+
def load_metadata(map_dir)
|
121
|
+
metafile = "#{map_dir}/metadata.json"
|
122
|
+
unless File.exist? metafile
|
123
|
+
@console.err "could not load gametiles '#{metafile}'"
|
124
|
+
exit 1
|
125
|
+
end
|
126
|
+
|
127
|
+
@metadata = JSON.parse(File.read(metafile))
|
128
|
+
if @metadata['chichilku3-map-version'] != MAP_VERSION
|
129
|
+
@console.err "Failed to load map '#{@metadata['name']}':"
|
130
|
+
@console.err " Expected map version '#{MAP_VERSION}' but got '#{@metadata['chichilku3-map-version']}'"
|
131
|
+
exit 1
|
132
|
+
end
|
133
|
+
@console.log "loaded map '#{@metadata['name']}' (#{@metadata['version']}) by #{@metadata['authors'].join(',')}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def load_data(map_dir)
|
137
|
+
load_gametiles(map_dir)
|
138
|
+
load_metadata(map_dir)
|
139
|
+
@ready = true
|
140
|
+
end
|
141
|
+
|
142
|
+
def death?(x, y)
|
143
|
+
{ x: x, y: y } if @gametiles[y][x] == 'X'
|
144
|
+
end
|
145
|
+
|
146
|
+
def collision?(x, y)
|
147
|
+
{ x: x, y: y } if @gametiles[y][x] == 'O'
|
148
|
+
end
|
149
|
+
|
150
|
+
def grass?(x, y)
|
151
|
+
{ x: x, y: y } if @gametiles[y][x] == 'i'
|
152
|
+
end
|
153
|
+
|
154
|
+
# SERVER
|
155
|
+
|
156
|
+
def prepare_upload
|
157
|
+
return if @mapname == '' || @mapname.nil?
|
158
|
+
|
159
|
+
map_dir = "#{@cfg.chichilku3_dir}maps/#{@mapname}"
|
160
|
+
unless File.directory? map_dir
|
161
|
+
@console.err "failed to load map '#{@mapname}' (directory not found)"
|
162
|
+
exit 1
|
163
|
+
end
|
164
|
+
unless File.exist? "#{map_dir}/background.png"
|
165
|
+
@console.err "failed to load map '#{@mapname}' (no background.png)"
|
166
|
+
exit 1
|
167
|
+
end
|
168
|
+
unless File.exist? "#{map_dir}/gametiles.txt"
|
169
|
+
@console.err "failed to load map '#{@mapname}' (no gametiles.txt)"
|
170
|
+
exit 1
|
171
|
+
end
|
172
|
+
load_data(map_dir)
|
173
|
+
zip
|
174
|
+
encode
|
175
|
+
end
|
176
|
+
|
177
|
+
def zip
|
178
|
+
map_dir = "#{@cfg.chichilku3_dir}maps/#{@mapname}"
|
179
|
+
map_zip = "#{@cfg.chichilku3_dir}maps/#{@mapname}.zip"
|
180
|
+
File.delete map_zip if File.exist? map_zip
|
181
|
+
|
182
|
+
@console.log "archiving map '#{map_zip}' ..."
|
183
|
+
Zip::File.open(map_zip, Zip::File::CREATE) do |zipfile|
|
184
|
+
MAP_FILES.each do |filename|
|
185
|
+
filepath = File.join(map_dir, filename)
|
186
|
+
unless File.exist? filepath
|
187
|
+
@console.err "failed to zip map '#{@mapname}' missing file:"
|
188
|
+
@console.err filepath
|
189
|
+
exit 1
|
190
|
+
end
|
191
|
+
zipfile.add(filename, filepath)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def encode
|
197
|
+
rawfile = "#{@cfg.chichilku3_dir}maps/#{@mapname}.zip"
|
198
|
+
@console.log "encoding map archive '#{@mapname}' ..."
|
199
|
+
File.open(rawfile, 'rb') do |map_png|
|
200
|
+
raw_content = map_png.read
|
201
|
+
@sha1sum = Digest::SHA1.hexdigest raw_content
|
202
|
+
encodefile = "#{@cfg.chichilku3_dir}maps_b64/#{@mapname}_#{checksum}.zip"
|
203
|
+
File.open(encodefile, 'wb') do |map_encoded|
|
204
|
+
@b64_data = Base64.encode64(raw_content).delete! "\n"
|
205
|
+
@b64_size = @b64_data.size
|
206
|
+
map_encoded.write(@b64_data)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
@console.log "finished encoding size=#{@b64_size} checksum=#{checksum}"
|
210
|
+
end
|
211
|
+
|
212
|
+
def get_data(offset, size)
|
213
|
+
return nil if @mapname == '' || @mapname.nil?
|
214
|
+
|
215
|
+
if offset + size > @b64_size
|
216
|
+
@b64_data[offset..-1].ljust(size, ' ')
|
217
|
+
else
|
218
|
+
@b64_data[offset...offset + size]
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# CLIENT
|
223
|
+
|
224
|
+
def dl_path
|
225
|
+
"#{@cfg.chichilku3_dir}downloadedmaps/#{@mapname}_#{checksum}"
|
226
|
+
end
|
227
|
+
|
228
|
+
def prepare_download
|
229
|
+
@tmpfile = "#{@cfg.chichilku3_dir}tmp/#{@mapname}"
|
230
|
+
File.delete @tmpfile if File.exist? @tmpfile
|
231
|
+
end
|
232
|
+
|
233
|
+
def download(data)
|
234
|
+
data.strip!
|
235
|
+
@progress += data.size
|
236
|
+
@console.dbg "downloading #{@progress} / #{@b64_size} ..."
|
237
|
+
IO.write(@tmpfile, data, mode: 'a')
|
238
|
+
if @progress >= @b64_size
|
239
|
+
@console.log 'finished download'
|
240
|
+
@callback.call(load)
|
241
|
+
end
|
242
|
+
@progress
|
243
|
+
end
|
244
|
+
|
245
|
+
def found?
|
246
|
+
File.directory? dl_path
|
247
|
+
end
|
248
|
+
|
249
|
+
def unzip
|
250
|
+
map_archive = "#{dl_path}.zip"
|
251
|
+
map_dir = dl_path
|
252
|
+
FileUtils.mkdir_p map_dir
|
253
|
+
Dir.chdir map_dir do
|
254
|
+
Zip::File.open(map_archive) do |zip_file|
|
255
|
+
zip_file.each do |entry|
|
256
|
+
@console.log "extracting '#{entry.name}' ...'"
|
257
|
+
raise 'File too large when extracted' if entry.size > MAX_UNZIP_SIZE
|
258
|
+
|
259
|
+
entry.extract
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
File.delete map_archive if File.exist? map_archive
|
264
|
+
map_dir
|
265
|
+
end
|
266
|
+
|
267
|
+
def load
|
268
|
+
outfile = "#{dl_path}.zip"
|
269
|
+
@console.log 'converting downloaded map ...'
|
270
|
+
File.open(@tmpfile, 'rb') do |map_encoded|
|
271
|
+
File.open(outfile, 'wb') do |map_png|
|
272
|
+
map_png.write(
|
273
|
+
Base64.decode64(map_encoded.read)
|
274
|
+
)
|
275
|
+
end
|
276
|
+
end
|
277
|
+
unzip
|
278
|
+
end
|
279
|
+
end
|
data/lib/share/math.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
SIDE_LEFT = -1
|
4
|
+
SIDE_RIGHT = 1
|
5
|
+
|
6
|
+
##
|
7
|
+
# Checks wether a given point is closer to the left or right step of a given interval
|
8
|
+
#
|
9
|
+
# @return -1 for left and 1 for right
|
10
|
+
# @param interval [Integer] interval size.
|
11
|
+
# @param point [Integer] point to check.
|
12
|
+
def closest_interval_side(interval, point)
|
13
|
+
(point % interval) * 2 < interval ? SIDE_LEFT : SIDE_RIGHT
|
14
|
+
end
|
data/lib/share/network.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'socket'
|
2
4
|
# check doc_network.rb for documentation
|
3
5
|
|
4
6
|
# update GAME_VERSION on network protocol changes
|
5
|
-
GAME_VERSION = '
|
7
|
+
GAME_VERSION = '0015'
|
6
8
|
|
7
9
|
# game
|
8
10
|
|
9
11
|
TILE_SIZE = 64
|
10
|
-
|
11
|
-
|
12
|
+
PLAYER_SIZE = TILE_SIZE - 2
|
13
|
+
MAP_WIDTH = 16
|
14
|
+
MAP_HEIGHT = 9
|
15
|
+
WINDOW_SIZE_X = TILE_SIZE * MAP_WIDTH
|
16
|
+
WINDOW_SIZE_Y = TILE_SIZE * MAP_HEIGHT
|
12
17
|
FULLHD_X = 1920
|
13
|
-
UI_SCALE = WINDOW_SIZE_X.to_f / FULLHD_X
|
18
|
+
UI_SCALE = WINDOW_SIZE_X.to_f / FULLHD_X
|
14
19
|
SPEED = TILE_SIZE
|
15
20
|
|
16
21
|
# networking
|
17
22
|
|
18
23
|
CMD_LEN = 7
|
19
24
|
NAME_LEN = 9
|
25
|
+
MAX_MAPNAME_LEN = 43
|
20
26
|
MAX_CLIENTS = 12
|
21
27
|
PLAYER_PACKAGE_LEN = 16
|
22
28
|
CLIENT_PACKAGE_LEN = 11 # used by server
|
@@ -24,40 +30,41 @@ SERVER_PACKAGE_LEN = MAX_CLIENTS * PLAYER_PACKAGE_LEN + 4 # used by client
|
|
24
30
|
|
25
31
|
MAX_TIMEOUT = 5
|
26
32
|
MAX_TICK_SPEED = 0.01 # the lower the faster client and server tick
|
33
|
+
# MAX_TICK_SPEED = 0.07
|
27
34
|
# MAX_TICK_SPEED = 0.005
|
28
35
|
|
29
|
-
NET_ERR_FULL =
|
30
|
-
NET_ERR_DISCONNECT =
|
31
|
-
NET_ERR_KICK =
|
32
|
-
NET_ERR_BAN =
|
33
|
-
NET_ERR_SERVER_OUTDATED =
|
34
|
-
NET_ERR_CLIENT_OUTDATED =
|
36
|
+
NET_ERR_FULL = '404'
|
37
|
+
NET_ERR_DISCONNECT = '001'
|
38
|
+
NET_ERR_KICK = '002'
|
39
|
+
NET_ERR_BAN = '003'
|
40
|
+
NET_ERR_SERVER_OUTDATED = '004'
|
41
|
+
NET_ERR_CLIENT_OUTDATED = '005'
|
35
42
|
|
36
43
|
NET_ERR = {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
44
|
+
'404' => 'SERVER FULL',
|
45
|
+
'001' => 'DISCONNECTED',
|
46
|
+
'002' => 'KICKED',
|
47
|
+
'003' => 'BANNED',
|
48
|
+
'004' => 'SERVER OUTDATED',
|
49
|
+
'005' => 'CLIENT OUTDATED'
|
50
|
+
}.freeze
|
44
51
|
|
45
52
|
CLIENT_PCK_TYPE = {
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
}
|
53
|
+
error: '0',
|
54
|
+
join: '1',
|
55
|
+
move: '2',
|
56
|
+
info: '3',
|
57
|
+
cmd: '4'
|
58
|
+
}.freeze
|
52
59
|
|
53
60
|
SERVER_PCK_TYPE = {
|
54
|
-
:
|
55
|
-
:
|
61
|
+
error: '0',
|
62
|
+
update: '1',
|
56
63
|
# TODO: find a good name here
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
}
|
64
|
+
info: '3',
|
65
|
+
cmd: '4',
|
66
|
+
event: '5'
|
67
|
+
}.freeze
|
61
68
|
|
62
69
|
NET_INT_OFFSET = 33
|
63
70
|
NET_INT_BASE = 93
|
@@ -70,13 +77,13 @@ NET_MIN_INT = 0
|
|
70
77
|
# the base of the network is NET_INT_BASE
|
71
78
|
# so the number 93 is the last single character number represented as '~'
|
72
79
|
#
|
73
|
-
# @param [Integer, #chr] int decimal based number
|
80
|
+
# @param [Integer, #chr] int decimal based number
|
74
81
|
# @return [String] the int converted to base NET_INT_BASE
|
75
82
|
|
76
83
|
def net_pack_int(int)
|
77
84
|
net_error "#{__method__}: '#{int}' is too low allowed range #{NET_MIN_INT}-#{NET_MAX_INT}" if int < NET_MIN_INT
|
78
85
|
net_error "#{__method__}: '#{int}' is too high allowed range #{NET_MIN_INT}-#{NET_MAX_INT}" if int > NET_MAX_INT
|
79
|
-
int
|
86
|
+
int += NET_INT_OFFSET
|
80
87
|
int.chr
|
81
88
|
end
|
82
89
|
|
@@ -101,17 +108,18 @@ end
|
|
101
108
|
# @return [String] the int converted to base NET_INT_BASE
|
102
109
|
|
103
110
|
def net_pack_bigint(int, size)
|
104
|
-
sum =
|
111
|
+
sum = ''
|
105
112
|
div = size - 1
|
106
113
|
(size - 1).times do
|
107
|
-
buf = int / ((NET_MAX_INT+1)
|
114
|
+
buf = int / ((NET_MAX_INT + 1)**div)
|
108
115
|
sum += net_pack_int(buf)
|
109
|
-
int = int % ((NET_MAX_INT+1)
|
116
|
+
int = int % ((NET_MAX_INT + 1)**div)
|
117
|
+
div -= 1
|
110
118
|
end
|
111
119
|
sum += net_pack_int(int)
|
112
120
|
# TODO: check reminder and so on
|
113
121
|
# throw and error when int is too big for size
|
114
|
-
int
|
122
|
+
int /= NET_MAX_INT
|
115
123
|
sum
|
116
124
|
end
|
117
125
|
|
@@ -127,21 +135,18 @@ def net_unpack_bigint(net_int)
|
|
127
135
|
if i.zero?
|
128
136
|
sum = net_unpack_int(c)
|
129
137
|
else
|
130
|
-
sum += net_unpack_int(c) *
|
138
|
+
sum += net_unpack_int(c) * (NET_MAX_INT + 1)**i
|
131
139
|
end
|
132
140
|
end
|
133
141
|
sum
|
134
142
|
end
|
135
143
|
|
136
144
|
def save_read(socket, size)
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
return ''
|
141
|
-
end
|
145
|
+
socket.read_nonblock(size)
|
146
|
+
rescue IO::WaitReadable
|
147
|
+
''
|
142
148
|
end
|
143
149
|
|
144
150
|
def net_error(err)
|
145
151
|
raise "NetError: #{err}"
|
146
|
-
exit 1
|
147
152
|
end
|