steam-condenser 0.13.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/lib/exceptions/packet_format_exception.rb +12 -5
  2. data/lib/exceptions/rcon_ban_exception.rb +11 -3
  3. data/lib/exceptions/rcon_no_auth_exception.rb +10 -3
  4. data/lib/exceptions/steam_condenser_exception.rb +8 -5
  5. data/lib/exceptions/timeout_exception.rb +13 -3
  6. data/lib/exceptions/web_api_exception.rb +31 -23
  7. data/lib/steam-condenser.rb +9 -3
  8. data/lib/steam-condenser/community.rb +8 -1
  9. data/lib/steam-condenser/servers.rb +7 -1
  10. data/lib/steam-condenser/version.rb +2 -1
  11. data/lib/steam/community/cacheable.rb +4 -4
  12. data/lib/steam/community/game_inventory.rb +119 -0
  13. data/lib/steam/community/game_item.rb +38 -0
  14. data/lib/steam/community/game_stats.rb +10 -4
  15. data/lib/steam/community/portal2/portal2_inventory.rb +21 -0
  16. data/lib/steam/community/portal2/portal2_item.rb +35 -0
  17. data/lib/steam/community/portal2/portal2_stats.rb +28 -0
  18. data/lib/steam/community/tf2/tf2_inventory.rb +7 -37
  19. data/lib/steam/community/tf2/tf2_item.rb +8 -79
  20. data/lib/steam/community/tf2/tf2_stats.rb +10 -13
  21. data/lib/steam/community/web_api.rb +1 -0
  22. data/lib/steam/packets/a2m_get_servers_batch2_packet.rb +37 -4
  23. data/lib/steam/packets/a2s_info_packet.rb +10 -5
  24. data/lib/steam/packets/a2s_player_packet.rb +16 -6
  25. data/lib/steam/packets/a2s_rules_packet.rb +16 -4
  26. data/lib/steam/packets/a2s_serverquery_getchallenge_packet.rb +11 -5
  27. data/lib/steam/packets/c2m_checkmd5_packet.rb +10 -4
  28. data/lib/steam/packets/m2a_server_batch_packet.rb +19 -3
  29. data/lib/steam/packets/m2c_isvalidmd5_packet.rb +14 -5
  30. data/lib/steam/packets/m2s_requestrestart_packet.rb +14 -4
  31. data/lib/steam/packets/rcon/rcon_auth_request.rb +15 -3
  32. data/lib/steam/packets/rcon/rcon_auth_response.rb +17 -3
  33. data/lib/steam/packets/rcon/rcon_exec_request.rb +15 -3
  34. data/lib/steam/packets/rcon/rcon_exec_response.rb +20 -3
  35. data/lib/steam/packets/rcon/rcon_goldsrc_request.rb +18 -3
  36. data/lib/steam/packets/rcon/rcon_goldsrc_response.rb +17 -3
  37. data/lib/steam/packets/rcon/rcon_packet.rb +31 -3
  38. data/lib/steam/packets/rcon/rcon_packet_factory.rb +15 -5
  39. data/lib/steam/packets/rcon/rcon_terminator.rb +14 -5
  40. data/lib/steam/packets/request_with_challenge.rb +10 -5
  41. data/lib/steam/packets/s2a_info2_packet.rb +14 -5
  42. data/lib/steam/packets/s2a_info_base_packet.rb +16 -6
  43. data/lib/steam/packets/s2a_info_detailed_packet.rb +15 -8
  44. data/lib/steam/packets/s2a_logstring_packet.rb +11 -5
  45. data/lib/steam/packets/s2a_player_packet.rb +14 -6
  46. data/lib/steam/packets/s2a_rules_packet.rb +15 -5
  47. data/lib/steam/packets/s2c_challenge_packet.rb +17 -6
  48. data/lib/steam/packets/s2m_heartbeat2_packet.rb +18 -4
  49. data/lib/steam/packets/steam_packet.rb +14 -5
  50. data/lib/steam/packets/steam_packet_factory.rb +25 -2
  51. data/lib/steam/servers/game_server.rb +154 -25
  52. data/lib/steam/servers/goldsrc_server.rb +35 -3
  53. data/lib/steam/servers/master_server.rb +77 -23
  54. data/lib/steam/servers/server.rb +42 -3
  55. data/lib/steam/servers/source_server.rb +35 -11
  56. data/lib/stringio_additions.rb +48 -3
  57. data/test/query_tests.rb +4 -4
  58. metadata +11 -6
