pwood-wowr 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,85 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ # TODO: This class requires some thought as its source is different to others
5
+ # The data source for other classes are single XML files that contain
6
+ # information relevant to the request.
7
+ # Dungeon data is stored in two large (7kb each) files.
8
+ # Even with caching this is going to be slow as the entire XML file has
9
+ # to be read in and built even for a single look-up.
10
+
11
+ module Wowr
12
+ module Classes
13
+ class Dungeon
14
+ attr_reader :id, :key, :name,
15
+ :level_minimum, :level_maximum,
16
+ :party_size, :raid,
17
+ :release, :heroic, :bosses
18
+
19
+ alias_method :to_s, :name
20
+ alias_method :to_i, :id
21
+ alias_method :max_level, :level_maximum
22
+ alias_method :min_level, :level_minimum
23
+
24
+ def initialize(elem)
25
+ @id = elem[:id].to_i
26
+ @key = elem[:key]
27
+ @level_minimum = elem[:levelMin].to_i
28
+ @level_maximum = elem[:levelMax].to_i
29
+ @party_size = elem[:partySize].to_i
30
+ @raid = (elem[:raid].to_i == 1) ? true : false
31
+ @release = elem[:release].to_i
32
+ @heroic = (elem[:hasHeroic].to_i == 1) ? true : false
33
+
34
+ # Ideally want to be able to get the boss by both ID and key
35
+ # but by using normal hash.
36
+ # After a test it seems the method below creates 2 references to an object.
37
+ @bosses = {}
38
+
39
+ (elem/:boss).each do |elem|
40
+ # TODO: Is this insane?
41
+ # After object test, appears this will be references to the same object
42
+ boss = Boss.new(elem)
43
+ @bosses[boss.id] = boss if boss.id
44
+ @bosses[boss.key] = boss if boss.key
45
+ end
46
+ end
47
+
48
+ # Add the name data from dungeonStrings.xml
49
+ def add_name_data(elem)
50
+ # puts elem.raw_string.to_yaml
51
+ @name = elem.attributes["name"]
52
+
53
+ (elem/:boss).each do |boss_elem|
54
+ id = boss_elem[:id].to_i
55
+ key = boss_elem[:key]
56
+
57
+ @bosses[id].add_name_data(boss_elem) if id
58
+ @bosses[key].add_name_data(boss_elem) if key
59
+ end
60
+ end
61
+ end
62
+
63
+
64
+ # Note Key or id can be nil
65
+ # Not both
66
+ class Boss
67
+ attr_reader :id, :key, :name, :type
68
+
69
+ alias_method :to_s, :name
70
+ alias_method :to_i, :id
71
+
72
+ def initialize(elem)
73
+ @id = elem[:id].to_i if elem[:id].to_i
74
+ @key = elem[:key] if elem[:key]
75
+ @id = @key if !elem[:id].to_i
76
+
77
+ @type = elem[:type]
78
+ end
79
+
80
+ def add_name_data(elem)
81
+ @name = elem['name']
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,163 @@
1
+ module Wowr
2
+ module Exceptions
3
+ def self.raise_me(code, options = {})
4
+ case code
5
+ when "noCharacter"
6
+ raise CharacterNotFound.new("Character '#{options[:character_name]}' not found.")
7
+ when "belowMinLevel"
8
+ raise CharacterBelowMinLevel.new("Character '#{options[:character_name]}' is below min level (10).")
9
+ else
10
+ raise StandardError.new("The XML returned an error: #{code.to_s}")
11
+ end
12
+ end
13
+
14
+ class InvalidXML < StandardError
15
+ end
16
+
17
+ class EmptyPage < StandardError
18
+ end
19
+
20
+ class ServerDoesNotExist < StandardError
21
+ def initialize(string)
22
+ super "Server at '#{string}' did not respond."
23
+ end
24
+ end
25
+
26
+ class CharacterNameNotSet < StandardError
27
+ def initialize
28
+ super "Character name not set in options or API constructor."
29
+ end
30
+ end
31
+
32
+ class GuildNameNotSet < StandardError
33
+ def initialize
34
+ super "Guild name not set in options or API constructor."
35
+ end
36
+ end
37
+
38
+ class ArenaTeamNameNotSet < StandardError
39
+ def initialize
40
+ super "Arena team name not set."
41
+ end
42
+ end
43
+
44
+ class CookieNotSet < StandardError
45
+ def initialize
46
+ super "Cookie required for secure requests not set. Use login(username, password) to retrieve cookie."
47
+ end
48
+ end
49
+
50
+ class GuildBankNotFound < StandardError
51
+ def initialize(guild)
52
+ super "Guild bank for '#{guild}' not found, this could be due to lack of access privileges or failed login attempt."
53
+ end
54
+ end
55
+
56
+ class InvalidLoginDetails < StandardError
57
+ def initialize
58
+ super "It was not possible to login using the username and password provided."
59
+ end
60
+ end
61
+
62
+ class LoginRequiresAuthenticator < StandardError
63
+ def initialize
64
+ super "It was not possible to login using the username and password provided, because an authenticator code is required."
65
+ end
66
+ end
67
+
68
+ class LoginBroken < StandardError
69
+ def initialize
70
+ super "It was not possible to login due to a failure of login logic."
71
+ end
72
+ end
73
+
74
+ class InvalidArenaTeamSize < StandardError
75
+ end
76
+
77
+ class RealmNotSet < StandardError
78
+ def initialize
79
+ super "Realm not set in options or API constructor."
80
+ end
81
+ end
82
+
83
+ class EventNotSet < StandardError
84
+ def initialize
85
+ super "Event not set in options or API constructor."
86
+ end
87
+ end
88
+
89
+ # Search (fold)
90
+ class SearchError < StandardError
91
+ end
92
+
93
+ class InvalidSearchType < SearchError
94
+ def initialize(string)
95
+ super "'#{string}' is not a valid search type."
96
+ end
97
+ end
98
+
99
+ class NoSearchString < SearchError
100
+ def initialize
101
+ super "No search string specified or string was empty."
102
+ end
103
+ end
104
+
105
+ class ElementNotFoundError < StandardError
106
+ end
107
+
108
+ class CharacterNotFound < ElementNotFoundError
109
+ def initialize(string)
110
+ super "Character not found with name '#{string}'."
111
+ end
112
+ end
113
+
114
+ class CharacterBelowMinLevel < ElementNotFoundError
115
+ def initialize(string)
116
+ super "Character with name '#{string}' is below min level (10)."
117
+ end
118
+ end
119
+
120
+ class CharacterNoInfo < StandardError
121
+ def initialize(string)
122
+ super "Character with name '#{string}' have no informations in the armory (not logged on WoW since last armory reset)"
123
+ end
124
+ end
125
+
126
+ class ItemNotFound < ElementNotFoundError
127
+ def initialize(string)
128
+ super "Item not found with name '#{string}'."
129
+ end
130
+ end
131
+
132
+ class GuildNotFound < ElementNotFoundError
133
+ def initialize(string)
134
+ super "Guild not found with name '#{string}'."
135
+ end
136
+ end
137
+
138
+ class ArenaTeamNotFound < ElementNotFoundError
139
+ def initialize(string)
140
+ super "Arena team not found with name '#{string}'."
141
+ end
142
+ end
143
+ # (end)
144
+
145
+ class InvalidIconSize < StandardError
146
+ def initialize(array)
147
+ super "Icon size must be: #{array.keys.inspect}"
148
+ end
149
+ end
150
+
151
+ class InvalidIconType < StandardError
152
+ def initialize(array)
153
+ super "Icon type must be: #{array.keys.inspect}"
154
+ end
155
+ end
156
+
157
+ class NetworkTimeout < StandardError
158
+ def initialize(string)
159
+ super "Network timeout '#{string}'."
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,67 @@
1
+ module Wowr
2
+ module Extensions
3
+
4
+ # Rails's cattr_ things. activesupport/lib/active_support/core_ext/class
5
+ # Really quite handy.
6
+ # Thanks Reve's Lisa Seelye
7
+ module Class #:nodoc:
8
+ def cattr_reader(*syms) #:nodoc:
9
+ syms.flatten.each do |sym|
10
+ next if sym.is_a?(Hash)
11
+ class_eval(<<-EOS, __FILE__, __LINE__)
12
+ unless defined? @@#{sym}
13
+ @@#{sym} = nil
14
+ end
15
+
16
+ def self.#{sym}
17
+ @@#{sym}
18
+ end
19
+
20
+ def #{sym}
21
+ @@#{sym}
22
+ end
23
+ EOS
24
+ end
25
+ end
26
+
27
+ def cattr_writer(*syms) #:nodoc:
28
+ options = syms.last.is_a?(Hash) ? syms.pop : {}
29
+ syms.flatten.each do |sym|
30
+ class_eval(<<-EOS, __FILE__, __LINE__)
31
+ unless defined? @@#{sym}
32
+ @@#{sym} = nil
33
+ end
34
+
35
+ def self.#{sym}=(obj)
36
+ @@#{sym} = obj
37
+ end
38
+ #{"
39
+ def #{sym}=(obj)
40
+ @@#{sym} = obj
41
+ end
42
+ " unless options[:instance_writer] == false }
43
+ EOS
44
+ end
45
+ end
46
+ def cattr_accessor(*syms) #:nodoc:
47
+ cattr_reader(*syms)
48
+ cattr_writer(*syms)
49
+ end
50
+
51
+
52
+ def stringy(sym) #:nodoc:
53
+ class_eval(<<-EOS, __FILE__, __LINE__)
54
+ def to_s
55
+ @#{sym}
56
+ end
57
+ EOS
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+
64
+
65
+ class Class #:nodoc:
66
+ include Wowr::Extensions::Class
67
+ end
@@ -0,0 +1,39 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ module Wowr
5
+ module Classes
6
+
7
+ # TODO: Fix default to_s option
8
+ class Money
9
+ attr_reader :total
10
+ alias_method :to_i, :total
11
+ alias_method :to_s, :total
12
+
13
+ def initialize(total)
14
+ @total = total
15
+ end
16
+
17
+ def gold
18
+ return (@total / 10000)
19
+ end
20
+
21
+ def silver
22
+ return (@total % 10000) / 100
23
+ end
24
+
25
+ def bronze
26
+ return @total % 100
27
+ end
28
+
29
+ def +(add)
30
+ return Money.new(self.total + add.total)
31
+ end
32
+
33
+ def -(add)
34
+ return Money.new(self.total - add.total)
35
+ end
36
+ end
37
+
38
+ end
39
+ end
@@ -0,0 +1,85 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'character.rb'
5
+
6
+ module Wowr #:nodoc:
7
+ module Classes #:nodoc:
8
+
9
+ # A player guild containing members
10
+ # Abstract
11
+ class Guild
12
+ attr_reader :name, :url, :realm
13
+ # :roster_url, :stats_url, :stats_url_escape,
14
+ alias_method :to_s, :name
15
+
16
+ def initialize(elem)
17
+ if (elem%'guildKey')
18
+ guild = (elem%'guildKey')
19
+ else
20
+ guild = elem
21
+ end
22
+
23
+ @name = guild[:name]
24
+ @url = guild[:url]
25
+ @realm = guild[:realm]
26
+ end
27
+ end
28
+
29
+ # Basic search information returned by the search.xml
30
+ # <guilds>
31
+ # <guild
32
+ # battleGroup="Ruin"
33
+ # faction="Alliance"
34
+ # factionId="0"
35
+ # name="HAND"
36
+ # realm="Stormrage"
37
+ # relevance="100"
38
+ # url="r=Stormrage&amp;n=HAND&amp;p=1"/>
39
+ # </guilds>
40
+ class SearchGuild < Guild
41
+ attr_reader :faction, :faction_id, :battle_group
42
+
43
+ def initialize(elem)
44
+ super(elem)
45
+
46
+ @battle_group = elem[:battleGroup]
47
+ @faction = elem[:faction]
48
+ @faction_id = elem[:factionId].to_i
49
+
50
+ @relevance = elem[:relevance].to_i
51
+ end
52
+ end
53
+
54
+ # Full guild data
55
+ # <guildKey factionId="0" name="HAND" nameUrl="HAND" realm="Stormrage" realmUrl="Stormrage" url="r=Stormrage&amp;n=HAND"/>
56
+ # <guildInfo>
57
+ # <guild>
58
+ # <members filterField="" filterValue="" maxPage="1" memberCount="1" page="1" sortDir="a" sortField="">
59
+ # <character class="Paladin" classId="2" gender="Male" genderId="0" level="14" name="Sturky" race="Dwarf" raceId="3" rank="0" url="r=Stormrage&amp;n=Sturky"/>
60
+ # </members>
61
+ # </guild>
62
+ # </guildInfo>
63
+ class FullGuild < Guild
64
+ attr_reader :members, :name_url, :realm_url, :member_count
65
+
66
+ def initialize(elem)
67
+ super(elem)
68
+
69
+ @name_url = elem[:nameUrl]
70
+ @realm_url = elem[:realmUrl]
71
+
72
+ # Guild/guild_id/guild_url not set for characters
73
+ if (elem%'guildInfo')
74
+ @member_count = (elem%'guildInfo'%'guild'%'members')[:memberCount].to_i || nil
75
+ @members = {}
76
+ (elem%'guildInfo'%'guild'%'members'/:character).each do |char|
77
+ # TODO: Change to search character?
78
+ members[char[:name]] = Character.new(char)
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,188 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'item.rb'
5
+ require 'general.rb'
6
+
7
+ module Wowr
8
+ module Classes
9
+
10
+ # def get_login_status
11
+ # name = xml%'loginStatus'[:username]
12
+ # return name == "" ? nil : name
13
+ # end
14
+
15
+ class GuildBank < Guild
16
+ attr_reader :motd, :info, :money, :ranks, :bags
17
+
18
+ def initialize(elem)
19
+ super(elem%'guildKey')
20
+
21
+ @motd = (elem%'guildMessages')[:motd]
22
+ @info = (elem%'guildMessages')[:info]
23
+ @info.gsub("&#10;", "\n")
24
+
25
+ @bags = []
26
+ (elem%'bags'/:bag).each do |bag|
27
+ @bags[bag[:id].to_i] = GuildBankBag.new(bag)
28
+ end
29
+
30
+ @ranks = []
31
+ (elem%'guildRanks'/:rank).each do |rank|
32
+ @ranks[rank[:id].to_i] = rank[:name]
33
+ end
34
+ end
35
+ end
36
+
37
+ # bags now contain references to the items
38
+ # Items can be accessed from items (within Wowr::Classes::GuildBankContents)
39
+ # Or by their individual bags using bag.items
40
+ class GuildBankContents < GuildBank
41
+ attr_reader :items
42
+
43
+ def initialize(elem, api = nil)
44
+ super(elem)
45
+ @money = Money.new((elem%'guildBank')[:money].to_i)
46
+
47
+ @items = []
48
+ (elem%'items'/:item).each do |item|
49
+ @items << GuildBankItem.new(item, bags, api)
50
+ end
51
+ end
52
+ end
53
+
54
+
55
+ # Consists of multiple groups, each with 1000 entries
56
+ class GuildBankLog < GuildBank
57
+ attr_reader :entries, :group_now, :group_next, :group_prev
58
+
59
+ def initialize(elem, api = nil)
60
+ super(elem)
61
+
62
+ @entries = []
63
+ (elem%'banklogs'/:banklog).each do |entry|
64
+ @entries << GuildBankLogEntry.new(entry, self, api)
65
+ end
66
+
67
+ @group_now = (elem%'banklogs')[:now].to_i
68
+ @group_next = (elem%'banklogs')[:next].to_i
69
+ @group_prev = (elem%'banklogs')[:prev].to_i
70
+ end
71
+ end
72
+
73
+
74
+ class GuildBankBag < Item
75
+ attr_reader :viewable
76
+ attr_accessor :items
77
+
78
+ def initialize(elem, api = nil)
79
+ super(elem, api)
80
+ @viewable = (@viewable == "true")
81
+
82
+ @items = []
83
+ end
84
+ end
85
+
86
+
87
+ # Zero to 1 items
88
+ # <banklog dtab="" money="1200000" otab="" player="Quixsilver" rank="0" ts="1212595269000" type="4"/>
89
+ # <banklog dtab="" money="0" otab="0" player="Quixsilver" rank="0" ts="1212527470000" type="2">
90
+ # <item count="1" icon="inv_potion_92" id="12820" name="Winterfall Firewater" qi="1" subtype="" type="consumables"/>
91
+ # </banklog>
92
+ class GuildBankLogEntry
93
+ attr_reader :dtab, :money, :otab, :player, :rank_id, :ts, :type_id, :item, :unknown
94
+
95
+ @@types = {
96
+ 1 => 'Deposit Item',
97
+ 2 => 'Withdraw Item',
98
+ 3 => 'Move Item',
99
+ 4 => 'Deposit Money',
100
+ 5 => 'Withdraw Money',
101
+ 6 => 'Repair',
102
+ 7 => 'Move Item',
103
+ 8 => 'Withdraw Money',
104
+ 9 => 'Guild Bank Tab Purchase'
105
+ }
106
+
107
+ def initialize(elem, bank = nil, api = nil)
108
+ @bank = bank
109
+
110
+ @dtab = elem[:dtab] == "" ? nil : elem[:dtab].to_i
111
+ @otab = elem[:otab] == "" ? nil : elem[:otab].to_i
112
+ @money = Money.new(elem[:money].to_i)
113
+ @player = elem[:player]
114
+ @unknown = elem[:unknown] == "1" ? true : false
115
+ @rank_id = elem[:rank].to_i
116
+ @ts = elem[:ts].to_i # TODO: Check TS isn't overloading
117
+ @type_id = elem[:type].to_i
118
+
119
+ if (elem%'item')
120
+ @item = GuildBankLogItem.new(elem%'item', api)
121
+ end
122
+ end
123
+
124
+ def type
125
+ return @@types[@type_id]
126
+ end
127
+
128
+ def rank
129
+ @rank_id.nil? ? nil : @bank.ranks[@rank_id]
130
+ end
131
+
132
+ def origin
133
+ @otab.nil? ? nil : @bank.bags[@otab]
134
+ end
135
+
136
+ def destination
137
+ @dtab.nil? ? nil : @bank.bags[@dtab]
138
+ end
139
+
140
+ def time
141
+ return Time.at(@ts / 1000)
142
+ end
143
+ end
144
+
145
+
146
+ # Simple item that appears in Wowr::Classes::GuildBankLog entries
147
+ # <item count="1" icon="inv_potion_92" id="12820" name="Winterfall Firewater" qi="1" subtype="" type="consumables"/>
148
+ class GuildBankLogItem < Item
149
+ attr_reader :count, :qi, :subtype, :type
150
+
151
+ def initialize(elem, api = nil)
152
+ super(elem, api)
153
+ @count = elem[:count].to_i
154
+ @qi = elem[:qi].to_i
155
+ @subtype = elem[:subtype] == "" ? nil : elem[:subtype]
156
+ @type = elem[:type]
157
+ end
158
+ end
159
+
160
+
161
+ # More detailed item used in full Wowr::Classes::GuildBank
162
+ # Very close to Wowr::Classes::EquippedItem
163
+ # <item bag="0" durability="0" icon="racial_dwarf_findtreasure" id="12219" maxDurability="0" name="Unadorned Seal of Ascension" qi="1" quantity="1" randomPropertiesId="0" seed="1827537860" slot="90" subtype="" subtypeLoc="Quest" type="consumables"/>
164
+ class GuildBankItem < Item
165
+ attr_reader :bag_id, :durability, :max_durability, :qi, :quantity,
166
+ :random_properties_id, :seed, :slot, :subtype, :subtype_loc, :type
167
+
168
+ def initialize(elem, bags = nil, api = nil)
169
+ super(elem, api)
170
+
171
+ @bag_id = elem[:bag].to_i
172
+ @qi = elem[:qi].to_i
173
+ @quantity = elem[:quantity].to_i
174
+
175
+ @durability = elem[:durability].to_i
176
+ @max_durability = elem[:maxDurability].to_i
177
+ @random_properties_id = elem[:randomPropertiesId] == 0 ? nil : elem[:randomPropertiesId].to_i
178
+ @seed = elem[:seed].to_i
179
+ @slot = elem[:slot].to_i
180
+ @subtype = elem[:subtype] == "" ? nil : elem[:subtype]
181
+ @subtype_loc = elem[:subtypeLoc] == "" ? nil : elem[:subtypeLoc]
182
+ @type = elem[:type].to_i
183
+
184
+ bags[@bag_id].items << self
185
+ end
186
+ end
187
+ end
188
+ end