steam-condenser 0.8.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.
Files changed (72) hide show
  1. data/LICENSE +25 -0
  2. data/README.md +30 -0
  3. data/Rakefile +42 -0
  4. data/lib/abstract_class.rb +40 -0
  5. data/lib/byte_buffer.rb +126 -0
  6. data/lib/datagram_channel.rb +70 -0
  7. data/lib/exceptions/buffer_underflow_exception.rb +10 -0
  8. data/lib/exceptions/packet_format_exception.rb +12 -0
  9. data/lib/exceptions/rcon_no_auth_exception.rb +14 -0
  10. data/lib/exceptions/steam_condenser_exception.rb +8 -0
  11. data/lib/exceptions/timeout_exception.rb +10 -0
  12. data/lib/socket_channel.rb +54 -0
  13. data/lib/steam-condenser.rb +3 -0
  14. data/lib/steam/community/dods/dods_class.rb +32 -0
  15. data/lib/steam/community/dods/dods_stats.rb +47 -0
  16. data/lib/steam/community/dods/dods_weapon.rb +54 -0
  17. data/lib/steam/community/game_achievement.rb +26 -0
  18. data/lib/steam/community/game_class.rb +15 -0
  19. data/lib/steam/community/game_stats.rb +92 -0
  20. data/lib/steam/community/game_weapon.rb +29 -0
  21. data/lib/steam/community/l4d/l4d_explosive.rb +23 -0
  22. data/lib/steam/community/l4d/l4d_map.rb +34 -0
  23. data/lib/steam/community/l4d/l4d_stats.rb +166 -0
  24. data/lib/steam/community/l4d/l4d_weapon.rb +23 -0
  25. data/lib/steam/community/steam_group.rb +16 -0
  26. data/lib/steam/community/steam_id.rb +212 -0
  27. data/lib/steam/community/tf2/tf2_class.rb +31 -0
  28. data/lib/steam/community/tf2/tf2_class_factory.rb +38 -0
  29. data/lib/steam/community/tf2/tf2_engineer.rb +25 -0
  30. data/lib/steam/community/tf2/tf2_medic.rb +22 -0
  31. data/lib/steam/community/tf2/tf2_sniper.rb +20 -0
  32. data/lib/steam/community/tf2/tf2_spy.rb +23 -0
  33. data/lib/steam/community/tf2/tf2_stats.rb +39 -0
  34. data/lib/steam/packets/a2a_ack_packet.rb +21 -0
  35. data/lib/steam/packets/a2a_ping_packet.rb +18 -0
  36. data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +25 -0
  37. data/lib/steam/packets/a2s_info_packet.rb +18 -0
  38. data/lib/steam/packets/a2s_player_packet.rb +22 -0
  39. data/lib/steam/packets/a2s_rules_packet.rb +21 -0
  40. data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +18 -0
  41. data/lib/steam/packets/m2a_server_batch_packet.rb +37 -0
  42. data/lib/steam/packets/rcon/rcon_auth_request.rb +16 -0
  43. data/lib/steam/packets/rcon/rcon_auth_response.rb +16 -0
  44. data/lib/steam/packets/rcon/rcon_exec_request.rb +16 -0
  45. data/lib/steam/packets/rcon/rcon_exec_response.rb +20 -0
  46. data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +20 -0
  47. data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +20 -0
  48. data/lib/steam/packets/rcon/rcon_packet.rb +36 -0
  49. data/lib/steam/packets/rcon/rcon_packet_factory.rb +37 -0
  50. data/lib/steam/packets/request_with_challenge.rb +16 -0
  51. data/lib/steam/packets/s2a_info2_packet.rb +48 -0
  52. data/lib/steam/packets/s2a_info_base_packet.rb +29 -0
  53. data/lib/steam/packets/s2a_info_detailed_packet.rb +50 -0
  54. data/lib/steam/packets/s2a_player_packet.rb +32 -0
  55. data/lib/steam/packets/s2a_rules_packet.rb +33 -0
  56. data/lib/steam/packets/s2c_challenge_packet.rb +23 -0
  57. data/lib/steam/packets/steam_packet.rb +48 -0
  58. data/lib/steam/packets/steam_packet_factory.rb +90 -0
  59. data/lib/steam/servers/game_server.rb +222 -0
  60. data/lib/steam/servers/goldsrc_server.rb +36 -0
  61. data/lib/steam/servers/master_server.rb +60 -0
  62. data/lib/steam/servers/source_server.rb +65 -0
  63. data/lib/steam/sockets/goldsrc_socket.rb +108 -0
  64. data/lib/steam/sockets/master_server_socket.rb +20 -0
  65. data/lib/steam/sockets/rcon_socket.rb +50 -0
  66. data/lib/steam/sockets/source_socket.rb +72 -0
  67. data/lib/steam/sockets/steam_socket.rb +63 -0
  68. data/lib/steam/steam_player.rb +51 -0
  69. data/test/query_tests.rb +71 -0
  70. data/test/rcon_tests.rb +79 -0
  71. data/test/steam_community_tests.rb +36 -0
  72. metadata +132 -0
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2008, Sebastian Staudt
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name of the author nor the names of its contributors
13
+ may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ Steam Condenser
2
+ ===============
3
+
4
+ The Steam Condenser is a multi-language library for querying the Steam
5
+ Community, Source and GoldSrc game servers as well as the Steam master servers.
6
+ Currently it is implemented in Java, PHP and Ruby.
7
+
8
+ ## Requirements
9
+
10
+ * Linux, MacOS X or Windows
11
+ * Ruby 1.8.6 or newer
12
+ * [Ruby BZ2 module](http://www.rubyforge.org/projects/bz2)
13
+
14
+ ## License
15
+
16
+ This code is free software; you can redistribute it and/or modify it under the
17
+ terms of the new BSD License. A copy of this license can be found in the LICENSE
18
+ file.
19
+
20
+ ## Credits
21
+
22
+ * Sebastian Staudt -- koraktor(at)gmail.com
23
+
24
+ ## See Also
25
+
26
+ * [Steam Condenser home](http://koraktor.github.com/steam-condenser)
27
+ * [Documentation](http://www.rdoc.info/projects/koraktor/steam-condenser)
28
+ * [GitHub project page](http://github.com/koraktor/steam-condenser)
29
+ * [Google group](http://groups.google.com/group/steam-condenser)
30
+ * [Ohloh profile](http://www.ohloh.net/projects/steam-condenser)
data/Rakefile ADDED
@@ -0,0 +1,42 @@
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) 2008-2009, Sebastian Staudt
5
+
6
+ require 'rake/rdoctask'
7
+ require 'rake/gempackagetask'
8
+ require 'rubygems'
9
+ require 'jeweler'
10
+
11
+ src_files = Dir.glob(File.join("lib", "**", "*.rb"))
12
+ test_files = Dir.glob(File.join("test", "**", "*.rb"))
13
+
14
+ # Gem specification
15
+ Jeweler::Tasks.new do |s|
16
+ s.name = "steam-condenser"
17
+ s.date = Time.now
18
+ s.description = s.summary = 'A multi-language library for querying Source, GoldSrc servers and Steam master servers'
19
+ s.authors = ['Sebastian Staudt']
20
+ s.email = 'koraktor@gmail.com'
21
+ s.homepage = 'http://github.com/koraktor/steam-condenser'
22
+
23
+ s.files = %w(README.md Rakefile LICENSE) + src_files + test_files
24
+ s.rdoc_options = ["--all", "--inline-source", "--line-numbers", "--charset=utf-8", "--webcvs=http://github.com/koraktor/steam-condenser/source/blob/master/ruby/%s"]
25
+ end
26
+
27
+ # Create a rake task +:rdoc+ to build the documentation
28
+ desc "Building docs"
29
+ Rake::RDocTask.new do |rdoc|
30
+ rdoc.title = "Steam Condenser documentation"
31
+ rdoc.rdoc_files.include ["lib/**/*.rb", "test/**/*.rb", "LICENSE", "README.md"]
32
+ rdoc.main = "README.md"
33
+ rdoc.rdoc_dir = "rdoc"
34
+ rdoc.options = ["--all", "--inline-source", "--line-numbers", "--charset=utf-8", "--webcvs=http://github.com/koraktor/steam-condenser/source/blob/master/ruby/%s"]
35
+ end
36
+
37
+ # Task for cleaning documentation and package directories
38
+ desc "Clean documentation and package directories"
39
+ task :clean do
40
+ FileUtils.rm_rf "doc"
41
+ FileUtils.rm_rf "pkg"
42
+ end
@@ -0,0 +1,40 @@
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) 2008, Sebastian Staudt
5
+ #
6
+ # $Id$
7
+
8
+ # This module is used to mimic the behavior of abstract classes known from other
9
+ # object-oriented programming languages
10
+ module AbstractClass
11
+
12
+ # If this module is included in a class:
13
+ # * protect the constructor of the class
14
+ # * make sure every derived class has a constructor calling the super
15
+ # constructor
16
+ def self.included(klass)
17
+ klass.module_eval do
18
+
19
+ class << self
20
+ protected :new
21
+
22
+ # Each derived class gets a constructor calling the super constructor
23
+ def inherited(klass)
24
+ klass.module_eval do
25
+
26
+ # The constructor for derived classes, simply calling the super
27
+ # constructor
28
+ def self.new(*args)
29
+ super
30
+ end
31
+
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ end
@@ -0,0 +1,126 @@
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) 2008, Sebastian Staudt
5
+
6
+ require "exceptions/buffer_underflow_exception"
7
+
8
+ # The ByteBuffer class derived from Java's java.nio.ByteBuffer
9
+ class ByteBuffer
10
+
11
+ attr_accessor :limit
12
+ attr_reader :position
13
+ protected :initialize
14
+
15
+ # Creates a new buffer with the given size in bytes
16
+ def self.allocate(length)
17
+ return ByteBuffer.new(0.chr * length)
18
+ end
19
+
20
+ # Creates a new buffer from an existing String
21
+ def self.wrap(byte_array)
22
+ return ByteBuffer.new(byte_array.to_s)
23
+ end
24
+
25
+ #
26
+ def initialize(byte_array)
27
+ if byte_array.is_a? ByteBuffer
28
+ raise Exception.new
29
+ end
30
+
31
+ @byte_array = byte_array.to_s
32
+ @capacity = @byte_array.length
33
+ @limit = @capacity
34
+ @position = 0
35
+ @mark = -1
36
+ end
37
+
38
+ def array
39
+ return @byte_array
40
+ end
41
+
42
+ def clear
43
+ @limit = @capacity
44
+ @position = 0
45
+ @mark = -1
46
+
47
+ return self
48
+ end
49
+
50
+ def flip
51
+ @limit = @position
52
+ @position = 0
53
+ @mark = -1
54
+
55
+ return self
56
+ end
57
+
58
+ def get(length = nil)
59
+ if length == nil
60
+ length = @limit - @position
61
+ elsif length > self.remaining
62
+ BufferUnderflowException.new
63
+ end
64
+
65
+ data = @byte_array[@position, length]
66
+ @position += length
67
+
68
+ return data
69
+ end
70
+
71
+ def get_byte
72
+ return self.get(1)[0]
73
+ end
74
+
75
+ def get_float
76
+ return self.get(4).unpack("e")[0]
77
+ end
78
+
79
+ def get_long
80
+ return self.get(4).unpack("V")[0]
81
+ end
82
+
83
+ def get_short
84
+ return self.get(2).unpack("v")[0]
85
+ end
86
+
87
+ def get_signed_long
88
+ return self.get(4).unpack('l')[0]
89
+ end
90
+
91
+ def get_string
92
+ zero_byte_index = @byte_array.index("\0", @position)
93
+ if zero_byte_index == nil
94
+ return ""
95
+ else
96
+ data_string = self.get(zero_byte_index - @position)
97
+ @position += 1
98
+ return data_string
99
+ end
100
+ end
101
+
102
+ def length
103
+ return @byte_array.length
104
+ end
105
+
106
+ def remaining
107
+ return @limit - @position
108
+ end
109
+
110
+ def rewind
111
+ @position = 0
112
+ @mark = -1
113
+
114
+ return self
115
+ end
116
+
117
+ def put(source_byte_array)
118
+ new_position = [source_byte_array.length, self.remaining].min
119
+
120
+ @byte_array[@position, new_position] = source_byte_array
121
+ @position = new_position
122
+
123
+ return self
124
+ end
125
+
126
+ end
@@ -0,0 +1,70 @@
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) 2008, Sebastian Staudt
5
+ #
6
+ # $Id$
7
+
8
+ require "byte_buffer"
9
+
10
+ class DatagramChannel
11
+
12
+ attr_reader :socket
13
+
14
+ def self.open
15
+ return DatagramChannel.new
16
+ end
17
+
18
+ def close
19
+ @socket.close
20
+ end
21
+
22
+ def connect(*args)
23
+ if args[0].is_a? IPAddr
24
+ ip_address = args[0].to_s
25
+ elsif args[0].is_a? String
26
+ sockaddr = (Socket.gethostbyname args[0])[3]
27
+ ip_address = "#{sockaddr[0]}.#{sockaddr[1]}.#{sockaddr[2]}.#{sockaddr[3]}"
28
+ end
29
+
30
+ if args[1].is_a? Numeric
31
+ port_number = args[1]
32
+ else
33
+ port_number = args[1].to_i
34
+ end
35
+
36
+ @socket.connect ip_address, port_number
37
+
38
+ return self
39
+ end
40
+
41
+ def configure_blocking(do_block)
42
+ end
43
+
44
+ def read(destination_buffer)
45
+ if !destination_buffer.is_a? ByteBuffer
46
+ raise ArgumentError
47
+ end
48
+
49
+ length = destination_buffer.remaining
50
+ data = @socket.recv length
51
+ destination_buffer.put data
52
+
53
+ return data.length
54
+ end
55
+
56
+ def write(source_buffer)
57
+ if !source_buffer.is_a? ByteBuffer
58
+ raise ArgumentError
59
+ end
60
+
61
+ return @socket.send(source_buffer.get, 0)
62
+ end
63
+
64
+ protected
65
+
66
+ def initialize
67
+ @socket = UDPSocket.new
68
+ self.configure_blocking true
69
+ end
70
+ end
@@ -0,0 +1,10 @@
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) 2008, Sebastian Staudt
5
+ #
6
+ # $Id$
7
+
8
+ class BufferUnderflowException < Exception
9
+
10
+ end
@@ -0,0 +1,12 @@
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) 2008, Sebastian Staudt
5
+ #
6
+ # $Id$
7
+
8
+ require "exceptions/steam_condenser_exception"
9
+
10
+ class PacketFormatException < SteamCondenserException
11
+
12
+ end
@@ -0,0 +1,14 @@
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) 2008, Sebastian Staudt
5
+ #
6
+ # $Id$
7
+
8
+ class RCONNoAuthException < Exception
9
+
10
+ def initialize
11
+ super "Not authenticated yet."
12
+ end
13
+
14
+ end
@@ -0,0 +1,8 @@
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) 2008-2009, Sebastian Staudt
5
+
6
+ class SteamCondenserException < StandardError
7
+
8
+ end
@@ -0,0 +1,10 @@
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) 2008-2009, Sebastian Staudt
5
+ #
6
+ # $Id$
7
+
8
+ class TimeoutException < StandardError
9
+
10
+ end
@@ -0,0 +1,54 @@
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) 2008-2009, Sebastian Staudt
5
+
6
+ require 'byte_buffer'
7
+ require 'timeout'
8
+
9
+ class SocketChannel
10
+
11
+ attr_reader :socket
12
+
13
+ def self.open
14
+ return SocketChannel.new
15
+ end
16
+
17
+ def connect(*args)
18
+ timeout(1) do
19
+ @socket = TCPSocket.new args[0][0][3], args[0][0][1]
20
+ @connected = true
21
+ end
22
+
23
+ return self
24
+ end
25
+
26
+ def initialize
27
+ @connected = false
28
+ end
29
+
30
+ def connected?
31
+ return @connected
32
+ end
33
+
34
+ def read(destination_buffer)
35
+ if !destination_buffer.is_a? ByteBuffer
36
+ raise ArgumentError
37
+ end
38
+
39
+ length = destination_buffer.remaining
40
+ data = @socket.recv length
41
+ destination_buffer.put data
42
+
43
+ return data.length
44
+ end
45
+
46
+ def write(source_buffer)
47
+ if !source_buffer.is_a? ByteBuffer
48
+ raise ArgumentError
49
+ end
50
+
51
+ return @socket.send(source_buffer.get, 0)
52
+ end
53
+
54
+ end