@@ -0,0 +1,21 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ require 'steam/community/game_inventory'
7
+ require 'steam/community/portal2/portal2_item'
8
+
9
+ # Represents the inventory (a.k.a. Robot Enrichment) of a Portal 2 player
10
+ class Portal2Inventory
11
+
12
+ include Cacheable
13
+ cacheable_with_ids :steam_id64
14
+
15
+ include GameInventory
16
+
17
+ @@app_id = 620
18
+
19
+ @@item_class = Portal2Item
20
+
21
+ end
@@ -0,0 +1,35 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ require 'steam/community/game_item'
7
+
8
+ # Represents a Portal 2 item
9
+ class Portal2Item
10
+
11
+ include GameItem
12
+
13
+ BOTS = [ :pbody, :atlas ]
14
+
15
+ # Creates a new instance of a Portal2Item with the given data
16
+ def initialize(inventory, item_data)
17
+ super
18
+
19
+ @equipped = {}
20
+ BOTS.each_index do |class_id|
21
+ @equipped[BOTS[class_id]] = (item_data[:inventory] & (1 << 16 + class_id) != 0)
22
+ end
23
+ end
24
+
25
+ # Returns the symbols for each bot this player has equipped this item
26
+ def bots_equipped?
27
+ @equipped.reject { |bot_id, equipped| !equipped }
28
+ end
29
+
30
+ # Returns whether this item is equipped by this player at all
31
+ def equipped?
32
+ @equipped.has_value? true
33
+ end
34
+
35
+ end
@@ -0,0 +1,28 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2011, Sebastian Staudt
5
+
6
+ require 'steam/community/game_stats'
7
+ require 'steam/community/portal2/portal2_inventory'
8
+
9
+ # The Portal2Stats class represents the game statistics for a single user in
10
+ # Portal 2
11
+ class Portal2Stats < GameStats
12
+
13
+ attr_reader :accumulated_points
14
+
15
+ # Creates a Portal2Stats object by calling the super constructor with the
16
+ # game name "portal2"
17
+ def initialize(steam_id)
18
+ super steam_id, 'portal2'
19
+ end
20
+
21
+ # Returns the current Portal 2 inventory (a.k.a Robot Enrichment) of this
22
+ # player
23
+ def inventory
24
+ @inventory = Portal2Inventory.new(steam_id64) if @inventory.nil?
25
+ @inventory
26
+ end
27
+
28
+ end
@@ -1,11 +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.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2010, Sebastian Staudt
4
+ # Copyright (c) 2010-2011, Sebastian Staudt
5
5
 
6
- require 'steam/community/cacheable'
6
+ require 'steam/community/game_inventory'
7
7
  require 'steam/community/tf2/tf2_item'
8
- require 'steam/community/web_api'
9
8
 
10
9
  # Represents the inventory (aka. Backpack) of a Team Fortress 2 player
11
10
  class TF2Inventory
@@ -13,39 +12,10 @@ class TF2Inventory
13
12
  include Cacheable
14
13
  cacheable_with_ids :steam_id64
15
14
 
16
- attr_reader :items, :steam_id64
15
+ include GameInventory
17
16
 
18
- # Creates a new inventory object for the given SteamID64. This calls update
19
- # to fetch the data and create the TF2Item instances contained in this
20
- # players backpack
21
- def initialize(steam_id64, fetch_now = true)
22
- @steam_id64 = steam_id64
17
+ @@app_id = 440
23
18
 
