steam-condenser 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/VERSION.yml +2 -2
  2. data/lib/datagram_channel.rb +30 -33
  3. data/lib/exceptions/packet_format_exception.rb +7 -3
  4. data/lib/exceptions/rcon_ban_exception.rb +7 -5
  5. data/lib/exceptions/rcon_no_auth_exception.rb +8 -6
  6. data/lib/exceptions/timeout_exception.rb +10 -4
  7. data/lib/socket_channel.rb +11 -17
  8. data/lib/steam/community/cacheable.rb +5 -7
  9. data/lib/steam/community/css/css_map.rb +31 -0
  10. data/lib/steam/community/css/css_stats.rb +116 -0
  11. data/lib/steam/community/css/css_weapon.rb +33 -0
  12. data/lib/steam/community/dods/dods_stats.rb +3 -3
  13. data/lib/steam/community/game_stats.rb +14 -13
  14. data/lib/steam/community/game_weapon.rb +3 -5
  15. data/lib/steam/community/l4d/abstract_l4d_stats.rb +4 -2
  16. data/lib/steam/community/l4d/l4d_explosive.rb +2 -2
  17. data/lib/steam/community/l4d/l4d_map.rb +3 -3
  18. data/lib/steam/community/steam_group.rb +2 -4
  19. data/lib/steam/community/steam_id.rb +2 -2
  20. data/lib/steam/community/tf2/tf2_class.rb +17 -17
  21. data/lib/steam/community/tf2/tf2_class_factory.rb +17 -17
  22. data/lib/steam/community/tf2/tf2_engineer.rb +9 -9
  23. data/lib/steam/community/tf2/tf2_medic.rb +9 -9
  24. data/lib/steam/community/tf2/tf2_sniper.rb +7 -7
  25. data/lib/steam/community/tf2/tf2_spy.rb +9 -9
  26. data/lib/steam/community/tf2/tf2_stats.rb +9 -9
  27. data/lib/steam/packets/a2a_ack_packet.rb +11 -9
  28. data/lib/steam/packets/a2a_ping_packet.rb +5 -4
  29. data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +13 -12
  30. data/lib/steam/packets/a2s_info_packet.rb +8 -7
  31. data/lib/steam/packets/a2s_player_packet.rb +6 -6
  32. data/lib/steam/packets/a2s_rules_packet.rb +5 -5
  33. data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +4 -3
  34. data/lib/steam/packets/m2a_server_batch_packet.rb +20 -22
  35. data/lib/steam/packets/rcon/rcon_auth_request.rb +5 -5
  36. data/lib/steam/packets/rcon/rcon_auth_response.rb +6 -6
  37. data/lib/steam/packets/rcon/rcon_exec_request.rb +5 -5
  38. data/lib/steam/packets/rcon/rcon_exec_response.rb +2 -2
  39. data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +7 -7
  40. data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +8 -8
  41. data/lib/steam/packets/rcon/rcon_packet.rb +12 -16
  42. data/lib/steam/packets/rcon/rcon_packet_factory.rb +19 -19
  43. data/lib/steam/packets/request_with_challenge.rb +5 -5
  44. data/lib/steam/packets/s2a_info2_packet.rb +28 -30
  45. data/lib/steam/packets/s2a_info_base_packet.rb +11 -16
  46. data/lib/steam/packets/s2a_info_detailed_packet.rb +30 -28
  47. data/lib/steam/packets/s2a_player_packet.rb +7 -9
  48. data/lib/steam/packets/s2a_rules_packet.rb +8 -12
  49. data/lib/steam/packets/s2c_challenge_packet.rb +7 -6
  50. data/lib/steam/packets/steam_packet.rb +7 -6
  51. data/lib/steam/packets/steam_packet_factory.rb +37 -38
  52. data/lib/steam/servers/game_server.rb +76 -86
  53. data/lib/steam/servers/goldsrc_server.rb +5 -5
  54. data/lib/steam/servers/master_server.rb +24 -24
  55. data/lib/steam/servers/source_server.rb +17 -19
  56. data/lib/steam/sockets/goldsrc_socket.rb +43 -46
  57. data/lib/steam/sockets/master_server_socket.rb +11 -13
  58. data/lib/steam/sockets/rcon_socket.rb +15 -17
  59. data/lib/steam/sockets/source_socket.rb +21 -21
  60. data/lib/steam/sockets/steam_socket.rb +25 -28
  61. data/lib/steam/steam_player.rb +3 -1
  62. data/lib/stringio_additions.rb +48 -0
  63. data/test/datagram_channel_tests.rb +8 -8
  64. data/test/query_tests.rb +15 -14
  65. data/test/rcon_tests.rb +32 -31
  66. data/test/socket_channel_tests.rb +7 -7
  67. data/test/steam/communtiy/steam_community_test_suite.rb +5 -2
  68. data/test/steam_community_tests.rb +4 -3
  69. data/test/stringio_additions_tests.rb +77 -0
  70. metadata +15 -8
  71. data/lib/byte_buffer.rb +0 -126
  72. data/lib/exceptions/buffer_underflow_exception.rb +0 -8
  73. data/test/byte_buffer_tests.rb +0 -76
