warchat 0.0.9 → 0.0.10

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.
@@ -25,6 +25,10 @@ This is a simple chat client that will let you talk in guild chat and receive me
25
25
  PASSWORD = ''
26
26
  CHARACTER_NAME = ''
27
27
  CHARACTER_REALM = ''
28
+ HOST = "m.us.wowarmory.com"
29
+ #HOST = "m.eu.wowarmory.com"
30
+ #HOST = "m.kr.wowarmory.com"
31
+ PORT = 8780
28
32
 
29
33
  client = Warchat::Chat::Client.new
30
34
 
@@ -35,18 +39,18 @@ This is a simple chat client that will let you talk in guild chat and receive me
35
39
  client.on_message = Proc.new do |message|
36
40
  case message.type
37
41
  when Warchat::Chat::Message::CHAT_MSG_TYPE_GUILD_CHAT
38
- puts "[Guild] #{message.character_name}: #{message.body}"
42
+ puts "[Guild] #{message.character.name}: #{message.body}"
39
43
  when Warchat::Chat::Message::CHAT_MSG_TYPE_GUILD_MOTD
40
44
  puts "MOTD: #{message.body}"
41
45
  when Warchat::Chat::Message::CHAT_MSG_TYPE_OFFICER_CHAT
42
- puts "[Officer] #{message.character_name}: #{message.body}"
46
+ puts "[Officer] #{message.character.name}: #{message.body}"
43
47
  when Warchat::Chat::Message::CHAT_MSG_TYPE_WHISPER
44
- puts "[Whisper] #{message.character_name}: #{message.body}"
48
+ puts "[Whisper] #{message.character.name}: #{message.body}"
45
49
  end
46
50
  end
47
51
 
48
52
  begin
49
- client.start(USERNAME,PASSWORD)
53
+ client.start(USERNAME,PASSWORD,HOST,PORT)
50
54
  loop do
51
55
  msg = gets.chomp
52
56
  client.message msg,Warchat::Chat::Message::CHAT_MSG_TYPE_GUILD_CHAT
@@ -1,7 +1,18 @@
1
1
  # encoding: ASCII-8BIT
2
- require 'active_support/inflector'
2
+ require 'active_support/all'
3
3
 
4
4
  module Warchat
5
+ def self.debug message
6
+ puts message if self.debug?
7
+ end
8
+
9
+ def self.debug?
10
+ @debug and true or false
11
+ end
12
+
13
+ def self.enable_debug v
14
+ @debug = v
15
+ end
5
16
  end
6
17
 
7
- [['*.rb'],['network','*.rb'],['srp','*.rb'],['chat','*.rb']].each do |p| Dir.glob(File.join(File.expand_path('../warchat',__FILE__),*p)).each &method(:require) end
18
+ [[],['network'],['srp'],['chat'],['models']].each do |p| Dir.glob(File.join(File.expand_path('../warchat',__FILE__),*(p << '*.rb')),&method(:require)) end
@@ -0,0 +1,7 @@
1
+ module Warchat
2
+ module Chat
3
+ class Ack
4
+
5
+ end
6
+ end
7
+ end
@@ -1,23 +1,22 @@
1
1
  # encoding: ASCII-8BIT
2
2
  module Warchat
3
3
  module Chat
4
- class Warchat::Chat::Client
5
- attr_accessor :on_message,:on_presence,:on_logout,:on_fail,:on_establish
4
+ class Client
5
+ attr_accessor :on_message,:on_presence,:on_logout,:on_fail,:on_establish,:on_presence_change,:on_ack
6
6
  attr_accessor :on_message_afk,:on_message_dnd,:on_message_guild_chat,:on_message_motd,:on_message_officer_chat,:on_message_whisper,:on_chat_logout
7
7
 
8
- attr_reader :session,:character_name,:character_realm
8
+ attr_reader :session,:character_name,:character_realm,:online_characters,:last_whisper
9
9
 
10
10
  def initialize
11
11
  @session = Warchat::Network::Session.new
12
-
13
12
  [:receive,:establish,:error].each do |m|
14
13
  session.send("on_#{m}=".to_sym, method("session_#{m}".to_sym))
15
14
  end
16
15
  end
17
16
 
18
- def start username, password
17
+ def start account_name, account_password,host="m.us.wowarmory.com",port=8780
19
18
  [username,password].each do |s| s.respond_to? :force_encoding and s.force_encoding(__ENCODING__) end
20
- self.session.start(username,password)
19
+ self.session.start(account_name,account_password,host,port)
21
20
  end
22
21
 
23
22
  def session_error response
@@ -38,7 +37,7 @@ module Warchat
38
37
  [character_name,character_realm].each do |s| s.respond_to? :force_encoding and s.force_encoding(__ENCODING__) end