24
- super(fetch_now)
25
- end
26
-
27
- # Returns the item at the given position in the backpack. The positions range
28
- # from 1 to 100 instead of the usual array indices (0 to 99).
29
- def [](index)
30
- @items[index - 1]
31
- end
32
-
33
- # Updates the contents of the backpack using Steam Web API
34
- def fetch
35
- result = WebApi.json!('ITFItems_440', 'GetPlayerItems', 1, { :SteamID => @steam_id64 })
36
-
37
- @items = []
38
- result[:items][:item].each do |item_data|
39
- unless item_data.nil?
40
- item = TF2Item.new(item_data)
41
- @items[item.backpack_position - 1] = item
42
- end
43
- end
44
- end
45
-
46
- # Returns the number of items in the user's backpack
47
- def size
48
- @items.size
49
- end
19
+ @@item_class = TF2Item
50
20
 
51
21
  end
@@ -1,71 +1,25 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2010, Sebastian Staudt
4
+ # Copyright (c) 2010-2011, Sebastian Staudt
5
5
 
6
- require 'steam/community/web_api'
6
+ require 'steam/community/game_item'
7
7
 
8
8
  # Represents a Team Fortress 2 item
9
9
  class TF2Item
10
10
 
11
- CLASSES = [ :scout, :sniper, :soldier, :demoman, :medic, :heavy, :pyro, :spy ]
12
-
13
- attr_reader :attributes, :backpack_position, :class, :count, :defindex, :id,
14
- :level, :name, :quality, :slot, :type
15
-
16
- @@attribute_schema = nil
17
-
18
- @@item_schema = nil
11
+ include GameItem
19
12
 
20
- @@schema_language = 'en'
21
-
22
- # Returns the attribute schema
23
- #
24
- # The attribute schema is fetched first if not done already
25
- def self.attribute_schema
26
- update_schema if @@attribute_schema.nil?
27
-
28
- @@attribute_schema
29
- end
30
-
31
- # Returns the item schema
32
- #
33
- # The item schema is fetched first if not done already
34
- def self.item_schema
35
- update_schema if @@item_schema.nil?
36
-
37
- @@item_schema
38
- end
39
-
40
- # Sets the language the schema should be fetched in (default is: +'en'+)
41
- def self.schema_language=(language)
42
- @@schema_language = language
43
- end
13
+ CLASSES = [ :scout, :sniper, :soldier, :demoman, :medic, :heavy, :pyro, :spy ]
44
14
 
45
15
  # Creates a new instance of a TF2Item with the given data
46
- def initialize(item_data)
47
- update_schema if @@item_schema.nil?
48
-
49
- @defindex = item_data[:defindex]
50
-
51
- @backpack_position = item_data[:inventory] & 0xffff
52
- @class = @@item_schema[@defindex][:item_class]
53
- @count = item_data[:quantity]
54
- @id = item_data[:id]
55
- @level = item_data[:level]
56
- @name = @@item_schema[@defindex][:item_name]
57
- @quality = @@qualities[item_data[:quality]]
58
- @slot = @@item_schema[@defindex][:item_slot]
59
- @type = @@item_schema[@defindex][:item_type_name]
16
+ def initialize(inventory, item_data)
17
+ super
60
18
 
61
19
  @equipped = {}
62
20
  CLASSES.each_index do |class_id|
63
21
  @equipped[CLASSES[class_id]] = (item_data[:inventory] & (1 << 16 + class_id) != 0)
64
22
  end
65
-
66
- unless @@item_schema[@defindex][:attributes].nil?
67
- @attributes = @@item_schema[@defindex][:attributes][:attribute]
68
- end
69
23
  end
70
24
 
71
25
  # Returns the class symbols for each class this player has equipped this item
@@ -78,29 +32,4 @@ class TF2Item
78
32
  @equipped.has_value? true
79
33
  end
80
34
 