@@ -1,12 +1,12 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2009, Sebastian Staudt
4
+ # Copyright (c) 2008-2010, Sebastian Staudt
5
5
 
6
- require "byte_buffer"
7
- require "steam/packets/steam_packet_factory"
8
- require "steam/packets/rcon/rcon_goldsrc_request"
9
- require "steam/sockets/steam_socket"
6
+ require 'stringio_additions'
7
+ require 'steam/packets/steam_packet_factory'
8
+ require 'steam/packets/rcon/rcon_goldsrc_request'
9
+ require 'steam/sockets/steam_socket'
10
10
 
11
11
  # The SourceSocket class is a sub class of SteamSocket respecting the
12
12
  # specifications of the Source query protocol.
@@ -21,18 +21,18 @@ class GoldSrcSocket < SteamSocket
21
21
  # maximum packet size of 1400 byte. Greater packets will be split over several
22
22
  # UDP packets. This method reassembles split packets into single packet
23
23
  # objects.
24
- def get_reply
25
- bytes_read = self.receive_packet 1400
26
-
27
- if @buffer.get_long == 0xFFFFFFFE
28
- split_packets = Array.new
24
+ def reply
25
+ bytes_read = receive_packet 1400
26
+
27
+ if @buffer.long == 0xFFFFFFFE
28
+ split_packets = []
29
29
  begin
30
30
  # Parsing of split packet headers
31
- request_id = @buffer.get_long
32
- packet_number_and_count = @buffer.get_byte.to_i
31
+ request_id = @buffer.long
32
+ packet_number_and_count = @buffer.byte.to_i
33
33
  packet_count = packet_number_and_count & 0xF
34
34
  packet_number = (packet_number_and_count >> 4) + 1
35
-
35
+
36
36
  # Caching of split packet data
37
37
  split_packets[packet_number - 1] = @buffer.get
38
38
 
@@ -41,68 +41,65 @@ class GoldSrcSocket < SteamSocket
41
41
  # Receiving the next packet
42
42
  if split_packets.size < packet_count
43
43
  begin
44
- bytes_read = self.receive_packet
44
+ bytes_read = receive_packet
45
45
  rescue TimeoutException
46
46
  bytes_read = 0
47
47
  end
48
48
  else
49
49
  bytes_read = 0
50
50
  end
51
- end while bytes_read > 0 && @buffer.get_long == 0xFFFFFFFE
52
-
51
+ end while bytes_read > 0 && @buffer.long == 0xFFFFFFFE
52
+
53
53
  packet = SteamPacketFactory.reassemble_packet(split_packets)
54
-
55
54
  else
56
- packet = SteamPacketFactory.get_packet_from_data(@buffer.get)
55
+ packet = SteamPacketFactory.packet_from_data(@buffer.get)
57
56
  end
58
57
 
59
58
  puts "Got reply of type \"#{packet.class.to_s}\"." if $DEBUG
60
59
 
61
- return packet
60
+ packet
62
61
  end
63
-
62
+
64
63
  def rcon_exec(password, command)
