mtproto 0.0.9 → 0.0.11
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.
- checksums.yaml +4 -4
- data/data/tl-schema.json +42686 -0
- data/ext/aes_ige/extconf.rb +1 -1
- data/ext/factorization/extconf.rb +1 -1
- data/lib/mtproto/client/api/get_dialogs.rb +21 -0
- data/lib/mtproto/client/api/get_history.rb +20 -0
- data/lib/mtproto/client/api.rb +8 -0
- data/lib/mtproto/client/rpc.rb +4 -7
- data/lib/mtproto/client.rb +7 -7
- data/lib/mtproto/errors.rb +8 -0
- data/lib/mtproto/tl/constructor_names.rb +2271 -0
- data/lib/mtproto/tl/constructors.rb +91 -2261
- data/lib/mtproto/tl/object.rb +1 -1
- data/lib/mtproto/tl/objects/account_password.rb +2 -5
- data/lib/mtproto/tl/objects/authorization.rb +2 -5
- data/lib/mtproto/tl/objects/check_password.rb +2 -5
- data/lib/mtproto/tl/objects/client_dh_inner_data.rb +1 -3
- data/lib/mtproto/tl/objects/dh_gen_response.rb +3 -7
- data/lib/mtproto/tl/objects/dialogs.rb +453 -0
- data/lib/mtproto/tl/objects/export_login_token.rb +2 -5
- data/lib/mtproto/tl/objects/get_config.rb +1 -3
- data/lib/mtproto/tl/objects/get_dialogs.rb +51 -0
- data/lib/mtproto/tl/objects/get_difference.rb +1 -3
- data/lib/mtproto/tl/objects/get_history.rb +49 -0
- data/lib/mtproto/tl/objects/get_password.rb +1 -3
- data/lib/mtproto/tl/objects/get_state.rb +1 -3
- data/lib/mtproto/tl/objects/get_users.rb +3 -7
- data/lib/mtproto/{type → tl/objects}/gzip_packed.rb +1 -3
- data/lib/mtproto/tl/objects/help_config.rb +4 -5
- data/lib/mtproto/tl/objects/import_login_token.rb +1 -3
- data/lib/mtproto/tl/objects/init_connection.rb +1 -3
- data/lib/mtproto/tl/objects/invoke_with_layer.rb +1 -3
- data/lib/mtproto/tl/objects/login_token.rb +3 -7
- data/lib/mtproto/{type → tl/objects}/message.rb +1 -1
- data/lib/mtproto/tl/objects/messages.rb +162 -0
- data/lib/mtproto/{type → tl/objects}/msg_container.rb +1 -3
- data/lib/mtproto/{type → tl/objects}/new_session_created.rb +1 -3
- data/lib/mtproto/tl/objects/pq_inner_data.rb +1 -4
- data/lib/mtproto/tl/objects/req_dh_params.rb +1 -3
- data/lib/mtproto/tl/objects/req_pq_multi.rb +1 -3
- data/lib/mtproto/tl/objects/res_pq.rb +2 -4
- data/lib/mtproto/{type → tl/objects}/rpc_error.rb +1 -3
- data/lib/mtproto/tl/objects/send_code.rb +2 -5
- data/lib/mtproto/tl/objects/sent_code.rb +4 -4
- data/lib/mtproto/tl/objects/server_dh_inner_data.rb +3 -3
- data/lib/mtproto/tl/objects/server_dh_params.rb +3 -3
- data/lib/mtproto/tl/objects/set_client_dh_params.rb +1 -3
- data/lib/mtproto/tl/objects/sign_in.rb +1 -3
- data/lib/mtproto/tl/objects/update.rb +3 -6
- data/lib/mtproto/tl/objects/update_short.rb +0 -2
- data/lib/mtproto/tl/objects/update_short_message.rb +0 -2
- data/lib/mtproto/tl/objects/updates_difference.rb +6 -11
- data/lib/mtproto/tl/objects/updates_state.rb +1 -3
- data/lib/mtproto/tl/objects/users.rb +2 -5
- data/lib/mtproto/tl/schema.rb +102 -0
- data/lib/mtproto/version.rb +1 -1
- data/lib/mtproto.rb +6 -10
- metadata +15 -11
- data/lib/mtproto/type/bad_msg_notification.rb +0 -46
- data/lib/mtproto/type/client_dh_inner_data.rb +0 -29
- data/lib/mtproto/type/pq_inner_data.rb +0 -41
- data/lib/mtproto/type/serializer.rb +0 -55
- data/lib/mtproto/type/server_dh_inner_data.rb +0 -85
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MTProto
|
|
4
|
+
module TL
|
|
5
|
+
class GetHistory
|
|
6
|
+
include Binary
|
|
7
|
+
|
|
8
|
+
CONSTRUCTOR = 0x4423e6c5
|
|
9
|
+
|
|
10
|
+
def initialize(peer:, offset_id: 0, offset_date: 0, add_offset: 0, limit: 100, max_id: 0, min_id: 0)
|
|
11
|
+
@peer = peer
|
|
12
|
+
@offset_id = offset_id
|
|
13
|
+
@offset_date = offset_date
|
|
14
|
+
@add_offset = add_offset
|
|
15
|
+
@limit = limit
|
|
16
|
+
@max_id = max_id
|
|
17
|
+
@min_id = min_id
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def body
|
|
21
|
+
result = u32_b(CONSTRUCTOR)
|
|
22
|
+
result += serialize_input_peer
|
|
23
|
+
result += u32_b(@offset_id)
|
|
24
|
+
result += u32_b(@offset_date)
|
|
25
|
+
result += u32_b(@add_offset)
|
|
26
|
+
result += u32_b(@limit)
|
|
27
|
+
result += u32_b(@max_id)
|
|
28
|
+
result += u32_b(@min_id)
|
|
29
|
+
result += u64_b(0) # hash
|
|
30
|
+
result
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def serialize_input_peer
|
|
36
|
+
case @peer[:type]
|
|
37
|
+
when :user
|
|
38
|
+
u32_b(Constructors::INPUT_PEER_USER) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
|
|
39
|
+
when :chat
|
|
40
|
+
u32_b(Constructors::INPUT_PEER_CHAT) + u64_b(@peer[:id])
|
|
41
|
+
when :channel
|
|
42
|
+
u32_b(Constructors::INPUT_PEER_CHANNEL) + u64_b(@peer[:id]) + u64_b(@peer[:access_hash] || 0)
|
|
43
|
+
else
|
|
44
|
+
raise "Unknown peer type: #{@peer[:type]}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -5,15 +5,11 @@ module MTProto
|
|
|
5
5
|
class GetUsers
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0x0d91a548
|
|
9
|
-
VECTOR_CONSTRUCTOR = 0x1cb5c415
|
|
10
|
-
INPUT_USER_SELF = 0xf7c1b13f
|
|
11
|
-
|
|
12
8
|
def body
|
|
13
|
-
u32_b(
|
|
14
|
-
u32_b(
|
|
9
|
+
u32_b(Constructors::USERS_GET_USERS) +
|
|
10
|
+
u32_b(Constructors::VECTOR) +
|
|
15
11
|
u32_b(1) +
|
|
16
|
-
u32_b(INPUT_USER_SELF)
|
|
12
|
+
u32_b(Constructors::INPUT_USER_SELF)
|
|
17
13
|
end
|
|
18
14
|
end
|
|
19
15
|
end
|
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
module MTProto
|
|
4
4
|
module TL
|
|
5
5
|
class HelpConfig
|
|
6
|
-
CONSTRUCTOR = 0xcc1a241e
|
|
7
|
-
CONSTRUCTOR_ALT = 0x3072cfa1
|
|
8
|
-
|
|
9
6
|
attr_reader :flags, :date, :expires, :test_mode, :this_dc, :dc_options
|
|
10
7
|
|
|
11
8
|
def initialize(flags:, date:, expires:, test_mode:, this_dc:, dc_options:)
|
|
@@ -19,7 +16,9 @@ module MTProto
|
|
|
19
16
|
|
|
20
17
|
def self.parse(data)
|
|
21
18
|
constructor = data[0, 4].unpack1('L<')
|
|
22
|
-
|
|
19
|
+
unless [Constructors::CONFIG, Constructors::GZIP_PACKED].include?(constructor)
|
|
20
|
+
raise UnexpectedConstructorError, constructor
|
|
21
|
+
end
|
|
23
22
|
|
|
24
23
|
offset = 4
|
|
25
24
|
flags = data[offset, 4].unpack1('L<')
|
|
@@ -28,7 +27,7 @@ module MTProto
|
|
|
28
27
|
offset += 4
|
|
29
28
|
expires = data[offset, 4].unpack1('L<')
|
|
30
29
|
offset += 4
|
|
31
|
-
test_mode = data[offset, 4].unpack1('L<') ==
|
|
30
|
+
test_mode = data[offset, 4].unpack1('L<') == Constructors::BOOL_TRUE
|
|
32
31
|
offset += 4
|
|
33
32
|
this_dc = data[offset, 4].unpack1('L<')
|
|
34
33
|
offset += 4
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class ImportLoginToken
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0x95ac5ce4
|
|
9
|
-
|
|
10
8
|
attr_reader :token
|
|
11
9
|
|
|
12
10
|
def initialize(token:)
|
|
@@ -14,7 +12,7 @@ module MTProto
|
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
def body
|
|
17
|
-
u32_b(
|
|
15
|
+
u32_b(Constructors::AUTH_IMPORT_LOGIN_TOKEN) + serialize_tl_bytes(@token)
|
|
18
16
|
end
|
|
19
17
|
|
|
20
18
|
private
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class InitConnection
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xc1cd5ea9
|
|
9
|
-
|
|
10
8
|
attr_reader :api_id, :device_model, :system_version, :app_version,
|
|
11
9
|
:system_lang_code, :lang_pack, :lang_code, :query
|
|
12
10
|
|
|
@@ -25,7 +23,7 @@ module MTProto
|
|
|
25
23
|
def body
|
|
26
24
|
flags = 0
|
|
27
25
|
|
|
28
|
-
result = u32_b(
|
|
26
|
+
result = u32_b(Constructors::INIT_CONNECTION)
|
|
29
27
|
result += u32_b(flags)
|
|
30
28
|
result += u32_b(@api_id)
|
|
31
29
|
result += serialize_tl_string(@device_model)
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class InvokeWithLayer
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xda9b0d0d
|
|
9
|
-
|
|
10
8
|
attr_reader :layer, :query
|
|
11
9
|
|
|
12
10
|
def initialize(layer:, query:)
|
|
@@ -15,7 +13,7 @@ module MTProto
|
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
def body
|
|
18
|
-
u32_b(
|
|
16
|
+
u32_b(Constructors::INVOKE_WITH_LAYER) + u32_b(@layer) + @query.body
|
|
19
17
|
end
|
|
20
18
|
end
|
|
21
19
|
end
|
|
@@ -5,10 +5,6 @@ require_relative 'authorization'
|
|
|
5
5
|
module MTProto
|
|
6
6
|
module TL
|
|
7
7
|
class LoginToken
|
|
8
|
-
CONSTRUCTOR_TOKEN = 0x629f1980
|
|
9
|
-
CONSTRUCTOR_MIGRATE_TO = 0x068e9916
|
|
10
|
-
CONSTRUCTOR_SUCCESS = 0x390d5c5e
|
|
11
|
-
|
|
12
8
|
attr_reader :type, :expires, :token, :dc_id, :authorization
|
|
13
9
|
|
|
14
10
|
def initialize(type:, expires: nil, token: nil, dc_id: nil, authorization: nil)
|
|
@@ -35,11 +31,11 @@ module MTProto
|
|
|
35
31
|
constructor = data[0, 4].unpack1('L<')
|
|
36
32
|
|
|
37
33
|
case constructor
|
|
38
|
-
when
|
|
34
|
+
when Constructors::AUTH_LOGIN_TOKEN
|
|
39
35
|
parse_token(data)
|
|
40
|
-
when
|
|
36
|
+
when Constructors::AUTH_LOGIN_TOKEN_MIGRATE_TO
|
|
41
37
|
parse_migrate_to(data)
|
|
42
|
-
when
|
|
38
|
+
when Constructors::AUTH_LOGIN_TOKEN_SUCCESS
|
|
43
39
|
new(type: :success, authorization: Authorization.parse(data[4..]))
|
|
44
40
|
else
|
|
45
41
|
raise UnexpectedConstructorError, constructor
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../schema'
|
|
4
|
+
|
|
5
|
+
module MTProto
|
|
6
|
+
module TL
|
|
7
|
+
class Messages
|
|
8
|
+
Message = Struct.new(:id, :from_id, :date, :text, keyword_init: true)
|
|
9
|
+
|
|
10
|
+
MESSAGES_MESSAGES = 0x8c718e87
|
|
11
|
+
MESSAGES_SLICE = 0x762b263d
|
|
12
|
+
MESSAGES_CHANNEL = 0xc776ba4e
|
|
13
|
+
|
|
14
|
+
MESSAGE = Constructors::MESSAGE
|
|
15
|
+
MESSAGE_SERVICE = 0x7a800e0a
|
|
16
|
+
MESSAGE_EMPTY = 0x90a6ca84
|
|
17
|
+
|
|
18
|
+
VALID_CONSTRUCTORS = [MESSAGES_MESSAGES, MESSAGES_SLICE, MESSAGES_CHANNEL].freeze
|
|
19
|
+
|
|
20
|
+
attr_reader :messages, :count
|
|
21
|
+
|
|
22
|
+
def initialize(messages:, count: nil)
|
|
23
|
+
@messages = messages
|
|
24
|
+
@count = count
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def slice?
|
|
28
|
+
!@count.nil?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.schema
|
|
32
|
+
@schema ||= Schema.new(
|
|
33
|
+
File.expand_path('../../../../data/tl-schema.json', __dir__)
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.parse(data)
|
|
38
|
+
constructor = data[0, 4].unpack1('L<')
|
|
39
|
+
raise UnexpectedConstructorError, constructor unless VALID_CONSTRUCTORS.include?(constructor)
|
|
40
|
+
|
|
41
|
+
offset = 4
|
|
42
|
+
count = nil
|
|
43
|
+
|
|
44
|
+
case constructor
|
|
45
|
+
when MESSAGES_MESSAGES
|
|
46
|
+
# messages:Vector<Message> chats:Vector<Chat> users:Vector<User>
|
|
47
|
+
when MESSAGES_SLICE
|
|
48
|
+
# flags:# count:int next_rate:flags.0?int offset_id_offset:flags.2?int
|
|
49
|
+
# search_flood:flags.3?SearchPostsFlood messages:Vector<Message> ...
|
|
50
|
+
flags = data[offset, 4].unpack1('L<')
|
|
51
|
+
offset += 4
|
|
52
|
+
count = data[offset, 4].unpack1('L<')
|
|
53
|
+
offset += 4
|
|
54
|
+
offset += 4 if flags.anybits?(1 << 0) # next_rate
|
|
55
|
+
offset += 4 if flags.anybits?(1 << 2) # offset_id_offset
|
|
56
|
+
offset = schema.skip(data, offset) if flags.anybits?(1 << 3) # search_flood
|
|
57
|
+
when MESSAGES_CHANNEL
|
|
58
|
+
# flags:# pts:int count:int offset_id_offset:flags.2?int
|
|
59
|
+
# messages:Vector<Message> topics:Vector<ForumTopic> ...
|
|
60
|
+
flags = data[offset, 4].unpack1('L<')
|
|
61
|
+
offset += 4
|
|
62
|
+
offset += 4 # pts
|
|
63
|
+
count = data[offset, 4].unpack1('L<')
|
|
64
|
+
offset += 4
|
|
65
|
+
offset += 4 if flags.anybits?(1 << 2) # offset_id_offset
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
messages, offset = parse_messages_vector(data, offset)
|
|
69
|
+
|
|
70
|
+
# skip topics vector for channelMessages
|
|
71
|
+
schema.skip_vector(data, offset) { |d, o| schema.skip(d, o) } if constructor == MESSAGES_CHANNEL
|
|
72
|
+
|
|
73
|
+
# skip chats and users (we don't need them here)
|
|
74
|
+
|
|
75
|
+
new(messages: messages, count: count)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class << self
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def parse_messages_vector(data, offset)
|
|
82
|
+
offset += 4 # vector constructor
|
|
83
|
+
count = data[offset, 4].unpack1('L<')
|
|
84
|
+
offset += 4
|
|
85
|
+
|
|
86
|
+
messages = []
|
|
87
|
+
count.times do
|
|
88
|
+
constructor = data[offset, 4].unpack1('L<')
|
|
89
|
+
|
|
90
|
+
if constructor == MESSAGE
|
|
91
|
+
msg, = parse_message(data, offset)
|
|
92
|
+
messages << msg if msg
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
offset = schema.skip(data, offset)
|
|
96
|
+
end
|
|
97
|
+
[messages, offset]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# message#9815cec8 flags:# flags2:# id:int
|
|
101
|
+
# from_id:flags.8?Peer ... date:int message:string ...
|
|
102
|
+
def parse_message(data, offset)
|
|
103
|
+
offset += 4 # constructor
|
|
104
|
+
flags = data[offset, 4].unpack1('L<')
|
|
105
|
+
offset += 4
|
|
106
|
+
flags2 = data[offset, 4].unpack1('L<')
|
|
107
|
+
offset += 4
|
|
108
|
+
id = data[offset, 4].unpack1('l<')
|
|
109
|
+
offset += 4
|
|
110
|
+
|
|
111
|
+
from_id = nil
|
|
112
|
+
_, from_id, offset = parse_peer(data, offset) if flags.anybits?(1 << 8)
|
|
113
|
+
offset += 4 if flags.anybits?(1 << 29) # from_boosts_applied
|
|
114
|
+
_, _, offset = parse_peer(data, offset) # peer_id (skip)
|
|
115
|
+
_, _, offset = parse_peer(data, offset) if flags.anybits?(1 << 28) # saved_peer_id
|
|
116
|
+
offset = schema.skip(data, offset) if flags.anybits?(1 << 2) # fwd_from
|
|
117
|
+
offset += 8 if flags.anybits?(1 << 11) # via_bot_id
|
|
118
|
+
offset += 8 if flags2.anybits?(1 << 0) # via_business_bot_id
|
|
119
|
+
offset = schema.skip(data, offset) if flags.anybits?(1 << 3) # reply_to
|
|
120
|
+
|
|
121
|
+
date = data[offset, 4].unpack1('L<')
|
|
122
|
+
offset += 4
|
|
123
|
+
|
|
124
|
+
text, offset = read_tl_string(data, offset)
|
|
125
|
+
|
|
126
|
+
msg = Message.new(id: id, from_id: from_id, date: date, text: text)
|
|
127
|
+
[msg, offset]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def parse_peer(data, offset)
|
|
131
|
+
constructor = data[offset, 4].unpack1('L<')
|
|
132
|
+
offset += 4
|
|
133
|
+
case constructor
|
|
134
|
+
when Constructors::PEER_USER
|
|
135
|
+
[:user, data[offset, 8].unpack1('Q<'), offset + 8]
|
|
136
|
+
when Constructors::PEER_CHAT
|
|
137
|
+
[:chat, data[offset, 8].unpack1('Q<'), offset + 8]
|
|
138
|
+
when Constructors::PEER_CHANNEL
|
|
139
|
+
[:channel, data[offset, 8].unpack1('Q<'), offset + 8]
|
|
140
|
+
else
|
|
141
|
+
raise "Unknown peer constructor: 0x#{constructor.to_s(16)}"
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def read_tl_string(data, offset)
|
|
146
|
+
first_byte = data.getbyte(offset)
|
|
147
|
+
if first_byte == 254
|
|
148
|
+
len = data.getbyte(offset + 1) |
|
|
149
|
+
(data.getbyte(offset + 2) << 8) |
|
|
150
|
+
(data.getbyte(offset + 3) << 16)
|
|
151
|
+
total = 4 + len
|
|
152
|
+
else
|
|
153
|
+
len = first_byte
|
|
154
|
+
total = 1 + len
|
|
155
|
+
end
|
|
156
|
+
padding = (4 - (total % 4)) % 4
|
|
157
|
+
[data[offset + (total - len), len].force_encoding('UTF-8'), offset + total + padding]
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -5,9 +5,6 @@ module MTProto
|
|
|
5
5
|
class PQInnerData
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR_DC = 0xa9f55f95
|
|
9
|
-
CONSTRUCTOR_TEMP_DC = 0x56fddf88
|
|
10
|
-
|
|
11
8
|
attr_reader :pq, :p, :q, :nonce, :server_nonce, :new_nonce, :dc, :expires_in
|
|
12
9
|
|
|
13
10
|
def initialize(pq:, p:, q:, nonce:, server_nonce:, new_nonce:, dc:, expires_in: nil)
|
|
@@ -22,7 +19,7 @@ module MTProto
|
|
|
22
19
|
end
|
|
23
20
|
|
|
24
21
|
def body
|
|
25
|
-
constructor = @expires_in ?
|
|
22
|
+
constructor = @expires_in ? Constructors::PQ_INNER_DATA_TEMP_DC : Constructors::PQ_INNER_DATA_DC
|
|
26
23
|
|
|
27
24
|
result = u32_b(constructor)
|
|
28
25
|
result += serialize_tl_bytes(integer_to_bytes(@pq))
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class ReqDHParams
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xd712e4be
|
|
9
|
-
|
|
10
8
|
attr_reader :nonce, :server_nonce, :p, :q, :public_key_fingerprint, :encrypted_data
|
|
11
9
|
|
|
12
10
|
def initialize(nonce:, server_nonce:, p:, q:, public_key_fingerprint:, encrypted_data:)
|
|
@@ -22,7 +20,7 @@ module MTProto
|
|
|
22
20
|
end
|
|
23
21
|
|
|
24
22
|
def body
|
|
25
|
-
result = u32_b(
|
|
23
|
+
result = u32_b(Constructors::REQ_DH_PARAMS)
|
|
26
24
|
result += @nonce.bytes
|
|
27
25
|
result += @server_nonce.bytes
|
|
28
26
|
result += serialize_tl_bytes(integer_to_bytes(@p))
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class ReqPqMulti
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xbe7e8ef1
|
|
9
|
-
|
|
10
8
|
attr_reader :nonce
|
|
11
9
|
|
|
12
10
|
def initialize(nonce)
|
|
@@ -16,7 +14,7 @@ module MTProto
|
|
|
16
14
|
end
|
|
17
15
|
|
|
18
16
|
def body
|
|
19
|
-
u32_b(
|
|
17
|
+
u32_b(Constructors::REQ_PQ_MULTI) + @nonce.bytes
|
|
20
18
|
end
|
|
21
19
|
end
|
|
22
20
|
end
|
|
@@ -5,14 +5,12 @@ module MTProto
|
|
|
5
5
|
class ResPq
|
|
6
6
|
extend Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0x05162463
|
|
9
|
-
|
|
10
8
|
attr_reader :nonce, :server_nonce, :pq, :fingerprints
|
|
11
9
|
|
|
12
10
|
def self.parse(message)
|
|
13
11
|
data = message.body
|
|
14
12
|
constructor = b_u32(data[0, 4])
|
|
15
|
-
raise "Unexpected constructor: 0x#{constructor.to_s(16)}" unless constructor ==
|
|
13
|
+
raise "Unexpected constructor: 0x#{constructor.to_s(16)}" unless constructor == Constructors::RES_PQ
|
|
16
14
|
|
|
17
15
|
offset = 4
|
|
18
16
|
|
|
@@ -38,7 +36,7 @@ module MTProto
|
|
|
38
36
|
|
|
39
37
|
vector_constructor = b_u32(data[offset, 4])
|
|
40
38
|
offset += 4
|
|
41
|
-
raise 'Expected vector constructor' unless vector_constructor ==
|
|
39
|
+
raise 'Expected vector constructor' unless vector_constructor == Constructors::VECTOR
|
|
42
40
|
|
|
43
41
|
fingerprints_count = b_u32(data[offset, 4])
|
|
44
42
|
offset += 4
|
|
@@ -5,9 +5,6 @@ module MTProto
|
|
|
5
5
|
class SendCode
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xa677244f
|
|
9
|
-
CODE_SETTINGS = 0xad253d78
|
|
10
|
-
|
|
11
8
|
attr_reader :phone_number, :api_id, :api_hash
|
|
12
9
|
|
|
13
10
|
def initialize(phone_number:, api_id:, api_hash:)
|
|
@@ -17,7 +14,7 @@ module MTProto
|
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
def body
|
|
20
|
-
u32_b(
|
|
17
|
+
u32_b(Constructors::AUTH_SEND_CODE) +
|
|
21
18
|
serialize_tl_string(@phone_number) +
|
|
22
19
|
u32_b(@api_id) +
|
|
23
20
|
serialize_tl_string(@api_hash) +
|
|
@@ -27,7 +24,7 @@ module MTProto
|
|
|
27
24
|
private
|
|
28
25
|
|
|
29
26
|
def code_settings
|
|
30
|
-
u32_b(CODE_SETTINGS) + u32_b(0)
|
|
27
|
+
u32_b(Constructors::CODE_SETTINGS) + u32_b(0)
|
|
31
28
|
end
|
|
32
29
|
|
|
33
30
|
def serialize_tl_string(str)
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
module MTProto
|
|
4
4
|
module TL
|
|
5
5
|
class SentCode
|
|
6
|
-
CONSTRUCTOR = 0x5e002502
|
|
7
|
-
|
|
8
6
|
attr_reader :flags, :type, :phone_code_hash, :next_type, :timeout
|
|
9
7
|
|
|
10
8
|
def initialize(flags:, type:, phone_code_hash:, next_type: nil, timeout: nil)
|
|
@@ -17,7 +15,7 @@ module MTProto
|
|
|
17
15
|
|
|
18
16
|
def self.parse(data)
|
|
19
17
|
constructor = data[0, 4].unpack1('L<')
|
|
20
|
-
raise UnexpectedConstructorError, constructor unless constructor ==
|
|
18
|
+
raise UnexpectedConstructorError, constructor unless constructor == Constructors::AUTH_SENT_CODE
|
|
21
19
|
|
|
22
20
|
offset = 4
|
|
23
21
|
flags = data[offset, 4].unpack1('L<')
|
|
@@ -44,7 +42,9 @@ module MTProto
|
|
|
44
42
|
offset += 4
|
|
45
43
|
|
|
46
44
|
case constructor
|
|
47
|
-
when
|
|
45
|
+
when Constructors::AUTH_SENT_CODE_TYPE_APP,
|
|
46
|
+
Constructors::AUTH_SENT_CODE_TYPE_SMS,
|
|
47
|
+
Constructors::AUTH_SENT_CODE_TYPE_CALL
|
|
48
48
|
length = data[offset, 4].unpack1('L<')
|
|
49
49
|
offset += 4
|
|
50
50
|
[{ length: length }, offset]
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
module MTProto
|
|
4
4
|
module TL
|
|
5
5
|
class ServerDHInnerData
|
|
6
|
-
CONSTRUCTOR = 0xb5890dba
|
|
7
|
-
|
|
8
6
|
attr_reader :nonce, :server_nonce, :g, :dh_prime, :g_a, :server_time
|
|
9
7
|
|
|
10
8
|
def self.parse(bytes)
|
|
11
9
|
constructor = bytes[0, 4].unpack1('L<')
|
|
12
|
-
|
|
10
|
+
unless constructor == Constructors::SERVER_DH_INNER_DATA
|
|
11
|
+
raise "Unexpected constructor: 0x#{constructor.to_s(16)}"
|
|
12
|
+
end
|
|
13
13
|
|
|
14
14
|
offset = 4
|
|
15
15
|
|
|
@@ -5,14 +5,14 @@ module MTProto
|
|
|
5
5
|
class ServerDHParams
|
|
6
6
|
extend Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xd0e8075c
|
|
9
|
-
|
|
10
8
|
attr_reader :nonce, :server_nonce, :encrypted_answer
|
|
11
9
|
|
|
12
10
|
def self.parse(message)
|
|
13
11
|
data = message.body
|
|
14
12
|
constructor = b_u32(data[0, 4])
|
|
15
|
-
|
|
13
|
+
unless constructor == Constructors::SERVER_DH_PARAMS_OK
|
|
14
|
+
raise "Unexpected constructor: 0x#{constructor.to_s(16)}"
|
|
15
|
+
end
|
|
16
16
|
|
|
17
17
|
offset = 4
|
|
18
18
|
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class SetClientDHParams
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0xf5045f1f
|
|
9
|
-
|
|
10
8
|
attr_reader :nonce, :server_nonce, :encrypted_data
|
|
11
9
|
|
|
12
10
|
def initialize(nonce:, server_nonce:, encrypted_data:)
|
|
@@ -19,7 +17,7 @@ module MTProto
|
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def body
|
|
22
|
-
result = u32_b(
|
|
20
|
+
result = u32_b(Constructors::SET_CLIENT_DH_PARAMS)
|
|
23
21
|
result += @nonce.bytes
|
|
24
22
|
result += @server_nonce.bytes
|
|
25
23
|
result += serialize_tl_bytes(@encrypted_data.bytes)
|
|
@@ -5,8 +5,6 @@ module MTProto
|
|
|
5
5
|
class SignIn
|
|
6
6
|
include Binary
|
|
7
7
|
|
|
8
|
-
CONSTRUCTOR = 0x8d52a951
|
|
9
|
-
|
|
10
8
|
attr_reader :phone_number, :phone_code_hash, :phone_code
|
|
11
9
|
|
|
12
10
|
def initialize(phone_number:, phone_code_hash:, phone_code:)
|
|
@@ -18,7 +16,7 @@ module MTProto
|
|
|
18
16
|
def body
|
|
19
17
|
flags = 1 << 0
|
|
20
18
|
|
|
21
|
-
u32_b(
|
|
19
|
+
u32_b(Constructors::AUTH_SIGN_IN) +
|
|
22
20
|
u32_b(flags) +
|
|
23
21
|
serialize_tl_string(@phone_number) +
|
|
24
22
|
serialize_tl_string(@phone_code_hash) +
|
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
module MTProto
|
|
4
4
|
module TL
|
|
5
5
|
class Update
|
|
6
|
-
CONSTRUCTOR_NEW_MESSAGE = 0x1f2b0afd
|
|
7
|
-
MESSAGE_CONSTRUCTOR = 0x9815cec8
|
|
8
|
-
|
|
9
6
|
attr_reader :type, :text
|
|
10
7
|
|
|
11
8
|
def initialize(type, text: nil)
|
|
@@ -18,7 +15,7 @@ module MTProto
|
|
|
18
15
|
type = type_name(constructor_id)
|
|
19
16
|
|
|
20
17
|
case constructor_id
|
|
21
|
-
when
|
|
18
|
+
when Constructors::UPDATE_NEW_MESSAGE
|
|
22
19
|
text = extract_new_message_text(bytes)
|
|
23
20
|
new(type, text: text)
|
|
24
21
|
else
|
|
@@ -30,7 +27,7 @@ module MTProto
|
|
|
30
27
|
private
|
|
31
28
|
|
|
32
29
|
def type_name(constructor_id)
|
|
33
|
-
name =
|
|
30
|
+
name = ConstructorNames::NAMES.fetch(constructor_id)
|
|
34
31
|
name.sub(/^update/, '')
|
|
35
32
|
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
36
33
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
@@ -41,7 +38,7 @@ module MTProto
|
|
|
41
38
|
offset = 4 # skip updateNewMessage constructor
|
|
42
39
|
|
|
43
40
|
msg_constructor = bytes[offset, 4].unpack1('L<')
|
|
44
|
-
return nil unless msg_constructor ==
|
|
41
|
+
return nil unless msg_constructor == Constructors::MESSAGE
|
|
45
42
|
|
|
46
43
|
offset += 4
|
|
47
44
|
flags = bytes[offset, 4].unpack1('L<')
|