81
- protected
82
-
83
- # Updates the item schema (this includes attributes and qualities) using the
84
- # +GetSchema+ method of interface +ITFItems_440+
85
- def update_schema
86
- params = {}
87
- params[:language] = @@schema_language unless @@schema_language.nil?
88
- result = WebApi.json!('ITFItems_440', 'GetSchema', 1, params)
89
-
90
- @@attribute_schema = {}
91
- result[:attributes][:attribute].each do |attribute_data|
92
- @@attribute_schema[attribute_data[:name]] = attribute_data
93
- end
94
-
95
- @@item_schema = []
96
- result[:items][:item].each do |item_data|
97
- @@item_schema[item_data[:defindex]] = item_data
98
- end
99
-
100
- @@qualities = []
101
- result[:qualities].each do |quality, id|
102
- @@qualities[id] = quality
103
- end
104
- end
105
-
106
35
  end
@@ -1,7 +1,7 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/community/game_stats'
7
7
  require 'steam/community/tf2/tf2_class_factory'
@@ -23,16 +23,6 @@ class TF2Stats < GameStats
23
23
  end
24
24
  end
25
25
 
26
- # Returns the current Team Fortress 2 inventory (a.k.a. backpack) of this
27
- # player
28
- def inventory
29
- if @inventory.nil?
30
- @inventory = TF2Inventory.new(steam_id64)
31
- end
32
-
33
- @inventory
34
- end
35
-
36
26
  # Returns a Hash of TF2Class for this user containing all Team Fortress 2
37
27
  # classes. If the classes haven't been parsed already, parsing is done now.
38
28
  def class_stats
@@ -48,4 +38,11 @@ class TF2Stats < GameStats
48
38
  @class_stats
49
39
  end
50
40
 
41
+ # Returns the current Team Fortress 2 inventory (a.k.a. backpack) of this
42
+ # player
43
+ def inventory
44
+ @inventory = TF2Inventory.new(steam_id64) if @inventory.nil?
45
+ @inventory
46
+ end
47
+
51
48
  end
@@ -88,6 +88,7 @@ module WebApi
88
88
  open(url, { :proxy => true }).read
89
89
  rescue OpenURI::HTTPError
90
90
  status = $!.io.status[0]
91
+ status = [status, ''] unless status.is_a? Array
91
92
  raise WebApiException.new(:unauthorized) if status[0].to_i == 401
92
93
  raise WebApiException.new(:http_error, status[0].to_i, status[1])
93
94
  end
@@ -1,16 +1,46 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
  require 'steam/servers/master_server'
8
8
 
9
+ # This packet class represents a A2M_GET_SERVERS_BATCH2 request sent to a
10
+ # master server
11
+ #
12
+ # It is used to receive a list of game servers matching the specified filters.
13
+ #
14
+ # Filtering:
15
+ # Instead of filtering the results sent by the master server locally, you
16
+ # should at least use the following filters to narrow down the results sent by
17
+ # the master server. Receiving all servers from the master server is taking
18
+ # quite some time.
19
+ #
20
+ # Available filters:
21
+ #
22
+ # * `\type\d`: Request only dedicated servers
23
+ # * `\secure\1`: Request only secure servers
24
+ # * `\gamedir\[mod]`: Request only servers of a specific mod
25
+ # * `\map\[mapname]`: Request only servers running a specific map
26
+ # * `\linux\1`: Request only linux servers
27
+ # * `\emtpy\1`: Request only **non**-empty servers
28
+ # * `\full\`: Request only servers **not** full
29
+ # * `\proxy\1`: Request only spectator proxy servers
30
+ #
31
+ # @author Sebastian Staudt
32
+ # @see MasterServer#servers
9
33
  class A2M_GET_SERVERS_BATCH2_Packet
10
34
 
11
35
  include SteamPacket
12
36
 