39
38
  request = Warchat::Network::Request.new("/chat-login",:options=>{:mature_filter=>'false'},:n=>character_name,:r=>character_realm)
40
39
  session.send_request(request)
41
- @timer = Warchat::Timer.new(30) do keep_alive end
40
+ @timer = Warchat::Timer.new(60) do keep_alive end
42
41
  end
43
42
 
44
43
  def logout
@@ -46,28 +45,33 @@ module Warchat
46
45
  end
47
46
 
48
47
  def chat_logout response
49
- puts 'Logged out of chat'
48
+ Warchat.debug 'Logged out of chat'
50
49
  @timer and @timer.stop
51
50
  on_chat_logout and on_chat_logout.call response
52
51
  session.close
53
52
  end
54
53
 
55
54
  def chat_login response
56
- puts "Logged into chat"
55
+ Warchat.debug "Logged into chat"
57
56
  @chat_session_id = response["chatSessionId"]
58
57
  end
58
+
59
+ def chat_presence presence
60
+ on_presence and on_presence.call(presence)
61
+ end
59
62
 
60
63
  def chat response
61
64
  response.extend(Warchat::Chat::ChatResponse)
62
65
  if response.ack?
63
-
66
+ on_ack and on_ack.call response
64
67
  elsif response.message?
65
68
  message = Warchat::Chat::Message.new(response)
69
+ @last_whisper = message if message.whisper?
66
70
  [on_message,send("on_message_#{message.type}".to_sym)].compact.each do |m| m.call(message) end
67
71
  elsif response.presence?
68
- on_presence and on_presence.call(Presence.new(response))
72
+ chat_presence Warchat::Chat::Presence.new(response)
69
73
  else
70
- puts "unhandled chat type: #{response.chat_type}"
74
+ Warchat.debug "unhandled chat type: #{response.chat_type}"
71
75
  end
72
76
  end
73
77
 
@@ -82,7 +86,7 @@ module Warchat
82
86
  end
83
87
 
84
88
  def keep_alive
85
- puts 'keep alive'
89
+ Warchat.debug 'keep alive'
86
90
  request = Warchat::Network::Request.new("/ah-mail",:n=>character_name,:r=>character_realm)
87
91
  session.send_request(request)
88
92
  end
@@ -2,10 +2,6 @@
2
2
  module Warchat
3
3
  module Chat
4
4
  class Message
5
- CHAT_ID_TYPE_CHARACTER = "character"
6
- CHAT_ID_TYPE_GUILD = "guild"
7
- CHAT_ID_TYPE_GUILD_MEMBER = "guild_member"
8
-
9
5
  CHAT_MSG_TYPE_AFK = "afk"
10
6
  CHAT_MSG_TYPE_DND = "dnd"
11
7
  CHAT_MSG_TYPE_GUILD_CHAT = "guild_chat"
@@ -13,24 +9,31 @@ module Warchat
13
9
  CHAT_MSG_TYPE_OFFICER_CHAT = "officer_chat"
14
10
  CHAT_MSG_TYPE_WHISPER = "whisper"
15
11
 
16
- attr_reader :type,:body,:from_type,:character_id,:from
12
+ attr_reader :type,:body
17
13
 
18
14
  def initialize response
15
+ @response = response
19
16
  @type = response["messageType"]
20
17
  @body = response['body']
21
- @from = response["from"]
22
- if @from
23
- @from_type = from["chatIdType"]
24
- @character_id = from["characterId"]
25
- end
18
+ @from = (response["from"] or {})
26
19
  end
27
-
28
- def character_name
29
- @character_id and @character_id.split(':')[-2]
20
+
21
+ def guild
22
+ return @guild if @guild or @from["guildId"].nil?
23
+ _,name,realm = @response['from']["guildId"].split(':')
24
+ @guild = Warchat::Models::Guild.find_or_create 'n' => name,'r'=>realm
30
25
  end
31
-
32
- def realm_id
33
- @character_id and @character_id.split(':').last
26
+
27
+ def character
28
+ return @character if @character or @from["characterId"].nil?
29
+ _,name,realm = @from["characterId"].split(':')
30
+ @character = Warchat::Models::Character.find_or_create 'n' => name,'r'=>realm
31
+ end
32
+
33
+ constants.select do |c| c[0..13] == 'CHAT_MSG_TYPE_' end.map do |c| "Warchat::Chat::Message::#{c}" end.each do |c|
34
+ define_method "#{c.constantize}?".to_sym do
35
+ type == c.constantize
36
+ end
34
37
  end
35
38
  end
36
39
  end
@@ -1,23 +1,39 @@
1
1
  # encoding: ASCII-8BIT
2
2
  module Warchat
3
3
  module Chat
