mtproto 0.0.8 → 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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/data/tl-schema.json +42686 -0
  3. data/ext/aes_ige/extconf.rb +3 -9
  4. data/ext/factorization/extconf.rb +2 -0
  5. data/lib/mtproto/auth_key_generator.rb +68 -105
  6. data/lib/mtproto/binary.rb +21 -0
  7. data/lib/mtproto/client/api/check_password.rb +41 -0
  8. data/lib/mtproto/client/api/export_login_token.rb +27 -0
  9. data/lib/mtproto/client/api/get_dialogs.rb +21 -0
  10. data/lib/mtproto/client/api/get_history.rb +20 -0
  11. data/lib/mtproto/client/api/get_updates_difference.rb +21 -0
  12. data/lib/mtproto/client/api/get_updates_state.rb +14 -0
  13. data/lib/mtproto/client/api/get_users.rb +14 -0
  14. data/lib/mtproto/client/api/import_login_token.rb +23 -0
  15. data/lib/mtproto/client/api/send_code.rb +21 -0
  16. data/lib/mtproto/client/api/sign_in.rb +27 -0
  17. data/lib/mtproto/client/api.rb +36 -0
  18. data/lib/mtproto/client/rpc/response.rb +63 -0
  19. data/lib/mtproto/client/rpc.rb +60 -127
  20. data/lib/mtproto/client.rb +143 -32
  21. data/lib/mtproto/crypto/dh_key_exchange.rb +1 -2
  22. data/lib/mtproto/crypto/dh_validator.rb +17 -19
  23. data/lib/mtproto/crypto/factorization.rb +1 -1
  24. data/lib/mtproto/crypto/rsa_key.rb +2 -2
  25. data/lib/mtproto/crypto/srp.rb +117 -0
  26. data/lib/mtproto/delegate_methods.rb +11 -0
  27. data/lib/mtproto/errors.rb +8 -0
  28. data/lib/mtproto/message/message.rb +85 -0
  29. data/lib/mtproto/session.rb +1 -1
  30. data/lib/mtproto/tl/constructor_names.rb +2271 -0
  31. data/lib/mtproto/tl/constructors.rb +99 -0
  32. data/lib/mtproto/tl/object.rb +25 -0
  33. data/lib/mtproto/tl/objects/account_password.rb +69 -0
  34. data/lib/mtproto/tl/objects/authorization.rb +70 -0
  35. data/lib/mtproto/tl/objects/check_password.rb +43 -0
  36. data/lib/mtproto/tl/objects/client_dh_inner_data.rb +45 -0
  37. data/lib/mtproto/tl/objects/dh_gen_response.rb +46 -0
  38. data/lib/mtproto/tl/objects/dialogs.rb +453 -0
  39. data/lib/mtproto/tl/objects/export_login_token.rb +48 -0
  40. data/lib/mtproto/tl/objects/get_config.rb +13 -0
  41. data/lib/mtproto/tl/objects/get_dialogs.rb +51 -0
  42. data/lib/mtproto/tl/objects/get_difference.rb +34 -0
  43. data/lib/mtproto/tl/objects/get_history.rb +49 -0
  44. data/lib/mtproto/tl/objects/get_password.rb +13 -0
  45. data/lib/mtproto/tl/objects/get_state.rb +13 -0
  46. data/lib/mtproto/tl/objects/get_users.rb +16 -0
  47. data/lib/mtproto/{type → tl/objects}/gzip_packed.rb +6 -6
  48. data/lib/mtproto/tl/objects/help_config.rb +76 -0
  49. data/lib/mtproto/tl/objects/import_login_token.rb +37 -0
  50. data/lib/mtproto/tl/objects/init_connection.rb +57 -0
  51. data/lib/mtproto/tl/objects/invoke_with_layer.rb +20 -0
  52. data/lib/mtproto/tl/objects/login_token.rb +78 -0
  53. data/lib/mtproto/{type → tl/objects}/message.rb +3 -3
  54. data/lib/mtproto/tl/objects/messages.rb +162 -0
  55. data/lib/mtproto/{type → tl/objects}/msg_container.rb +1 -3
  56. data/lib/mtproto/{type → tl/objects}/new_session_created.rb +1 -3
  57. data/lib/mtproto/tl/objects/pq_inner_data.rb +66 -0
  58. data/lib/mtproto/tl/objects/req_dh_params.rb +63 -0
  59. data/lib/mtproto/tl/objects/req_pq_multi.rb +21 -0
  60. data/lib/mtproto/tl/objects/res_pq.rb +73 -0
  61. data/lib/mtproto/{type → tl/objects}/rpc_error.rb +1 -4
  62. data/lib/mtproto/tl/objects/send_code.rb +47 -0
  63. data/lib/mtproto/tl/objects/sent_code.rb +79 -0
  64. data/lib/mtproto/tl/objects/server_dh_inner_data.rb +74 -0
  65. data/lib/mtproto/tl/objects/server_dh_params.rb +53 -0
  66. data/lib/mtproto/tl/objects/set_client_dh_params.rb +46 -0
  67. data/lib/mtproto/tl/objects/sign_in.rb +45 -0
  68. data/lib/mtproto/tl/objects/update.rb +77 -0
  69. data/lib/mtproto/tl/objects/update_short.rb +20 -0
  70. data/lib/mtproto/tl/objects/update_short_message.rb +65 -0
  71. data/lib/mtproto/tl/objects/updates_difference.rb +152 -0
  72. data/lib/mtproto/tl/objects/updates_state.rb +35 -0
  73. data/lib/mtproto/tl/objects/users.rb +83 -0
  74. data/lib/mtproto/tl/schema.rb +102 -0
  75. data/lib/mtproto/transport/abridged_packet_codec.rb +35 -12
  76. data/lib/mtproto/transport/connection.rb +23 -0
  77. data/lib/mtproto/transport/errors.rb +11 -0
  78. data/lib/mtproto/transport/packet.rb +19 -0
  79. data/lib/mtproto/transport/tcp_connection.rb +57 -46
  80. data/lib/mtproto/updates_poller.rb +37 -33
  81. data/lib/mtproto/version.rb +1 -1
  82. data/lib/mtproto.rb +17 -27
  83. data/scripts/generate_constructors.rb +65 -0
  84. metadata +76 -61
  85. data/lib/mtproto/async/middleware/base.rb +0 -17
  86. data/lib/mtproto/async/middleware/flood_wait.rb +0 -42
  87. data/lib/mtproto/async/request.rb +0 -18
  88. data/lib/mtproto/async/request_queue.rb +0 -63
  89. data/lib/mtproto/async_client.rb +0 -201
  90. data/lib/mtproto/rpc/get_config.rb +0 -34
  91. data/lib/mtproto/rpc/get_contacts.rb +0 -29
  92. data/lib/mtproto/rpc/get_updates_difference.rb +0 -51
  93. data/lib/mtproto/rpc/get_updates_state.rb +0 -29
  94. data/lib/mtproto/rpc/get_users.rb +0 -29
  95. data/lib/mtproto/rpc/ping.rb +0 -33
  96. data/lib/mtproto/rpc/send_code.rb +0 -41
  97. data/lib/mtproto/rpc/send_message.rb +0 -47
  98. data/lib/mtproto/rpc/sign_in.rb +0 -48
  99. data/lib/mtproto/type/auth_key/dh_gen_response.rb +0 -37
  100. data/lib/mtproto/type/auth_key/req_dh_params.rb +0 -31
  101. data/lib/mtproto/type/auth_key/req_pq_multi.rb +0 -18
  102. data/lib/mtproto/type/auth_key/res_pq.rb +0 -62
  103. data/lib/mtproto/type/auth_key/server_dh_params.rb +0 -43
  104. data/lib/mtproto/type/auth_key/set_client_dh_params.rb +0 -25
  105. data/lib/mtproto/type/bad_msg_notification.rb +0 -46
  106. data/lib/mtproto/type/client_dh_inner_data.rb +0 -29
  107. data/lib/mtproto/type/code_settings.rb +0 -25
  108. data/lib/mtproto/type/config.rb +0 -124
  109. data/lib/mtproto/type/pq_inner_data.rb +0 -41
  110. data/lib/mtproto/type/rpc/auth/authorization.rb +0 -107
  111. data/lib/mtproto/type/rpc/auth/send_code.rb +0 -28
  112. data/lib/mtproto/type/rpc/auth/sent_code.rb +0 -36
  113. data/lib/mtproto/type/rpc/auth/sign_in.rb +0 -32
  114. data/lib/mtproto/type/rpc/contacts/contacts.rb +0 -155
  115. data/lib/mtproto/type/rpc/contacts/get_contacts.rb +0 -18
  116. data/lib/mtproto/type/rpc/help/config.rb +0 -35
  117. data/lib/mtproto/type/rpc/help/get_config.rb +0 -17
  118. data/lib/mtproto/type/rpc/init_connection.rb +0 -28
  119. data/lib/mtproto/type/rpc/invoke_with_layer.rb +0 -19
  120. data/lib/mtproto/type/rpc/messages/send_message.rb +0 -43
  121. data/lib/mtproto/type/rpc/messages/updates.rb +0 -87
  122. data/lib/mtproto/type/rpc/ping.rb +0 -18
  123. data/lib/mtproto/type/rpc/pong.rb +0 -46
  124. data/lib/mtproto/type/rpc/updates/difference.rb +0 -332
  125. data/lib/mtproto/type/rpc/updates/get_difference.rb +0 -42
  126. data/lib/mtproto/type/rpc/updates/get_state.rb +0 -17
  127. data/lib/mtproto/type/rpc/updates/state.rb +0 -59
  128. data/lib/mtproto/type/rpc/users/get_users.rb +0 -25
  129. data/lib/mtproto/type/rpc/users/users.rb +0 -99
  130. data/lib/mtproto/type/sent_code.rb +0 -128
  131. data/lib/mtproto/type/serializer.rb +0 -55
  132. data/lib/mtproto/type/server_dh_inner_data.rb +0 -85
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MTProto
4
- module Type
5
- module AuthKey
6
- class ServerDHParams
7
- CONSTRUCTOR = 0xd0e8075c
8
-
9
- def self.parse(body)
10
- constructor = body[0, 4].unpack1('L<')
11
- raise "Unexpected constructor: 0x#{constructor.to_s(16)}" unless constructor == CONSTRUCTOR
12
-
13
- offset = 4
14
-
15
- nonce = body[offset, 16]
16
- offset += 16
17
-
18
- server_nonce = body[offset, 16]
19
- offset += 16
20
-
21
- length_byte = body[offset].ord
22
- offset += 1
23
-
24
- if length_byte == 254
25
- length_bytes = body[offset, 3].bytes
26
- encrypted_answer_length = length_bytes[0] | (length_bytes[1] << 8) | (length_bytes[2] << 16)
27
- offset += 3
28
- else
29
- encrypted_answer_length = length_byte
30
- end
31
-
32
- encrypted_answer = body[offset, encrypted_answer_length]
33
-
34
- {
35
- nonce: nonce,
36
- server_nonce: server_nonce,
37
- encrypted_answer: encrypted_answer
38
- }
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../serializer'
4
-
5
- module MTProto
6
- module Type
7
- module AuthKey
8
- class SetClientDHParams
9
- CONSTRUCTOR = 0xf5045f1f
10
-
11
- def self.build(nonce:, server_nonce:, encrypted_data:)
12
- raise ArgumentError, 'Nonce must be 16 bytes' unless nonce.bytesize == 16
13
- raise ArgumentError, 'Server nonce must be 16 bytes' unless server_nonce.bytesize == 16
14
-
15
- body = Serializer.serialize_int(CONSTRUCTOR)
16
- body += nonce
17
- body += server_nonce
18
- body += Serializer.serialize_bytes(encrypted_data)
19
-
20
- body
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MTProto
4
- module Type
5
- class BadMsgNotification
6
- CONSTRUCTOR = 0xa7eff811
7
-
8
- attr_reader :bad_msg_id, :bad_msg_seqno, :error_code
9
-
10
- def self.deserialize(data)
11
- offset = 4
12
- bad_msg_id = data[offset, 8].unpack1('Q<')
13
- offset += 8
14
-
15
- bad_msg_seqno = data[offset, 4].unpack1('L<')
16
- offset += 4
17
-
18
- error_code = data[offset, 4].unpack1('L<')
19
-
20
- new(bad_msg_id: bad_msg_id, bad_msg_seqno: bad_msg_seqno, error_code: error_code)
21
- end
22
-
23
- def initialize(bad_msg_id:, bad_msg_seqno:, error_code:)
24
- @bad_msg_id = bad_msg_id
25
- @bad_msg_seqno = bad_msg_seqno
26
- @error_code = error_code
27
- end
28
-
29
- def error_message
30
- case @error_code
31
- when 16 then "msg_id too low (client time is wrong)"
32
- when 17 then "msg_id too high (client time needs sync)"
33
- when 18 then "incorrect two lower order msg_id bits (must be divisible by 4)"
34
- when 19 then "container msg_id is the same as previously received"
35
- when 20 then "message too old"
36
- when 32 then "msg_seqno too low"
37
- when 33 then "msg_seqno too high"
38
- when 34 then "even msg_seqno expected but odd received"
39
- when 35 then "odd msg_seqno expected but even received"
40
- when 48 then "incorrect server salt"
41
- else "unknown error code #{@error_code}"
42
- end
43
- end
44
- end
45
- end
46
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'serializer'
4
-
5
- module MTProto
6
- module Type
7
- class ClientDHInnerData
8
- CONSTRUCTOR = 0x6643b654
9
-
10
- attr_reader :nonce, :server_nonce, :retry_id, :g_b
11
-
12
- def initialize(nonce:, server_nonce:, retry_id:, g_b:)
13
- @nonce = nonce
14
- @server_nonce = server_nonce
15
- @retry_id = retry_id
16
- @g_b = g_b
17
- end
18
-
19
- def serialize
20
- data = Serializer.serialize_int(CONSTRUCTOR)
21
- data += @nonce
22
- data += @server_nonce
23
- data += Serializer.serialize_long(@retry_id)
24
- data += Serializer.serialize_bytes(@g_b)
25
- data
26
- end
27
- end
28
- end
29
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MTProto
4
- module Type
5
- class CodeSettings
6
- CONSTRUCTOR = 0xad253d78
7
-
8
- def self.serialize(settings = {})
9
- body = Serializer.serialize_int(CONSTRUCTOR)
10
-
11
- flags = 0
12
- flags |= (1 << 0) if settings[:allow_flashcall]
13
- flags |= (1 << 1) if settings[:current_number]
14
- flags |= (1 << 4) if settings[:allow_app_hash]
15
- flags |= (1 << 5) if settings[:allow_missed_call]
16
- flags |= (1 << 7) if settings[:allow_firebase]
17
- flags |= (1 << 9) if settings[:unknown_number]
18
-
19
- body += Serializer.serialize_int(flags)
20
-
21
- body
22
- end
23
- end
24
- end
25
- end
@@ -1,124 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MTProto
4
- module Type
5
- class Config
6
- CONSTRUCTOR = 0xcc1a241e
7
- CONSTRUCTOR_ALT = 0x3072cfa1
8
-
9
- attr_reader :flags, :date, :expires, :test_mode, :this_dc, :dc_options
10
-
11
- def self.deserialize(data)
12
- offset = 4
13
-
14
- flags = data[offset, 4].unpack1('L<')
15
- offset += 4
16
-
17
- date = data[offset, 4].unpack1('L<')
18
- offset += 4
19
-
20
- expires = data[offset, 4].unpack1('L<')
21
- offset += 4
22
-
23
- test_mode = (data[offset, 4].unpack1('L<') == 0x997275b5)
24
- offset += 4
25
-
26
- this_dc = data[offset, 4].unpack1('L<')
27
- offset += 4
28
-
29
- dc_options_constructor = data[offset, 4].unpack1('L<')
30
- offset += 4
31
-
32
- raise "Expected vector constructor 0x1cb5c415, got 0x#{dc_options_constructor.to_s(16)}" unless dc_options_constructor == 0x1cb5c415
33
-
34
- dc_options_count = data[offset, 4].unpack1('L<')
35
- offset += 4
36
-
37
- dc_options = []
38
- dc_options_count.times do
39
- dc_option, bytes_read = DcOption.deserialize_from(data[offset..])
40
- dc_options << dc_option
41
- offset += bytes_read
42
- end
43
-
44
- new(
45
- flags: flags,
46
- date: date,
47
- expires: expires,
48
- test_mode: test_mode,
49
- this_dc: this_dc,
50
- dc_options: dc_options
51
- )
52
- end
53
-
54
- def initialize(flags:, date:, expires:, test_mode:, this_dc:, dc_options:)
55
- @flags = flags
56
- @date = date
57
- @expires = expires
58
- @test_mode = test_mode
59
- @this_dc = this_dc
60
- @dc_options = dc_options
61
- end
62
- end
63
-
64
- class DcOption
65
- attr_reader :id, :ip_address, :port, :flags
66
-
67
- def self.deserialize_from(data)
68
- offset = 0
69
-
70
- constructor = data[offset, 4].unpack1('L<')
71
- offset += 4
72
-
73
- raise "Expected dcOption constructor 0x18b7a10d, got 0x#{constructor.to_s(16)}" unless constructor == 0x18b7a10d
74
-
75
- flags = data[offset, 4].unpack1('L<')
76
- offset += 4
77
-
78
- id = data[offset, 4].unpack1('L<')
79
- offset += 4
80
-
81
- ip_length = data[offset].ord
82
- offset += 1
83
-
84
- ip_address = data[offset, ip_length]
85
- offset += ip_length
86
-
87
- padding = (4 - ((ip_length + 1) % 4)) % 4
88
- offset += padding
89
-
90
- port = data[offset, 4].unpack1('L<')
91
- offset += 4
92
-
93
- [new(id: id, ip_address: ip_address, port: port, flags: flags), offset]
94
- end
95
-
96
- def initialize(id:, ip_address:, port:, flags:)
97
- @id = id
98
- @ip_address = ip_address
99
- @port = port
100
- @flags = flags
101
- end
102
-
103
- def ipv6?
104
- (@flags & 1) != 0
105
- end
106
-
107
- def media_only?
108
- (@flags & 2) != 0
109
- end
110
-
111
- def tcpo_only?
112
- (@flags & 4) != 0
113
- end
114
-
115
- def cdn?
116
- (@flags & 8) != 0
117
- end
118
-
119
- def static?
120
- (@flags & 16) != 0
121
- end
122
- end
123
- end
124
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'serializer'
4
-
5
- module MTProto
6
- module Type
7
- class PQInnerData
8
- CONSTRUCTOR_DC = 0xa9f55f95
9
- CONSTRUCTOR_TEMP_DC = 0x56fddf88
10
-
11
- attr_reader :pq, :p, :q, :nonce, :server_nonce, :new_nonce, :dc, :expires_in
12
-
13
- def initialize(pq:, p:, q:, nonce:, server_nonce:, new_nonce:, dc:, expires_in: nil)
14
- @pq = pq
15
- @p = p
16
- @q = q
17
- @nonce = nonce
18
- @server_nonce = server_nonce
19
- @new_nonce = new_nonce
20
- @dc = dc
21
- @expires_in = expires_in
22
- end
23
-
24
- def serialize
25
- constructor = @expires_in ? CONSTRUCTOR_TEMP_DC : CONSTRUCTOR_DC
26
-
27
- data = Serializer.serialize_int(constructor)
28
- data += Serializer.serialize_bytes(Serializer.integer_to_bytes(@pq))
29
- data += Serializer.serialize_bytes(Serializer.integer_to_bytes(@p))
30
- data += Serializer.serialize_bytes(Serializer.integer_to_bytes(@q))
31
- data += @nonce
32
- data += @server_nonce
33
- data += @new_nonce
34
-
35
- data += Serializer.serialize_int(@expires_in) if @expires_in
36
-
37
- data + Serializer.serialize_int(@dc)
38
- end
39
- end
40
- end
41
- end
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../gzip_packed'
4
- require_relative '../../rpc_error'
5
-
6
- module MTProto
7
- module Type
8
- module RPC
9
- module Auth
10
- class Authorization
11
- CONSTRUCTOR = 0x2ea2c0d4
12
- CONSTRUCTOR_SIGN_UP_REQUIRED = 0x44747e9a
13
-
14
- def self.parse(response)
15
- constructor = response[0, 4].unpack1('L<')
16
-
17
- if constructor == Type::GzipPacked::CONSTRUCTOR
18
- response = Type::GzipPacked.unpack(response)
19
- constructor = response[0, 4].unpack1('L<')
20
- end
21
-
22
- if constructor == Type::RpcError::CONSTRUCTOR
23
- error = Type::RpcError.deserialize(response)
24
- raise MTProto::RpcError.new(error.error_code, error.error_message)
25
- end
26
-
27
- if constructor == CONSTRUCTOR_SIGN_UP_REQUIRED
28
- return { authorization: nil, sign_up_required: true }
29
- end
30
-
31
- if constructor == CONSTRUCTOR
32
- offset = 4
33
-
34
- # Parse flags
35
- flags = response[offset, 4].unpack1('L<')
36
- offset += 4
37
-
38
- # tmp_sessions:flags.0?int
39
- if (flags & (1 << 0)) != 0
40
- offset += 4
41
- end
42
-
43
- # otherwise_relogin_days:flags.1?int
44
- if (flags & (1 << 1)) != 0
45
- offset += 4
46
- end
47
-
48
- # future_auth_token:flags.2?bytes
49
- if (flags & (1 << 2)) != 0
50
- first_byte = response[offset].unpack1('C')
51
-
52
- if first_byte < 254
53
- # Short format: 1 byte length + data + padding
54
- token_len = first_byte
55
- offset += 1 + token_len
56
- padding = (4 - ((1 + token_len) % 4)) % 4
57
- offset += padding
58
- else
59
- # Long format: 0xfe + 3 bytes length + data + padding
60
- offset += 1
61
- token_len = response[offset, 3].unpack('CCC').inject(0) {|sum, b| (sum << 8) + b}
62
- offset += 3 + token_len
63
- padding = (4 - ((4 + token_len) % 4)) % 4
64
- offset += padding
65
- end
66
- end
67
-
68
- # Parse User object
69
- # user#20b1422 flags:# flags2:# id:long access_hash:flags.0?long ...
70
- user_constructor = response[offset, 4].unpack1('L<')
71
- offset += 4
72
-
73
- user_flags = response[offset, 4].unpack1('L<')
74
- offset += 4
75
-
76
- user_flags2 = response[offset, 4].unpack1('L<')
77
- offset += 4
78
-
79
- # id:long (always present)
80
- user_id = response[offset, 8].unpack1('Q<')
81
- offset += 8
82
-
83
- # access_hash:flags.0?long (conditional on flags.0)
84
- access_hash = nil
85
- if (user_flags & (1 << 0)) != 0
86
- access_hash = response[offset, 8].unpack1('Q<')
87
- offset += 8
88
- end
89
-
90
- # We have what we need, skip the rest of User fields
91
-
92
- return {
93
- authorization: true,
94
- flags: flags,
95
- sign_up_required: false,
96
- user_id: user_id,
97
- access_hash: access_hash
98
- }
99
- end
100
-
101
- raise UnexpectedConstructorError.new(constructor)
102
- end
103
- end
104
- end
105
- end
106
- end
107
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../serializer'
4
- require_relative '../../code_settings'
5
-
6
- module MTProto
7
- module Type
8
- module RPC
9
- module Auth
10
- class SendCode
11
- CONSTRUCTOR = 0xa677244f
12
-
13
- def self.build(phone_number:, api_id:, api_hash:, code_settings: {})
14
- raise ArgumentError, 'phone_number is required' if phone_number.nil? || phone_number.empty?
15
-
16
- query = [CONSTRUCTOR].pack('L<')
17
- query += Serializer.serialize_string(phone_number)
18
- query += Serializer.serialize_int(api_id)
19
- query += Serializer.serialize_string(api_hash)
20
- query += CodeSettings.serialize(code_settings)
21
-
22
- query
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../gzip_packed'
4
- require_relative '../../rpc_error'
5
- require_relative '../../sent_code'
6
-
7
- module MTProto
8
- module Type
9
- module RPC
10
- module Auth
11
- class SentCode
12
- def self.parse(response)
13
- constructor = response[0, 4].unpack1('L<')
14
-
15
- if constructor == Type::GzipPacked::CONSTRUCTOR
16
- response = Type::GzipPacked.unpack(response)
17
- constructor = response[0, 4].unpack1('L<')
18
- end
19
-
20
- if constructor == Type::RpcError::CONSTRUCTOR
21
- error = Type::RpcError.deserialize(response)
22
- raise MTProto::RpcError.new(error.error_code, error.error_message)
23
- end
24
-
25
- if constructor == Type::SentCode::CONSTRUCTOR
26
- sent_code = Type::SentCode.deserialize(response)
27
- sent_code.to_h
28
- else
29
- raise UnexpectedConstructorError.new(constructor)
30
- end
31
- end
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../serializer'
4
-
5
- module MTProto
6
- module Type
7
- module RPC
8
- module Auth
9
- class SignIn
10
- CONSTRUCTOR = 0x8d52a951
11
-
12
- def self.build(phone_number:, phone_code_hash:, phone_code:)
13
- raise ArgumentError, 'phone_number is required' if phone_number.nil? || phone_number.empty?
14
- raise ArgumentError, 'phone_code_hash is required' if phone_code_hash.nil? || phone_code_hash.empty?
15
- raise ArgumentError, 'phone_code is required' if phone_code.nil? || phone_code.empty?
16
-
17
- flags = 0
18
- flags |= (1 << 0) # phone_code present
19
-
20
- query = [CONSTRUCTOR].pack('L<')
21
- query += Serializer.serialize_int(flags)
22
- query += Serializer.serialize_string(phone_number)
23
- query += Serializer.serialize_string(phone_code_hash)
24
- query += Serializer.serialize_string(phone_code)
25
-
26
- query
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,155 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../gzip_packed'
4
- require_relative '../../rpc_error'
5
-
6
- module MTProto
7
- module Type
8
- module RPC
9
- module Contacts
10
- class Contacts
11
- CONSTRUCTOR_CONTACTS = 0xeae87e42
12
- CONSTRUCTOR_CONTACTS_NOT_MODIFIED = 0xb74ba9d2
13
- VECTOR_CONSTRUCTOR = 0x1cb5c415
14
-
15
- def self.parse(response)
16
- offset = 0
17
-
18
- constructor = response[offset, 4].unpack1('L<')
19
- offset += 4
20
-
21
- if constructor == Type::GzipPacked::CONSTRUCTOR
22
- response = Type::GzipPacked.unpack(response)
23
- constructor = response[0, 4].unpack1('L<')
24
- offset = 4
25
- end
26
-
27
- if constructor == Type::RpcError::CONSTRUCTOR
28
- error = Type::RpcError.deserialize(response)
29
- raise MTProto::RpcError.new(error.error_code, error.error_message)
30
- end
31
-
32
- case constructor
33
- when CONSTRUCTOR_CONTACTS_NOT_MODIFIED
34
- # contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
35
- {
36
- contacts: [],
37
- users: []
38
- }
39
-
40
- when CONSTRUCTOR_CONTACTS
41
- # contacts.contacts#eae87e42 contacts:Vector<Contact> saved_count:int users:Vector<User> = contacts.Contacts;
42
-
43
- # Parse contacts vector
44
- contacts, offset = parse_contacts_vector(response, offset)
45
-
46
- # Parse saved_count
47
- saved_count = response[offset, 4].unpack1('L<')
48
- offset += 4
49
-
50
- # Parse users vector
51
- users, offset = parse_users_vector(response, offset)
52
-
53
- {
54
- contacts: contacts,
55
- saved_count: saved_count,
56
- users: users
57
- }
58
-
59
- else
60
- raise "Unknown Contacts constructor: 0x#{constructor.to_s(16)}"
61
- end
62
- end
63
-
64
- def self.parse_contacts_vector(response, offset)
65
- vector_constructor = response[offset, 4].unpack1('L<')
66
- offset += 4
67
-
68
- return [[], offset] unless vector_constructor == VECTOR_CONSTRUCTOR
69
-
70
- count = response[offset, 4].unpack1('L<')
71
- offset += 4
72
-
73
- contacts = []
74
- count.times do
75
- contact, offset = parse_contact(response, offset)
76
- contacts << contact if contact
77
- end
78
-
79
- [contacts, offset]
80
- end
81
-
82
- def self.parse_contact(response, offset)
83
- # contact#145ade0b user_id:long mutual:Bool
84
- constructor = response[offset, 4].unpack1('L<')
85
- offset += 4
86
-
87
- return [nil, offset] unless constructor == 0x145ade0b
88
-
89
- user_id = response[offset, 8].unpack1('Q<')
90
- offset += 8
91
-
92
- mutual_constructor = response[offset, 4].unpack1('L<')
93
- offset += 4
94
- mutual = mutual_constructor == 0x997275b5 # boolTrue
95
-
96
- [{
97
- user_id: user_id,
98
- mutual: mutual
99
- }, offset]
100
- rescue StandardError
101
- [nil, offset]
102
- end
103
-
104
- def self.parse_users_vector(response, offset)
105
- vector_constructor = response[offset, 4].unpack1('L<')
106
- offset += 4
107
-
108
- return [[], offset] unless vector_constructor == VECTOR_CONSTRUCTOR
109
-
110
- count = response[offset, 4].unpack1('L<')
111
- offset += 4
112
-
113
- users = []
114
- count.times do
115
- user, offset = parse_user(response, offset)
116
- users << user if user
117
- end
118
-
119
- [users, offset]
120
- end
121
-
122
- def self.parse_user(response, offset)
123
- user_constructor = response[offset, 4].unpack1('L<')
124
- offset += 4
125
-
126
- # user#20b1422 flags:# flags2:# id:long access_hash:flags.0?long ...
127
- return [nil, offset] unless user_constructor == 0x20b1422
128
-
129
- flags = response[offset, 4].unpack1('L<')
130
- offset += 4
131
-
132
- flags2 = response[offset, 4].unpack1('L<')
133
- offset += 4
134
-
135
- user_id = response[offset, 8].unpack1('Q<')
136
- offset += 8
137
-
138
- access_hash = nil
139
- if (flags & (1 << 0)) != 0
140
- access_hash = response[offset, 8].unpack1('Q<')
141
- offset += 8
142
- end
143
-
144
- [{
145
- id: user_id,
146
- access_hash: access_hash
147
- }, offset]
148
- rescue StandardError
149
- [nil, offset]
150
- end
151
- end
152
- end
153
- end
154
- end
155
- end