65
- self.rcon_get_challenge if @rcon_challenge.nil? or @is_hltv
66
-
67
- self.rcon_send "rcon #{@rcon_challenge} #{password} #{command}"
64
+ rcon_challenge if @rcon_challenge.nil? or @is_hltv
65
+
66
+ rcon_send "rcon #{@rcon_challenge} #{password} #{command}"
68
67
  if @is_hltv
69
68
  begin
70
- response = self.get_reply.get_response
69
+ response = reply.response
71
70
  rescue TimeoutException
72
- response = ""
71
+ response = ''
73
72
  end
74
73
  else
75
- response = self.get_reply.get_response
74
+ response = reply.response
76
75
  end
77
-
78
- if response.strip == "Bad rcon_password." or response.strip == "You have been banned from this server."
79
- raise RCONNoAuthException.new
76
+
77
+ if response.strip == 'Bad rcon_password.' or response.strip == 'You have been banned from this server.'
78
+ raise RCONNoAuthException
80
79
  end
81
-
80
+
82
81
  begin
83
- while true
84
- response_part = self.get_reply.get_response
82
+ loop do
83
+ response_part = reply.response
85
84
  response << response_part
86
85
  end
87
86
  rescue TimeoutException
88
87
  end
89
-
90
- return response
88
+
89
+ response
91
90
  end
92
-
93
- def rcon_get_challenge
94
- self.rcon_send "challenge rcon"
95
- response = self.get_reply.get_response.strip
96
-
97
- if response == "You have been banned from this server."
98
- raise RCONNoAuthException.new;
99
- end
100
-
91
+
92
+ def rcon_challenge
93
+ rcon_send 'challenge rcon'
94
+ response = reply.response.strip
95
+
96
+ raise RCONNoAuthException if response == 'You have been banned from this server.'
97
+
101
98
  @rcon_challenge = response[14..-1]
102
99
  end
103
-
100
+
104
101
  def rcon_send(command)
105
- self.send RCONGoldSrcRequest.new(command)
102
+ send RCONGoldSrcRequest.new(command)
106
103
  end
107
-
104
+
108
105
  end
@@ -1,20 +1,18 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2009, Sebastian Staudt
4
+ # Copyright (c) 2008-2010, Sebastian Staudt
5
5
 
6
- require "steam/sockets/steam_socket"
6
+ require 'steam/sockets/steam_socket'
7
7
 
8
8
  class MasterServerSocket < SteamSocket
9
-
10
- def get_reply
11
- self.receive_packet 1500
12
-
13
- if @buffer.get_long != 0xFFFFFFFF
14
- raise Exception.new("Master query response has wrong packet header.")
15
- end
16
-
17
- return SteamPacketFactory.get_packet_from_data(@buffer.get)
9
+
10
+ def reply
11
+ receive_packet 1500
12
+
13
+ raise Exception.new("Master query response has wrong packet header.") unless @buffer.long == 0xFFFFFFFF
14
+
15
+ SteamPacketFactory.packet_from_data(@buffer.get)
18
16
  end
19
-
20
- end
17
+
18
+ end
@@ -1,7 +1,7 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2009, Sebastian Staudt
4
+ # Copyright (c) 2008-2010, Sebastian Staudt
5
5
 
6
6
  require 'socket_channel'
7
7
  require 'exceptions/rcon_ban_exception'
@@ -17,35 +17,33 @@ class RCONSocket < SteamSocket
17
17
  end
18
18
 
19
19
  def send(data_packet)
20
- if !@channel.connected?
21
- @channel.connect @remote_socket
22
- end
20
+ @channel.connect @remote_socket unless @channel.connected?
23
21
 
24
- @buffer = ByteBuffer.wrap data_packet.get_bytes
22
+ @buffer = StringIO.new data_packet.bytes
25
23
  @channel.write @buffer
26
24
  end
27
25
 
28
- def get_reply
29
- if self.receive_packet(1440) == 0
30
- raise RCONBanException
31
- end
32
- packet_data = @buffer.array[0..@buffer.limit]
33
- packet_size = @buffer.get_long + 4
26
+ def reply
27
+ raise RCONBanException if receive_packet(1440) == 0
28
+
29
+ packet_data = @buffer.get
30
+ packet_size = @buffer.long + 4
31
+ @buffer.rewind
34
32
 
35
33
  if packet_size > 1440
