steam-condenser 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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