4
- class Presence
5
- attr_reader :name,:character
6
-
4
+ class Presence
5
+ STATUS_OFFLINE = 'offline'
6
+ STATUS_ONLINE = 'online'
7
+
7
8
  def initialize response
8
- @type = response["presenceType"];
9
- @character = response["character"];
10
- @name = character["n"];
9
+ @response = response
10
+ @type = response["presenceType"]
11
+
12
+ character.respond_to? status.to_sym and character.send status.to_sym
13
+
14
+ end
15
+
16
+ def character
17
+ @character ||= (@response["character"] and Warchat::Models::Character.find_or_create(@response["character"]) or nil)
11
18
  end
12
19
 
13
20
  def offline?
14
21
  @type and @type.include? 'offline'
15
22
  end
23
+
24
+ def status
25
+ return 'unknown' unless @type
26
+ @type.split('_').first
27
+ end
16
28
 
17
- def type
29
+ def client_type
18
30
  return 'unknown' unless @type
19
31
  @type.split('_')[1..-1].join '_'
20
32
  end
33
+
34
+ def inspect
35
+ "<#{self.class.name} character:#{character.inspect} status:#{status.inspect} client_type:#{client_type.inspect}>"
36
+ end
21
37
  end
22
38
  end
23
39
  end
@@ -0,0 +1,53 @@
1
+ module Warchat
2
+ class Model
3
+ class << self
4
+ def find_or_create data
5
+ find(data).tap do |m| m and m.update(data) end or new(data)
6
+ end
7
+
8
+ def find data
9
+ realm,name = data['r'],data['n']
10
+ mutex.synchronize do all[realm] and all[realm][name] or nil end
11
+ end
12
+
13
+ def mutex
14
+ @mutex ||= Mutex.new
15
+ end
16
+
17
+ def all
18
+ @all ||= {}
19
+ end
20
+
21
+ private
22
+ def add m
23
+ mutex.synchronize do
24
+ all[m.realm] ||= {}
25
+ all[m.realm][m.name] and all[m.realm][m.name].update(m.data) or all[m.realm][m.name] = m
26
+ end
27
+ end
28
+ end
29
+
30
+ attr_accessor :data
31
+
32
+ def initialize data
33
+ @data = data
34
+ self.class.send(:add,self)
35
+ end
36
+
37
+ def id
38
+ [self.class.name.underscore,name,realm].join ':'
39
+ end
40
+
41
+ def update data
42
+ @data = @data.merge data
43
+ end
44
+
45
+ def name
46
+ data['n']
47
+ end
48
+
49
+ def realm
50
+ data['r']
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,51 @@
1
+ module Warchat
2
+ module Models
3
+ class Character < Warchat::Model
4
+ CLASSES = {1=>'Warrior',2=>'Paladin',3=>'Hunter',4=>'Rogue',5=>'Priest',6=>'Death Knight',7=>'Shaman',8=>'Mage',9=>'Warlock',11=>'Druid'}
5
+ RACES = {1=>'Human',2=>'Orc',3=>'Dwarf',4=>'Night Elf',5=>'Forsaken',6=>'Tauren',7=>'Gnome',8=>'Troll',9=>'Goblin',10=>'Blood Elf',11=>'Draenei',22=>'Worgen'}
6
+
7
+ class << self
8
+ def online
9
+ all.select &:online?
10
+ end
11
+ end
12
+
13
+ def initialize data
14
+ super
15
+ @count = 0
16
+ end
17
+
18
+ def level
19
+ data['l']
20
+ end
21
+
22
+ def rank
23
+ data['grank']
24
+ end
25
+
26
+ def klass
27
+ CLASSES[data['c']]
28
+ end
29
+
30
+ def race
31
+ RACES[data['ra']]
32
+ end
33
+
34
+ def online?
35
+ count > 0
36
+ end
37
+
38
+ def online
39
+ @count += 1
40
+ end
41
+
42
+ def offline
43
+ @count -= 1
44
+ end
45
+
46
+ def inspect
47
+ "<#{self.class.name} name:#{name.inspect} realm:#{realm.inspect} klass:#{klass.inspect} level:#{level.inspect} race:#{race.inspect}>"
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,7 @@
1
+ module Warchat
2
+ module Models
3
+ class Guild < Warchat::Model
4
+
5
+ end
6
+ end
7
+ end
@@ -37,11 +37,15 @@ module Warchat
37
37
  end.flatten(1)]
38
38
  end
39
39
 
40
- {16=>'n',32=>'N',64=>'L_'}.each do |size,directive|
40
+ {16=>'n',32=>'N'}.each do |size,directive|
41
41
  define_method "int_#{size}".to_sym do
42
42
  substream(size/8).unpack(directive).first
43
43
  end
44
44
  end
45
+
46
+ def int_64
47
+ [substream(8).unpack('L_').first.to_s(16)].pack('H*').reverse.unpack('H*').first.hex
48
+ end
45
49
 
