minestat 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +6 -0
- data/ReadMe.md +9 -5
- data/example.rb +1 -1
- data/lib/minestat.rb +84 -54
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8a29b7c1a834e40e6a63b451abc0cd67018ca48b8efcdcd04a6ca365390cec0
|
4
|
+
data.tar.gz: 609d3ed8ccfdff65d6c317b25066012eeafb7e206dd347923088fe4108588add
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b27f9e97df7fc7f2f38d0d18ae1f4c14015845ca0590cc8a33d269642697d41001c130ba36b6c7e0c39a5e39020b28b64bc02b78333ecfd1c3047a430d43555
|
7
|
+
data.tar.gz: f7e487a9a821c8b2aa83b8120c55eeb08b7229797bf6f62aff18937c4875db238ad88e3b6be08e6948303b79f74494d5ae60725fb9917d58729535d57aa33175
|
data/ChangeLog.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
|
+
## 3.0.1 (February 5, 2023)
|
2
|
+
- Added configurable DNS SRV resolution
|
3
|
+
- Added request type that attempts all SLP protocols
|
4
|
+
- Improved debug messages
|
5
|
+
|
1
6
|
## 3.0.0 (January 31, 2023)
|
2
7
|
- Added UT3/GS4 query support
|
8
|
+
- Added debug mode
|
3
9
|
- Refactored code
|
4
10
|
- Added YARD documentation
|
5
11
|
|
data/ReadMe.md
CHANGED
@@ -18,7 +18,7 @@ To install the gem: `gem install minestat`
|
|
18
18
|
```ruby
|
19
19
|
require 'minestat'
|
20
20
|
|
21
|
-
ms = MineStat.new("
|
21
|
+
ms = MineStat.new("frag.land")
|
22
22
|
puts "Minecraft server status of #{ms.address} on port #{ms.port}:"
|
23
23
|
if ms.online
|
24
24
|
puts "Server is online running version #{ms.version} with #{ms.current_players} out of #{ms.max_players} players."
|
@@ -36,24 +36,28 @@ end
|
|
36
36
|
|
37
37
|
To simply connect to an address:
|
38
38
|
```ruby
|
39
|
-
ms = MineStat.new("
|
39
|
+
ms = MineStat.new("frag.land")
|
40
40
|
```
|
41
41
|
Connect to an address on a certain TCP or UDP port:
|
42
42
|
```ruby
|
43
|
-
ms = MineStat.new("
|
43
|
+
ms = MineStat.new("frag.land", 25565)
|
44
44
|
```
|
45
45
|
Same as above example and additionally includes a timeout in seconds:
|
46
46
|
```ruby
|
47
|
-
ms = MineStat.new("
|
47
|
+
ms = MineStat.new("frag.land", 25565, 3)
|
48
48
|
```
|
49
49
|
Same as above example and additionally includes an explicit protocol to use:
|
50
50
|
```ruby
|
51
|
-
ms = MineStat.new("
|
51
|
+
ms = MineStat.new("frag.land", 25565, 3, MineStat::Request::QUERY)
|
52
52
|
```
|
53
53
|
Connect to a Bedrock server and enable debug mode:
|
54
54
|
```ruby
|
55
55
|
ms = MineStat.new("minecraft.frag.land", 19132, 3, MineStat::Request::BEDROCK, true)
|
56
56
|
```
|
57
|
+
Attempt all SLP protocols, disable debug mode, and disable DNS SRV resolution:
|
58
|
+
```ruby
|
59
|
+
ms = MineStat.new("minecraft.frag.land", 25565, 3, MineStat::Request::SLP, false, false)
|
60
|
+
```
|
57
61
|
|
58
62
|
### Support
|
59
63
|
* Discord: https://discord.frag.land
|
data/example.rb
CHANGED
@@ -2,7 +2,7 @@ require 'minestat'
|
|
2
2
|
|
3
3
|
# Below is an example using the MineStat class.
|
4
4
|
# If server is offline, other instance members will be nil.
|
5
|
-
ms = MineStat.new("
|
5
|
+
ms = MineStat.new("frag.land")
|
6
6
|
# Bedrock/Pocket Edition explicit query example with debug enabled
|
7
7
|
#ms = MineStat.new("minecraft.frag.land", 19132, 5, MineStat::Request::BEDROCK, true)
|
8
8
|
puts "Minecraft server status of #{ms.address} on port #{ms.port}:"
|
data/lib/minestat.rb
CHANGED
@@ -27,7 +27,7 @@ require 'timeout'
|
|
27
27
|
# Provides a Ruby interface for polling the status of Minecraft servers
|
28
28
|
class MineStat
|
29
29
|
# MineStat version
|
30
|
-
VERSION = "3.0.
|
30
|
+
VERSION = "3.0.1"
|
31
31
|
|
32
32
|
# Number of values expected from server
|
33
33
|
NUM_FIELDS = 6
|
@@ -116,6 +116,10 @@ class MineStat
|
|
116
116
|
|
117
117
|
# Unreal Tournament 3/GameSpy 4 query
|
118
118
|
QUERY = 5
|
119
|
+
|
120
|
+
# SLP only
|
121
|
+
# @since 3.0.1
|
122
|
+
SLP = 6
|
119
123
|
end
|
120
124
|
|
121
125
|
# Instantiates a MineStat object and polls the specified server for information
|
@@ -126,59 +130,60 @@ class MineStat
|
|
126
130
|
# @param debug [Boolean] Enable or disable error output
|
127
131
|
# @return [MineStat] A MineStat object
|
128
132
|
# @example Simply connect to an address
|
129
|
-
# ms = MineStat.new("
|
133
|
+
# ms = MineStat.new("frag.land")
|
130
134
|
# @example Connect to an address on a certain TCP or UDP port
|
131
|
-
# ms = MineStat.new("
|
135
|
+
# ms = MineStat.new("frag.land", 25565)
|
132
136
|
# @example Same as above example and additionally includes a timeout in seconds
|
133
|
-
# ms = MineStat.new("
|
137
|
+
# ms = MineStat.new("frag.land", 25565, 3)
|
134
138
|
# @example Same as above example and additionally includes an explicit protocol to use
|
135
|
-
# ms = MineStat.new("
|
139
|
+
# ms = MineStat.new("frag.land", 25565, 3, MineStat::Request::QUERY)
|
136
140
|
# @example Connect to a Bedrock server and enable debug mode
|
137
141
|
# ms = MineStat.new("minecraft.frag.land", 19132, 3, MineStat::Request::BEDROCK, true)
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
@
|
142
|
-
@
|
143
|
-
@
|
144
|
-
@
|
145
|
-
@
|
146
|
-
@
|
147
|
-
@
|
148
|
-
@
|
149
|
-
@
|
150
|
-
@
|
151
|
-
@
|
152
|
-
@
|
153
|
-
@
|
154
|
-
@
|
155
|
-
@
|
156
|
-
@
|
157
|
-
@
|
158
|
-
@
|
159
|
-
@
|
160
|
-
@
|
142
|
+
# @example Attempt all SLP protocols, disable debug mode, and disable DNS SRV resolution
|
143
|
+
# ms = MineStat.new("minecraft.frag.land", 25565, 3, MineStat::Request::SLP, false, false)
|
144
|
+
def initialize(address, port = DEFAULT_TCP_PORT, timeout = DEFAULT_TIMEOUT, request_type = Request::NONE, debug = false, srv_enabled = true)
|
145
|
+
@address = address # address of server
|
146
|
+
@port = port # TCP/UDP port of server
|
147
|
+
@srv_address # server address from DNS SRV record
|
148
|
+
@srv_port # server TCP port from DNS SRV record
|
149
|
+
@online # online or offline?
|
150
|
+
@version # server version
|
151
|
+
@mode # game mode (Bedrock/Pocket Edition only)
|
152
|
+
@motd # message of the day
|
153
|
+
@stripped_motd # message of the day without formatting
|
154
|
+
@current_players # current number of players online
|
155
|
+
@max_players # maximum player capacity
|
156
|
+
@player_list # list of players (UT3/GS4 query only)
|
157
|
+
@plugin_list # list of plugins (UT3/GS4 query only)
|
158
|
+
@protocol # protocol level
|
159
|
+
@json_data # JSON data for 1.7 queries
|
160
|
+
@favicon_b64 # base64-encoded favicon possibly contained in JSON 1.7 responses
|
161
|
+
@favicon # decoded favicon data
|
162
|
+
@latency # ping time to server in milliseconds
|
163
|
+
@timeout = timeout # TCP/UDP timeout
|
164
|
+
@server # server socket
|
165
|
+
@request_type # protocol version
|
166
|
+
@connection_status # status of connection ("Success", "Fail", "Timeout", or "Unknown")
|
167
|
+
@try_all = false # try all protocols?
|
168
|
+
@debug = debug # debug mode
|
169
|
+
@srv_enabled = srv_enabled # enable SRV resolution?
|
161
170
|
|
162
171
|
@try_all = true if request_type == Request::NONE
|
163
|
-
resolve_srv(
|
172
|
+
resolve_srv() if @srv_enabled
|
164
173
|
set_connection_status(attempt_protocols(request_type))
|
165
174
|
end
|
166
175
|
|
167
|
-
# Attempts to resolve SRV records
|
168
|
-
# @param address [String] Minecraft server address
|
169
|
-
# @param port [Integer] Minecraft server TCP or UDP port
|
176
|
+
# Attempts to resolve DNS SRV records
|
170
177
|
# @return [Boolean] Whether or not SRV resolution was successful
|
171
178
|
# @since 2.3.0
|
172
|
-
def resolve_srv(
|
179
|
+
def resolve_srv()
|
173
180
|
begin
|
174
181
|
resolver = Resolv::DNS.new
|
175
182
|
res = resolver.getresource("_minecraft._tcp.#{@address}", Resolv::DNS::Resource::IN::SRV)
|
176
|
-
@
|
177
|
-
@
|
178
|
-
rescue => exception
|
179
|
-
$stderr.puts exception if @debug
|
180
|
-
@address = address
|
181
|
-
@port = port
|
183
|
+
@srv_address = res.target.to_s # SRV target
|
184
|
+
@srv_port = res.port.to_i # SRV port
|
185
|
+
rescue => exception # primarily catch Resolv::ResolvError and revert if unable to resolve SRV record(s)
|
186
|
+
$stderr.puts "resolve_srv(): #{exception}" if @debug
|
182
187
|
return false
|
183
188
|
end
|
184
189
|
return true
|
@@ -222,6 +227,7 @@ class MineStat
|
|
222
227
|
unless retval == Retval::CONNFAIL
|
223
228
|
retval = json_request()
|
224
229
|
end
|
230
|
+
return retval if request_type == Request::SLP
|
225
231
|
# Bedrock/Pocket Edition
|
226
232
|
unless @online || retval == Retval::SUCCESS
|
227
233
|
retval = bedrock_request()
|
@@ -275,13 +281,18 @@ class MineStat
|
|
275
281
|
@server.connect(@address, @port)
|
276
282
|
else
|
277
283
|
start_time = Time.now
|
278
|
-
|
284
|
+
if @srv_enabled
|
285
|
+
@server = TCPSocket.new(@srv_address, @srv_port)
|
286
|
+
else
|
287
|
+
@server = TCPSocket.new(@address, @port)
|
288
|
+
end
|
279
289
|
end
|
280
290
|
@latency = ((Time.now - start_time) * 1000).round
|
281
291
|
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
292
|
+
$stderr.puts "connect(): Host unreachable or connection refused" if @debug
|
282
293
|
return Retval::CONNFAIL
|
283
294
|
rescue => exception
|
284
|
-
$stderr.puts exception if @debug
|
295
|
+
$stderr.puts "connect(): #{exception}" if @debug
|
285
296
|
return Retval::UNKNOWN
|
286
297
|
end
|
287
298
|
return Retval::SUCCESS
|
@@ -322,7 +333,7 @@ class MineStat
|
|
322
333
|
end
|
323
334
|
end
|
324
335
|
rescue => exception
|
325
|
-
$stderr.puts exception if @debug
|
336
|
+
$stderr.puts "check_response(): #{exception}" if @debug
|
326
337
|
return nil, Retval::UNKNOWN
|
327
338
|
end
|
328
339
|
retval = Retval::UNKNOWN if data == nil || data.empty?
|
@@ -347,7 +358,7 @@ class MineStat
|
|
347
358
|
if server_info != nil && server_info.length >= NUM_FIELDS_BETA
|
348
359
|
@version = ">=1.8b/1.3" # since server does not return version, set it
|
349
360
|
@motd = server_info[0]
|
350
|
-
strip_motd
|
361
|
+
strip_motd()
|
351
362
|
@current_players = server_info[1].to_i
|
352
363
|
@max_players = server_info[2].to_i
|
353
364
|
@online = true
|
@@ -360,7 +371,7 @@ class MineStat
|
|
360
371
|
@version = "#{server_info[3]} #{server_info[7]} (#{server_info[0]})"
|
361
372
|
@mode = server_info[8]
|
362
373
|
@motd = server_info[1]
|
363
|
-
strip_motd
|
374
|
+
strip_motd()
|
364
375
|
@current_players = server_info[4].to_i
|
365
376
|
@max_players = server_info[5].to_i
|
366
377
|
@online = true
|
@@ -373,7 +384,7 @@ class MineStat
|
|
373
384
|
server_info = Hash[*server_info[0].split(delimiter).flatten(1)]
|
374
385
|
@version = server_info["version"]
|
375
386
|
@motd = server_info["hostname"]
|
376
|
-
strip_motd
|
387
|
+
strip_motd()
|
377
388
|
@current_players = server_info["numplayers"].to_i
|
378
389
|
@max_players = server_info["maxplayers"].to_i
|
379
390
|
unless server_info["plugins"].nil? || server_info["plugins"].empty?
|
@@ -392,7 +403,7 @@ class MineStat
|
|
392
403
|
@protocol = server_info[1].to_i # contains the protocol version (51 for 1.9 or 78 for 1.6.4 for example)
|
393
404
|
@version = server_info[2]
|
394
405
|
@motd = server_info[3]
|
395
|
-
strip_motd
|
406
|
+
strip_motd()
|
396
407
|
@current_players = server_info[4].to_i
|
397
408
|
@max_players = server_info[5].to_i
|
398
409
|
@online = true
|
@@ -429,9 +440,10 @@ class MineStat
|
|
429
440
|
retval = parse_data("\u00A7", true) # section symbol
|
430
441
|
end
|
431
442
|
rescue Timeout::Error
|
443
|
+
$stderr.puts "beta_request(): Connection timed out" if @debug
|
432
444
|
return Retval::TIMEOUT
|
433
445
|
rescue => exception
|
434
|
-
$stderr.puts exception if @debug
|
446
|
+
$stderr.puts "beta_request(): #{exception}" if @debug
|
435
447
|
return Retval::UNKNOWN
|
436
448
|
end
|
437
449
|
if retval == Retval::SUCCESS
|
@@ -474,9 +486,10 @@ class MineStat
|
|
474
486
|
retval = parse_data("\x00") # null
|
475
487
|
end
|
476
488
|
rescue Timeout::Error
|
489
|
+
$stderr.puts "legacy_request(): Connection timed out" if @debug
|
477
490
|
return Retval::TIMEOUT
|
478
491
|
rescue => exception
|
479
|
-
$stderr.puts exception if @debug
|
492
|
+
$stderr.puts "legacy_request(): #{exception}" if @debug
|
480
493
|
return Retval::UNKNOWN
|
481
494
|
end
|
482
495
|
if retval == Retval::SUCCESS
|
@@ -535,9 +548,10 @@ class MineStat
|
|
535
548
|
retval = parse_data("\x00") # null
|
536
549
|
end
|
537
550
|
rescue Timeout::Error
|
551
|
+
$stderr.puts "extended_legacy_request(): Connection timed out" if @debug
|
538
552
|
return Retval::TIMEOUT
|
539
553
|
rescue => exception
|
540
|
-
$stderr.puts exception if @debug
|
554
|
+
$stderr.puts "extended_legacy_request(): #{exception}" if @debug
|
541
555
|
return Retval::UNKNOWN
|
542
556
|
end
|
543
557
|
if retval == Retval::SUCCESS
|
@@ -596,7 +610,7 @@ class MineStat
|
|
596
610
|
@protocol = json_data['version']['protocol'].to_i
|
597
611
|
@version = json_data['version']['name']
|
598
612
|
@motd = json_data['description']
|
599
|
-
strip_motd
|
613
|
+
strip_motd()
|
600
614
|
@current_players = json_data['players']['online'].to_i
|
601
615
|
@max_players = json_data['players']['max'].to_i
|
602
616
|
@favicon_b64 = json_data['favicon']
|
@@ -611,11 +625,13 @@ class MineStat
|
|
611
625
|
end
|
612
626
|
end
|
613
627
|
rescue Timeout::Error
|
628
|
+
$stderr.puts "json_request(): Connection timed out" if @debug
|
614
629
|
return Retval::TIMEOUT
|
615
630
|
rescue JSON::ParserError
|
631
|
+
$stderr.puts "json_request(): JSON parse error" if @debug
|
616
632
|
return Retval::UNKNOWN
|
617
633
|
rescue => exception
|
618
|
-
$stderr.puts exception if @debug
|
634
|
+
$stderr.puts "json_request(): #{exception}" if @debug
|
619
635
|
return Retval::UNKNOWN
|
620
636
|
end
|
621
637
|
if retval == Retval::SUCCESS
|
@@ -640,7 +656,7 @@ class MineStat
|
|
640
656
|
break if json_data.length >= json_len
|
641
657
|
end
|
642
658
|
rescue => exception
|
643
|
-
$stderr.puts exception if @debug
|
659
|
+
$stderr.puts "recv_json(): #{exception}" if @debug
|
644
660
|
end
|
645
661
|
return json_data
|
646
662
|
end
|
@@ -711,9 +727,10 @@ class MineStat
|
|
711
727
|
retval = parse_data("\x3B") # semicolon
|
712
728
|
end
|
713
729
|
rescue Timeout::Error
|
730
|
+
$stderr.puts "bedrock_request(): Connection timed out" if @debug
|
714
731
|
return Retval::TIMEOUT
|
715
732
|
rescue => exception
|
716
|
-
$stderr.puts exception if @debug
|
733
|
+
$stderr.puts "bedrock_request(): #{exception}" if @debug
|
717
734
|
return Retval::UNKNOWN
|
718
735
|
end
|
719
736
|
if retval == Retval::SUCCESS
|
@@ -777,9 +794,10 @@ class MineStat
|
|
777
794
|
retval = parse_data("\x00") # null
|
778
795
|
end
|
779
796
|
rescue Timeout::Error
|
797
|
+
$stderr.puts "query_request(): Connection timed out" if @debug
|
780
798
|
return Retval::TIMEOUT
|
781
799
|
rescue => exception
|
782
|
-
$stderr.puts exception if @debug
|
800
|
+
$stderr.puts "query_request(): #{exception}" if @debug
|
783
801
|
return Retval::UNKNOWN
|
784
802
|
end
|
785
803
|
if retval == Retval::SUCCESS
|
@@ -795,6 +813,14 @@ class MineStat
|
|
795
813
|
# Port (TCP or UDP) of the Minecraft server
|
796
814
|
attr_reader :port
|
797
815
|
|
816
|
+
# Address of the Minecraft server from a DNS SRV record
|
817
|
+
# @since 3.0.1
|
818
|
+
attr_reader :srv_address
|
819
|
+
|
820
|
+
# TCP port of the Minecraft server from a DNS SRV record
|
821
|
+
# @since 3.0.1
|
822
|
+
attr_reader :srv_port
|
823
|
+
|
798
824
|
# Whether or not the Minecraft server is online
|
799
825
|
attr_reader :online
|
800
826
|
|
@@ -872,4 +898,8 @@ class MineStat
|
|
872
898
|
# Whether or not debug mode is enabled
|
873
899
|
# @since 3.0.0
|
874
900
|
attr_reader :debug
|
901
|
+
|
902
|
+
# Whether or not DNS SRV resolution is enabled
|
903
|
+
# @since 3.0.1
|
904
|
+
attr_reader :srv_enabled
|
875
905
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minestat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lloyd Dilley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: MineStat polls Minecraft server data such as version, motd, current players,
|
14
14
|
and max players.
|