36
- remaining_bytes = packet_size - @buffer.limit
34
+ remaining_bytes = packet_size - @buffer.size
37
35
  begin
38
36
  if remaining_bytes < 1440
39
- self.receive_packet remaining_bytes
37
+ receive_packet remaining_bytes
40
38
  else
41
- self.receive_packet 1440
39
+ receive_packet 1440
42
40
  end
43
- packet_data << @buffer.array[0..@buffer.limit]
44
- remaining_bytes -= @buffer.limit
41
+ packet_data << @buffer.get
42
+ remaining_bytes -= @buffer.size
45
43
  end while remaining_bytes > 0
46
44
  end
47
45
 
48
- return RCONPacketFactory.get_packet_from_data(packet_data)
46
+ RCONPacketFactory.packet_from_data(packet_data)
49
47
  end
50
48
 
51
49
  end
@@ -1,10 +1,10 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2009, Sebastian Staudt
4
+ # Copyright (c) 2008-2010, Sebastian Staudt
5
5
 
6
- require "byte_buffer"
7
- require "steam/sockets/steam_socket"
6
+ require 'stringio_additions'
7
+ require 'steam/sockets/steam_socket'
8
8
 
9
9
  # The SourceSocket class is a sub class of SteamSocket respecting the
10
10
  # specifications of the Source query protocol.
@@ -14,24 +14,24 @@ class SourceSocket < SteamSocket
14
14
  # maximum packet size of 1400 byte. Greater packets will be split over several
15
15
  # UDP packets. This method reassembles split packets into single packet
16
16
  # objects.
17
- def get_reply
18
- bytes_read = self.receive_packet 1400
17
+ def reply
18
+ bytes_read = receive_packet 1400
19
19
  is_compressed = false
20
20
 
21
- if @buffer.get_long == 0xFFFFFFFE
22
- split_packets = Array.new
21
+ if @buffer.long == 0xFFFFFFFE
22
+ split_packets = []
23
23
  begin
24
24
  # Parsing of split packet headers
25
- request_id = @buffer.get_long
25
+ request_id = @buffer.long
26
26
  is_compressed = ((request_id & 0x80000000) != 0)
27
- packet_count = @buffer.get_byte.to_i
28
- packet_number = @buffer.get_byte.to_i + 1
29
-
27
+ packet_count = @buffer.byte.to_i
28
+ packet_number = @buffer.byte.to_i + 1
29
+
30
30
  if is_compressed
31
- split_size = @buffer.get_long
32
- packet_checksum = @buffer.get_long
31
+ @buffer.long
32
+ packet_checksum = @buffer.long
33
33
  else
34
- split_size = @buffer.get_short
34
+ @buffer.short
35
35
  end
36
36
 
37
37
  # Caching of split packet data
@@ -42,22 +42,22 @@ class SourceSocket < SteamSocket
42
42
  # Receiving the next packet
43
43
  if split_packets.size < packet_count
44
44
  begin
45
- bytes_read = self.receive_packet
45
+ bytes_read = receive_packet
46
46
  rescue TimeoutException
47
47
  bytes_read = 0
48
48
  end
49
49
  else
50
50
  bytes_read = 0
51
51
  end
52
- end while bytes_read > 0 && @buffer.get_long == 0xFFFFFFFE
53
-
52
+ end while bytes_read > 0 && @buffer.long == 0xFFFFFFFE
53
+
54
54
  if is_compressed
55
55
  packet = SteamPacketFactory.reassemble_packet(split_packets, true, packet_checksum)
56
56
  else
57
57
  packet = SteamPacketFactory.reassemble_packet(split_packets)
58
58
  end
59
59
  else
60
- packet = SteamPacketFactory.get_packet_from_data(@buffer.get)
60
+ packet = SteamPacketFactory.packet_from_data(@buffer.get)
61
61
  end
62
62
 
63
63
  if is_compressed
@@ -65,8 +65,8 @@ class SourceSocket < SteamSocket
65
65
  else
66
66
  puts "Got reply of type \"#{packet.class.to_s}\"." if $DEBUG
67
67
  end
68
-
69
- return packet
68
+
69
+ packet
70
70
  end
71
-
71
+
72
72
  end
@@ -1,60 +1,57 @@
1
1
  # This code is free software; you can redistribute it and/or modify it under the