46
50
  def boolean
47
51
  byte == "\001"
@@ -6,19 +6,15 @@ module Warchat
6
6
  module Network
7
7
  class Connection
8
8
 
9
- attr_accessor :host,:port,:on_send,:on_receive,:on_close
9
+ attr_accessor :on_send,:on_receive,:on_close
10
10
 
11
- def initialize *args
12
- options = args.pop if args.last.is_a? Hash
13
-
14
- self.host = (args.shift or "m.us.wowarmory.com")
15
- self.port = (args.shift or 8780)
11
+ def initialize
16
12
  @closed = true
17
13
  @queue = []
18
14
  @mutex = Mutex.new
19
15
  end
20
16
 
21
- def start
17
+ def start host="m.us.wowarmory.com",port=8780
22
18
  close
23
19
 
24
20
  @closed = false;
@@ -59,8 +55,8 @@ module Warchat
59
55
  sleep 0.01
60
56
  end
61
57
  rescue Exception => e
62
- puts e.message
63
- puts e.backtrace unless e.is_a? IOError
58
+ Warchat.debug e.message
59
+ Warchat.debug e.backtrace unless e.is_a? IOError
64
60
  end
65
61
 
66
62
  def handle_requests
@@ -78,8 +74,8 @@ module Warchat
78
74
  sleep 0.01
79
75
  end
80
76
  rescue Exception => e
81
- puts e.message
82
- puts e.backtrace
77
+ Warchat.debug e.message
78
+ Warchat.debug e.backtrace
83
79
  end
84
80
  end
85
81
  end
@@ -13,11 +13,11 @@ module Warchat
13
13
  @connection.on_receive = method(:connection_receive)
14
14
  end
15
15
 
16
- def start account_name, password
16
+ def start account_name, account_password,host="m.us.wowarmory.com",port=8780
17
17
  @account_name = account_name
18
- @password = password
18
+ @account_password = account_password
19
19
 
20
- @connection.start
20
+ @connection.start host,port
21
21
 
22
22
  @srp = Warchat::Srp::Client.new
23
23
 
@@ -55,7 +55,7 @@ module Warchat
55
55
  end
56
56
 
57
57
  def stage_1 response
58
- proof = @srp.auth1_proof(response["user"], @password[0..15].upcase, response["salt"], response["B"])
58
+ proof = @srp.auth1_proof(response["user"], @account_password[0..15].upcase, response["salt"], response["B"])
59
59
  send_request(Request.new("/authenticate2",:clientProof=>proof))
60
60
  end
61
61
 
@@ -74,7 +74,7 @@ module Warchat
74
74
  respond_to? m and send(m,response) or on_receive and on_receive.call(response)
75
75
  else
76
76
  error = response["body"]
77
- puts("error: " + error)
77
+ Warchat.debug("error: " + error)
78
78
  close(error) if respond_to? m
79
79
  end
80
80
  end
@@ -15,8 +15,8 @@ module Warchat
15
15
  begin
16
16
  handler.call
17
17
  rescue Exception => e
18
- puts e.message
19
- puts e.backtrace
18
+ Warchat.debug e.message
19
+ Warchat.debug e.backtrace
20
20
  end
21
21
  end
22
22
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: ASCII-8BIT
2
2
  module Warchat
3
- VERSION = "0.0.9"
3
+ VERSION = "0.0.10"
4
4
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: warchat
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
4
+ hash: 11
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 9
10
- version: 0.0.9
9
+ - 10
10
+ version: 0.0.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - Zachary Gavin
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-18 00:00:00 -04:00
18
+ date: 2011-05-27 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -66,10 +66,14 @@ files:
66
66
  - Rakefile
67
67
  - lib/warchat.rb
68
68
  - lib/warchat/byte_string.rb
69
+ - lib/warchat/chat/ack.rb
69
70
  - lib/warchat/chat/chat_response.rb
70
71
  - lib/warchat/chat/client.rb
71
72
  - lib/warchat/chat/message.rb
72
73
  - lib/warchat/chat/presence.rb
74
+ - lib/warchat/model.rb
75
+ - lib/warchat/models/character.rb
76
+ - lib/warchat/models/guild.rb
73
77
  - lib/warchat/network/binary_reader.rb
74
78
  - lib/warchat/network/binary_writer.rb
75
79
  - lib/warchat/network/connection.rb
@@ -110,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
114
  requirements: []
111
115
 
112
116
  rubyforge_project: warchat
113
- rubygems_version: 1.3.7
117
+ rubygems_version: 1.5.0
114
118
  signing_key:
115
119
  specification_version: 3
116
120
  summary: A simple interface to World of Warcraft Remote Guild Chat based off Eike Siewertsen's C# implementation