warchat 0.0.9 → 0.0.10

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