gruby 0.2.1
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.
- 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
|