gruby 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/CHANGELOG.rdoc +11 -0
- data/README.rdoc +52 -0
- data/Rakefile +16 -0
- data/VERSION +1 -0
- data/examples/status.rb +15 -0
- data/gruby.gemspec +55 -0
- data/lib/GRuby/GG.rb +145 -0
- data/lib/GRuby/GG_constants.rb +42 -0
- data/lib/GRuby/GG_packets.rb +241 -0
- data/lib/GRuby/GG_utils.rb +50 -0
- data/lib/gruby.rb +1 -0
- data/test/test_GRuby.rb +14 -0
- data/test/test_helper.rb +2 -0
- metadata +70 -0
data/.gitignore
ADDED
data/CHANGELOG.rdoc
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
== GRuby
|
2
|
+
http://gruby.rubyforge.org
|
3
|
+
http://fazibear.prv.pl
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Gadu-Gadu protocol implementation in Ruby language
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* loggin
|
12
|
+
* set status
|
13
|
+
* set status messages
|
14
|
+
* send messages
|
15
|
+
* recive messages
|
16
|
+
|
17
|
+
== SYNOPSIS:
|
18
|
+
|
19
|
+
require File.dirname(__FILE__) + '/../lib/GRuby'
|
20
|
+
|
21
|
+
gg_uin = ''
|
22
|
+
gg_pass = ''
|
23
|
+
|
24
|
+
gg = GG::new_session :uin => gg_uin, :password => gg_pass
|
25
|
+
gg.on_recive_message do |m|
|
26
|
+
gg.set_status :status => GG::STATUS_AVAIL_DESCR, :description => m.message
|
27
|
+
gg.send_message :uin => m.sender, :message => "Status '#{m.message}' was set"
|
28
|
+
end
|
29
|
+
gg.set_status :status => GG::STATUS_AVAIL_DESCR, :description => "Send me new status :)"
|
30
|
+
|
31
|
+
gets
|
32
|
+
|
33
|
+
== REQUIREMENTS:
|
34
|
+
|
35
|
+
* ruby
|
36
|
+
* gadu-gadu account
|
37
|
+
|
38
|
+
== INSTALL:
|
39
|
+
|
40
|
+
* sudo gem install gruby
|
41
|
+
|
42
|
+
== LICENSE:
|
43
|
+
|
44
|
+
GRuby - Gadu-Gadu protocol implementation in Ruby language
|
45
|
+
|
46
|
+
Copyright (C) 2007 Michal Kalbarczyk
|
47
|
+
|
48
|
+
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
|
49
|
+
|
50
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
51
|
+
|
52
|
+
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gemspec|
|
7
|
+
gemspec.name = "gruby"
|
8
|
+
gemspec.summary = "Gadu-Gadu protocol implementation in Ruby language"
|
9
|
+
gemspec.email = "fazibear@gmail.com"
|
10
|
+
gemspec.homepage = "http://github.com/fazibear/gruby"
|
11
|
+
gemspec.description = "Gadu-Gadu protocol implementation in Ruby language"
|
12
|
+
gemspec.authors = ["fazibear"]
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
16
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.2.1
|
data/examples/status.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../lib/GRuby'
|
4
|
+
|
5
|
+
gg_uin = ''
|
6
|
+
gg_pass = ''
|
7
|
+
|
8
|
+
gg = GG::new_session :uin => gg_uin, :password => gg_pass
|
9
|
+
gg.on_recive_message do |m|
|
10
|
+
gg.set_status :status => GG::STATUS_AVAIL_DESCR, :description => m.message
|
11
|
+
gg.send_message :uin => m.sender, :message => "Status '#{m.message}' was set"
|
12
|
+
end
|
13
|
+
gg.set_status :status => GG::STATUS_AVAIL_DESCR, :description => "Send me new status :)"
|
14
|
+
|
15
|
+
gets
|
data/gruby.gemspec
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{gruby}
|
8
|
+
s.version = "0.2.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["fazibear"]
|
12
|
+
s.date = %q{2009-11-23}
|
13
|
+
s.description = %q{Gadu-Gadu protocol implementation in Ruby language}
|
14
|
+
s.email = %q{fazibear@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"CHANGELOG.rdoc",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"examples/status.rb",
|
25
|
+
"gruby.gemspec",
|
26
|
+
"lib/GRuby/GG.rb",
|
27
|
+
"lib/GRuby/GG_constants.rb",
|
28
|
+
"lib/GRuby/GG_packets.rb",
|
29
|
+
"lib/GRuby/GG_utils.rb",
|
30
|
+
"lib/gruby.rb",
|
31
|
+
"test/test_GRuby.rb",
|
32
|
+
"test/test_helper.rb"
|
33
|
+
]
|
34
|
+
s.homepage = %q{http://github.com/fazibear/gruby}
|
35
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.3.5}
|
38
|
+
s.summary = %q{Gadu-Gadu protocol implementation in Ruby language}
|
39
|
+
s.test_files = [
|
40
|
+
"test/test_helper.rb",
|
41
|
+
"test/test_GRuby.rb",
|
42
|
+
"examples/status.rb"
|
43
|
+
]
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
50
|
+
else
|
51
|
+
end
|
52
|
+
else
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
data/lib/GRuby/GG.rb
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
module GG
|
2
|
+
|
3
|
+
#
|
4
|
+
# Return new GG session
|
5
|
+
#
|
6
|
+
def self.new_session( params )
|
7
|
+
Session.new( params )
|
8
|
+
end
|
9
|
+
|
10
|
+
class Session
|
11
|
+
|
12
|
+
attr_reader :connected
|
13
|
+
|
14
|
+
def initialize( params )
|
15
|
+
@uin = params[:uin]
|
16
|
+
@password = params[:password]
|
17
|
+
@message_seq = 0
|
18
|
+
@connected = true
|
19
|
+
@logged = false
|
20
|
+
@socket = nil
|
21
|
+
@wait4login = true
|
22
|
+
@wait4login = params[:async] unless params[:async].nil?
|
23
|
+
|
24
|
+
# callbacks
|
25
|
+
@revice_msg_callback = nil
|
26
|
+
@login_failed_callback = lambda do exit end
|
27
|
+
@disconnecting_callback = lambda do exit end
|
28
|
+
|
29
|
+
socket_thread = Thread.new do
|
30
|
+
begin
|
31
|
+
params = GG::connection_params
|
32
|
+
@socket = TCPSocket.new( params['host'] , params['port'] )
|
33
|
+
while @connected do
|
34
|
+
begin
|
35
|
+
r_packet = PACKET.new
|
36
|
+
puts ":: Wait for data ..." if $DEBUG
|
37
|
+
r_packet.header = @socket.read r_packet.header_length
|
38
|
+
r_packet.data = @socket.read r_packet.length
|
39
|
+
rescue => e
|
40
|
+
@logged = false
|
41
|
+
@connected = false
|
42
|
+
end
|
43
|
+
case r_packet.type
|
44
|
+
when WELCOME
|
45
|
+
r_packet.type = PACKET_WELCOME
|
46
|
+
s_packet = PACKET.new
|
47
|
+
s_packet.type = PACKET_LOGIN60
|
48
|
+
s_packet.uin = @uin.to_i
|
49
|
+
s_packet.hash = GG::login_hash( @password, r_packet.seed )
|
50
|
+
|
51
|
+
@socket.write s_packet.packed
|
52
|
+
puts "++ #{s_packet} send" if $DEBUG
|
53
|
+
s_packet = s_packet.destroy
|
54
|
+
when LOGIN_OK
|
55
|
+
@logged = true
|
56
|
+
@wait4login = false
|
57
|
+
when RECV_MSG
|
58
|
+
r_packet.type = PACKET_RECV_MSG
|
59
|
+
@recive_msg_callback.call r_packet if @recive_msg_callback
|
60
|
+
when SEND_MSG_ACK
|
61
|
+
r_packet.type = PACKET_SEND_MSG_ACK
|
62
|
+
when LOGIN_FAILED
|
63
|
+
puts "!! Login failed" if $DEBUG
|
64
|
+
@login_failed_callback.call if @login_failed_callback
|
65
|
+
when DISCONNECTING
|
66
|
+
puts "!! Disconecting" if $DEBUG
|
67
|
+
@disconnecting_callback.call if @disconnecting_callback
|
68
|
+
else
|
69
|
+
puts "?? Unknown packet" if $DEBUG
|
70
|
+
end
|
71
|
+
r_packet = r_packet.destroy
|
72
|
+
end
|
73
|
+
puts ":: Disconected" if $DEBUG
|
74
|
+
rescue => e
|
75
|
+
puts "!! Exception: #{e}" if $DEBUG
|
76
|
+
puts "Something went wrong :)" unless $DEBUG
|
77
|
+
exit 0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
while @wait4login do
|
81
|
+
sleep 1
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
#
|
87
|
+
# Recive message callback
|
88
|
+
#
|
89
|
+
def on_recive_message( &block )
|
90
|
+
@recive_msg_callback = block;
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Login failed callback
|
95
|
+
#
|
96
|
+
def on_login_failed( &block )
|
97
|
+
@login_failed = block;
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Disconnecting callback
|
102
|
+
#
|
103
|
+
def on_diconnect( &block )
|
104
|
+
@disconnecting_callback = block;
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Send message
|
109
|
+
# :uin => GG reciver number
|
110
|
+
# :message => message text
|
111
|
+
#
|
112
|
+
def send_message( params )
|
113
|
+
if @logged
|
114
|
+
s_packet = PACKET.new
|
115
|
+
s_packet.type = PACKET_SEND_MSG
|
116
|
+
s_packet.recipient = params[:uin]
|
117
|
+
s_packet.message = params[:message]
|
118
|
+
|
119
|
+
@socket.write s_packet.packed
|
120
|
+
puts "++ #{s_packet} send" if $DEBUG
|
121
|
+
s_packet = s_packet.destroy
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Set new status.
|
127
|
+
# :status => new status, see constans.
|
128
|
+
# :description => new description
|
129
|
+
#
|
130
|
+
def set_status( params )
|
131
|
+
if @logged
|
132
|
+
s_packet = PACKET.new
|
133
|
+
s_packet.type = PACKET_NEW_STATUS
|
134
|
+
s_packet.status = params[:status]
|
135
|
+
s_packet.description = params[:description]
|
136
|
+
|
137
|
+
@socket.write s_packet.packed
|
138
|
+
puts "++ #{s_packet} send" if $DEBUG
|
139
|
+
s_packet = s_packet.destroy
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module GG
|
2
|
+
HEADER = 0x0000
|
3
|
+
NEW_STATUS = 0x0002
|
4
|
+
PONG = 0x0007
|
5
|
+
PING = 0x0008
|
6
|
+
SEND_MSG = 0x000b
|
7
|
+
LOGIN = 0x000c
|
8
|
+
ADD_NOTIFY = 0x000d
|
9
|
+
REMOVE_NOTIFY = 0x000e
|
10
|
+
NOTIFY_FIRST = 0x000f
|
11
|
+
NOTIFY_LAST = 0x0010
|
12
|
+
LIST_EMPTY = 0x0012
|
13
|
+
LOGIN_EXT = 0x0013
|
14
|
+
PUBDIR50_REQUEST = 0x0014
|
15
|
+
LOGIN60 = 0x0015
|
16
|
+
USERLIST_REQUEST = 0x0016
|
17
|
+
|
18
|
+
WELCOME = 0x0001
|
19
|
+
STATUS = 0x0002
|
20
|
+
LOGIN_OK = 0x0003
|
21
|
+
SEND_MSG_ACK = 0x0005
|
22
|
+
LOGIN_FAILED = 0x0009
|
23
|
+
RECV_MSG = 0x000a
|
24
|
+
DISCONNECTING = 0x000b
|
25
|
+
NOTIFY_REPLY = 0x000c
|
26
|
+
PUBDIR50_REPLY = 0x000e
|
27
|
+
STATUS60 = 0x000f
|
28
|
+
USERLIST_REPLY = 0x0010
|
29
|
+
NOTIFY_REPLY60 = 0x0011
|
30
|
+
NEED_EMAIL = 0x0014
|
31
|
+
|
32
|
+
STATUS_NOT_AVAIL = 0x0001
|
33
|
+
STATUS_NOT_AVAIL_DESCR = 0x0015
|
34
|
+
STATUS_AVAIL = 0x0002
|
35
|
+
STATUS_AVAIL_DESCR = 0x0004
|
36
|
+
STATUS_BUSY = 0x0003
|
37
|
+
STATUS_BUSY_DESCR = 0x0005
|
38
|
+
STATUS_INVISIBLE = 0x0014
|
39
|
+
STATUS_INVISIBLE_DESCR = 0x0016
|
40
|
+
STATUS_BLOCKED = 0x0006
|
41
|
+
STATUS_FRIENDS_MASK = 0x8000
|
42
|
+
end
|
@@ -0,0 +1,241 @@
|
|
1
|
+
module GG
|
2
|
+
|
3
|
+
#
|
4
|
+
# GG Packet class
|
5
|
+
#
|
6
|
+
class PACKET
|
7
|
+
def initialize
|
8
|
+
puts "++ #{self} created" if $DEBUG
|
9
|
+
end
|
10
|
+
|
11
|
+
def destroy
|
12
|
+
puts "++ #{self} destroyed" if $DEBUG
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def header=(data)
|
17
|
+
unpacked = data.unpack 'II'
|
18
|
+
@type, @length = unpacked
|
19
|
+
puts "++ #{self} recived header ... type:#{@type} length:#{@length}" if $DEBUG
|
20
|
+
end
|
21
|
+
|
22
|
+
def header_length
|
23
|
+
8
|
24
|
+
end
|
25
|
+
|
26
|
+
def type
|
27
|
+
@type
|
28
|
+
end
|
29
|
+
|
30
|
+
def length
|
31
|
+
@length
|
32
|
+
end
|
33
|
+
|
34
|
+
def type=(type)
|
35
|
+
begin
|
36
|
+
self.extend type
|
37
|
+
puts "++ #{self} extend to #{type}" if $DEBUG
|
38
|
+
fields @data if @data
|
39
|
+
rescue => e
|
40
|
+
raise "class extend ... #{e}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def data=(data)
|
45
|
+
@data = data
|
46
|
+
puts "++ #{self} recived data" if $DEBUG
|
47
|
+
end
|
48
|
+
|
49
|
+
def pack(pattern)
|
50
|
+
begin
|
51
|
+
puts "++ #{self} data packed" if $DEBUG
|
52
|
+
packet.pack pattern
|
53
|
+
rescue => e
|
54
|
+
raise "packet pack ... #{e}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# RECV PACKETS #
|
60
|
+
|
61
|
+
module PACKET_WELCOME
|
62
|
+
attr_reader :seed
|
63
|
+
|
64
|
+
def type
|
65
|
+
WELCOME
|
66
|
+
end
|
67
|
+
|
68
|
+
def fields(data)
|
69
|
+
unpacked = data.unpack 'I'
|
70
|
+
@seed = unpacked[0]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module PACKET_RECV_MSG
|
75
|
+
attr_reader :sender # numer nadawcy
|
76
|
+
attr_reader :seq # numer sekwencyjny
|
77
|
+
attr_reader :time # czas nadania
|
78
|
+
attr_reader :class # klasa wiadomości
|
79
|
+
attr_reader :message # treść wiadomości
|
80
|
+
|
81
|
+
def type
|
82
|
+
RECV_MSG
|
83
|
+
end
|
84
|
+
|
85
|
+
def fields(data)
|
86
|
+
unpacked = data.unpack 'IIIIZ*'
|
87
|
+
@sender,
|
88
|
+
@seq,
|
89
|
+
@time,
|
90
|
+
@class,
|
91
|
+
@message = unpacked
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
module PACKET_SEND_MSG_ACK
|
97
|
+
attr_reader :status # stan wiadomości */
|
98
|
+
attr_reader :recipient # numer odbiorcy */
|
99
|
+
attr_reader :seq # numer sekwencyjny */
|
100
|
+
|
101
|
+
def type
|
102
|
+
SEND_MSG_ACK
|
103
|
+
end
|
104
|
+
|
105
|
+
def fields(data)
|
106
|
+
unpacked = data.unpack 'III'
|
107
|
+
@status,
|
108
|
+
@recipient,
|
109
|
+
@seq = unpacked
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# SEND PACKECTS #
|
114
|
+
|
115
|
+
module PACKET_LOGIN60
|
116
|
+
attr_writer :uin # mój numerek
|
117
|
+
attr_writer :hash # hash hasła */
|
118
|
+
attr_writer :status # status na dzień dobry */
|
119
|
+
attr_writer :version # moja wersja klienta */
|
120
|
+
attr_writer :unknown1 # 0x00 */
|
121
|
+
attr_writer :local_ip # mój adres ip */
|
122
|
+
attr_writer :local_port # port, na którym słucham */
|
123
|
+
attr_writer :external_ip # zewnętrzny adres ip */
|
124
|
+
attr_writer :external_port # zewnętrzny port */
|
125
|
+
attr_writer :image_size # maksymalny rozmiar grafiki w KB */
|
126
|
+
attr_writer :unknown2 # 0xbe */
|
127
|
+
attr_writer :description # opis, nie musi wystąpić */
|
128
|
+
attr_writer :time # czas, nie musi wystąpić */
|
129
|
+
|
130
|
+
def type
|
131
|
+
LOGIN60
|
132
|
+
end
|
133
|
+
|
134
|
+
def packet
|
135
|
+
[
|
136
|
+
type,
|
137
|
+
length,
|
138
|
+
@uin ? @uin : 0,
|
139
|
+
@hash ? @hash : 0,
|
140
|
+
@status ? @status : 0,
|
141
|
+
@version ? @version : 0x22,
|
142
|
+
@unknown1 ? @unknown1 : 0,
|
143
|
+
@local_ip ? @local_ip : 0,
|
144
|
+
@local_port ? @local_port : 0,
|
145
|
+
@external_ip ? @external_ip : 0,
|
146
|
+
@external_port ? @external_port : 0,
|
147
|
+
@image_size ? @image_size : 0,
|
148
|
+
@unknown2 ? @unknown2 : 0xBE,
|
149
|
+
@description ? "#{@description}" : "\0",
|
150
|
+
@time ? @time : 0
|
151
|
+
]
|
152
|
+
end
|
153
|
+
|
154
|
+
def length
|
155
|
+
4+4+4+4+1+4+2+4+2+1+1+(@description ? @description.length : 1)+4
|
156
|
+
end
|
157
|
+
|
158
|
+
def packed
|
159
|
+
pack 'II IIIIcIsIsccA*I'
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
module PACKET_NEW_STATUS
|
165
|
+
attr_writer :status # na jaki zmienić? */
|
166
|
+
attr_writer :description # opis, nie musi wystąpić */
|
167
|
+
attr_writer :time # czas, nie musi wystąpić */
|
168
|
+
|
169
|
+
def type
|
170
|
+
NEW_STATUS
|
171
|
+
end
|
172
|
+
|
173
|
+
def packet
|
174
|
+
[
|
175
|
+
type,
|
176
|
+
length,
|
177
|
+
@status ? @status : 0,
|
178
|
+
@description ? "#{@description}" : "\0",
|
179
|
+
@time ? @time : 0
|
180
|
+
]
|
181
|
+
end
|
182
|
+
|
183
|
+
def length
|
184
|
+
4+(@description ? @description.length : 1)+4
|
185
|
+
end
|
186
|
+
|
187
|
+
def packed
|
188
|
+
pack 'II IA*I'
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
module PACKET_LIST_EMPTY
|
193
|
+
def type
|
194
|
+
LIST_EMPTY
|
195
|
+
end
|
196
|
+
def packet
|
197
|
+
[
|
198
|
+
type,
|
199
|
+
length
|
200
|
+
]
|
201
|
+
end
|
202
|
+
|
203
|
+
def length
|
204
|
+
0
|
205
|
+
end
|
206
|
+
|
207
|
+
def packed
|
208
|
+
pack 'II'
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
module PACKET_SEND_MSG
|
213
|
+
attr_writer :recipient # numer odbiorcy */
|
214
|
+
attr_writer :seq # numer sekwencyjny */
|
215
|
+
attr_writer :class # klasa wiadomości */
|
216
|
+
attr_writer :message # treść */
|
217
|
+
|
218
|
+
def type
|
219
|
+
SEND_MSG
|
220
|
+
end
|
221
|
+
|
222
|
+
def packet
|
223
|
+
[
|
224
|
+
type,
|
225
|
+
length,
|
226
|
+
@recipient ? @recipient : 0,
|
227
|
+
@seq ? @seq : 0,
|
228
|
+
@class ? @class : 0x0008,
|
229
|
+
@message ? "#{@message}" : "\0"
|
230
|
+
]
|
231
|
+
end
|
232
|
+
|
233
|
+
def length
|
234
|
+
4+4+4+@message.length
|
235
|
+
end
|
236
|
+
|
237
|
+
def packed
|
238
|
+
pack 'II IIIA*'
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module GG
|
2
|
+
|
3
|
+
#
|
4
|
+
# Return calculated password hash.
|
5
|
+
#
|
6
|
+
def self.login_hash ( password, seed )
|
7
|
+
x = 0;
|
8
|
+
y = seed;
|
9
|
+
z = 0;
|
10
|
+
|
11
|
+
password.each_byte do |char|
|
12
|
+
x = ( x & 0xffffff00 ) | char.to_i
|
13
|
+
y ^= x;
|
14
|
+
y &= 0xffffffff
|
15
|
+
y += x;
|
16
|
+
y &= 0xffffffff
|
17
|
+
x <<= 8;
|
18
|
+
x &= 0xffffffff
|
19
|
+
y ^= x;
|
20
|
+
y &= 0xffffffff
|
21
|
+
x <<= 8;
|
22
|
+
x &= 0xffffffff
|
23
|
+
y -= x;
|
24
|
+
y &= 0xffffffff
|
25
|
+
x <<= 8;
|
26
|
+
x &= 0xffffffff
|
27
|
+
y ^= x;
|
28
|
+
y &= 0xffffffff
|
29
|
+
z = y & 0x1f;
|
30
|
+
z &= 0xffffffff
|
31
|
+
y = (y << z) | (y >> (32 - z))
|
32
|
+
y &= 0xffffffff
|
33
|
+
end
|
34
|
+
return y;
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Return connection params returned from gg server.
|
39
|
+
#
|
40
|
+
def self.connection_params
|
41
|
+
require 'open-uri'
|
42
|
+
gg_connection = open("http://appmsg.gadu-gadu.pl/appsvc/appmsg4.asp?fmnumber=").readlines[0].split(/\s/)[2].split(':')
|
43
|
+
gg_connection_param = {
|
44
|
+
'host' => gg_connection[0],
|
45
|
+
'port' => gg_connection[1]
|
46
|
+
}
|
47
|
+
puts ":: Connection params ... host:#{gg_connection_param['host']} port:#{gg_connection_param['port']}" if $DEBUG
|
48
|
+
return gg_connection_param
|
49
|
+
end
|
50
|
+
end
|
data/lib/gruby.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.join(File.dirname(__FILE__), 'GRuby/*.rb')].each { |lib| require lib }
|
data/test/test_GRuby.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
|
3
|
+
class TestGRuby < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_hash
|
9
|
+
hash_t = GG::login_hash('GG_HASH_TEST', 12345)
|
10
|
+
hash_e = 2990357796
|
11
|
+
assert_equal( hash_t, hash_e )
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- fazibear
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-23 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Gadu-Gadu protocol implementation in Ruby language
|
17
|
+
email: fazibear@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- .gitignore
|
26
|
+
- CHANGELOG.rdoc
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- VERSION
|
30
|
+
- examples/status.rb
|
31
|
+
- gruby.gemspec
|
32
|
+
- lib/GRuby/GG.rb
|
33
|
+
- lib/GRuby/GG_constants.rb
|
34
|
+
- lib/GRuby/GG_packets.rb
|
35
|
+
- lib/GRuby/GG_utils.rb
|
36
|
+
- lib/gruby.rb
|
37
|
+
- test/test_GRuby.rb
|
38
|
+
- test/test_helper.rb
|
39
|
+
has_rdoc: true
|
40
|
+
homepage: http://github.com/fazibear/gruby
|
41
|
+
licenses: []
|
42
|
+
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --charset=UTF-8
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
version:
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.3.5
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Gadu-Gadu protocol implementation in Ruby language
|
67
|
+
test_files:
|
68
|
+
- test/test_helper.rb
|
69
|
+
- test/test_GRuby.rb
|
70
|
+
- examples/status.rb
|