2
2
  # terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2009, Sebastian Staudt
4
+ # Copyright (c) 2008-2010, Sebastian Staudt
5
5
 
6
- require "abstract_class"
7
- require "byte_buffer"
8
- require "datagram_channel"
9
- require "ipaddr"
10
- require "exceptions/timeout_exception"
6
+ require 'abstract_class'
7
+ require 'datagram_channel'
8
+ require 'ipaddr'
9
+ require 'stringio_additions'
10
+ require 'exceptions/timeout_exception'
11
11
 
12
- # The SteamSocket class is a sub class of CondenserSocket respecting the
13
- # specifications of the Source query protocol.
12
+ # Defines common methods for sockets used to connect to game and master
13
+ # servers.
14
14
  class SteamSocket
15
-
15
+
16
16
  include AbstractClass
17
-
17
+
18
18
  def initialize(*args)
19
19
  @channel = DatagramChannel.open
20
20
  @channel.connect *args
21
21
  @channel.configure_blocking false
22
-
22
+
23
23
  @remote_socket = Socket.getaddrinfo args[0].to_s, args[1]
24
24
  end
25
25
 
26
- # Abstract get_reply method
27
- def get_reply
26
+ # Abstract +reply+ method
27
+ def reply
28
28
  raise NotImplementedError
29
29
  end
30
-
30
+
31
31
  def receive_packet(buffer_length = 0)
32
- if select([@channel.socket], nil, nil, 1) == nil
33
- raise TimeoutException.new
34
- end
32
+ raise TimeoutException if select([@channel.socket], nil, nil, 1).nil?
35
33
 
36
34
  if buffer_length == 0
37
- @buffer.clear
35
+ @buffer.truncate @buffer.size
38
36
  else
39
- @buffer = ByteBuffer.allocate buffer_length
37
+ @buffer = StringIO.allocate buffer_length
40
38
  end
41
-
42
- bytes_read = @channel.read(@buffer)
39
+
40
+ bytes_read = @channel.read @buffer
43
41
  @buffer.rewind
44
- @buffer.limit = bytes_read
45
-
42
+
46
43
  bytes_read
47
44
  end
48
-
45
+
49
46
  def send(data_packet)
50
47
  puts "Sending data packet of type \"#{data_packet.class.to_s}\"." if $DEBUG
51
48
 
52
- @buffer = ByteBuffer.wrap(data_packet.to_s)
53
- @channel.write(@buffer)
49
+ @buffer = StringIO.new data_packet.to_s
50
+ @channel.write @buffer
54
51
  end
55
-
52
+
56
53
  def finalize
57
54
  @channel.close
58
55
  end
59
-
56
+
60
57
  end
@@ -25,7 +25,9 @@ class SteamPlayer
25
25
  def add_info(real_id, name, steam_id, *player_data)
26
26
  @extended = true
27
27
 
28
- raise SteamCondenserException.new('Information to add belongs to a different player.') unless name == @name
28
+ unless name == @name
29
+ raise SteamCondenserException.new('Information to add belongs to a different player.')
30
+ end
29
31
 
30
32
  @real_id = real_id
31
33
  @steam_id = steam_id
@@ -0,0 +1,48 @@
1
+ # This code is free software; you can redistribute it and/or modify it under the
2
+ # terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ require 'stringio'
7
+
8
+ class StringIO
9
+
10
+ alias_method :data, :string
11
+
12
+ def self.allocate(size)
13
+ new "\0" * size
14
+ end
15
+
16
+ def byte
17
+ read(1)[0]
18
+ end
19
+
20
+ def float
21
+ read(4).unpack('e')[0]
22
+ end
23
+
24
+ def get
25
+ read remaining
26
+ end
27
+
28
+ def long
29
+ read(4).unpack('V')[0]
30
+ end
31
+
32
+ def remaining
33
+ size - pos
34
+ end
35
+
36
+ def short
37
+ read(2).unpack('v')[0]
38
+ end
39
+
40
+ def signed_long
41
+ read(4).unpack('l')[0]
42
+ end
43
+
44
+ def string
45
+ gets("\0")[0..-2]
46
+ end
47
+
48
+ end