13
- # Creates a master server request, filtering by the given paramters.
37
+ # Creates a master server request, filtering by the given paramters
38
+ #
39
+ # @param [Numeric] region_code The region code to filter servers by region
40
+ # @param [String] start_ip This should be the last IP received from the
41
+ # master server or 0.0.0.0
42
+ # @param [String] filter The filters to apply in the form
43
+ # "\filtername\value..."
14
44
  def initialize(region_code = MasterServer::REGION_ALL, start_ip = '0.0.0.0:0', filter = '')
15
45
  super A2M_GET_SERVERS_BATCH2_HEADER
16
46
 
@@ -19,6 +49,9 @@ class A2M_GET_SERVERS_BATCH2_Packet
19
49
  @start_ip = start_ip
20
50
  end
21
51
 
52
+ # Returns the raw data representing this packet
53
+ #
54
+ # @return [String] A string containing the raw data of this request packet
22
55
  def to_s
23
56
  [@header_data, @region_code, @start_ip, @filter].pack('c2Z*Z*')
24
57
  end
@@ -1,12 +1,17 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/steam_packet'
7
7
 
8
- # The A2S_INFO_Packet class represents a A2S_INFO request send to the
9
- # server.
8
+ # This packet class class represents a A2S_INFO request send to a game server
9
+ #
10
+ # It will cause the server to send some basic information about itself, e.g.
11
+ # the running game, map and the number of players.
12
+ #
13
+ # @author Sebastian Staudt
14
+ # @see GameServer#update_server_info
10
15
  class A2S_INFO_Packet
11
16
 
12
17
  include SteamPacket
@@ -1,19 +1,29 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
- # Copyright (c) 2008-2010, Sebastian Staudt
4
+ # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/request_with_challenge'
7
7
  require 'steam/packets/steam_packet'
8
8
 
9
- # The A2S_PLAYER_Packet class represents a A2S_PLAYER request send to the
10
- # server.
9
+ # This packet class represents a A2S_PLAYER request send to a game server
10
+ #
11
+ # It is used to request the list of players currently playing on the server.
12
+ #
13
+ # This packet type requires the client to challenge the server in advance,
14
+ # which is done automatically if required.
15
+ #
16
+ # @author Sebastian Staudt
17
+ # @see GameServer#update_player_info
11
18
  class A2S_PLAYER_Packet
12
19
 
13
20
  include SteamPacket
14
21
  include RequestWithChallenge
15
22
 
16
- # Creates a new A2S_PLAYER request object including the challenge_number
23
+ # Creates a new A2S_PLAYER request object including the challenge number
24
+ #
25
+ # @param [Numeric] challenge_number The challenge number received from the
26
+ # server
17
27
  def initialize(challenge_number = -1)
18
28
  super A2S_PLAYER_HEADER, challenge_number
19
29
  end
@@ -1,18 +1,30 @@
1
- # This code is free software; you can redistribute it and/or modify it under the
2
- # terms of the new BSD License.
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
3
  #
4
4
  # Copyright (c) 2008-2011, Sebastian Staudt
5
5
 
6
6
  require 'steam/packets/request_with_challenge'
7
7
  require 'steam/packets/steam_packet'
8
8
 
9
- # Creates a new A2S_RULES request object including the challenge_number
9
+ # This packet class represents a A2S_RULES request send to a game server
10
+ #
11
+ # The game server will return a list of currently active game rules, e.g.
12
+ # `mp_friendlyfire = 1`.
13
+ #
14
+ # This packet type requires the client to challenge the server in advance,
15
+ # which is done automatically if required.
16
+ #
17
+ # @author Sebastian Staudt
18
+ # @see GameServer#update_rules_info
10
19
  class A2S_RULES_Packet
11
20
 
12
21
  include SteamPacket
13
22
  include RequestWithChallenge
14
23
 
15
- # Creates a new A2S_RULES request object including the challenge_number
24
+ # Creates a new A2S_RULES request object including the challenge number
25
+ #
26
+ # @param [Numeric] challenge_number The challenge number received from the
27
+ # server
16
28
  def initialize(challenge_number = -1)
17
29
  super A2S_RULES_HEADER, challenge_number
18
30
  end