mtproto 0.0.7 → 0.0.9
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/.env.example +4 -0
- data/ext/aes_ige/extconf.rb +3 -9
- data/ext/factorization/extconf.rb +2 -0
- data/lib/mtproto/auth_key_generator.rb +66 -103
- data/lib/mtproto/binary.rb +21 -0
- data/lib/mtproto/client/api/check_password.rb +41 -0
- data/lib/mtproto/client/api/export_login_token.rb +27 -0
- data/lib/mtproto/client/api/get_updates_difference.rb +21 -0
- data/lib/mtproto/client/api/get_updates_state.rb +14 -0
- data/lib/mtproto/client/api/get_users.rb +14 -0
- data/lib/mtproto/client/api/import_login_token.rb +23 -0
- data/lib/mtproto/client/api/send_code.rb +21 -0
- data/lib/mtproto/client/api/sign_in.rb +27 -0
- data/lib/mtproto/client/api.rb +28 -0
- data/lib/mtproto/client/rpc/response.rb +63 -0
- data/lib/mtproto/client/rpc.rb +67 -107
- data/lib/mtproto/client.rb +176 -31
- data/lib/mtproto/crypto/dh_key_exchange.rb +1 -2
- data/lib/mtproto/crypto/dh_validator.rb +17 -19
- data/lib/mtproto/crypto/factorization.rb +1 -1
- data/lib/mtproto/crypto/rsa_key.rb +2 -2
- data/lib/mtproto/crypto/srp.rb +117 -0
- data/lib/mtproto/delegate_methods.rb +11 -0
- data/lib/mtproto/message/message.rb +85 -0
- data/lib/mtproto/session.rb +1 -1
- data/lib/mtproto/tl/constructors.rb +2269 -0
- data/lib/mtproto/tl/object.rb +25 -0
- data/lib/mtproto/tl/objects/account_password.rb +72 -0
- data/lib/mtproto/tl/objects/authorization.rb +73 -0
- data/lib/mtproto/tl/objects/check_password.rb +46 -0
- data/lib/mtproto/tl/objects/client_dh_inner_data.rb +47 -0
- data/lib/mtproto/tl/objects/dh_gen_response.rb +50 -0
- data/lib/mtproto/tl/objects/export_login_token.rb +51 -0
- data/lib/mtproto/tl/objects/get_config.rb +15 -0
- data/lib/mtproto/tl/objects/get_difference.rb +36 -0
- data/lib/mtproto/tl/objects/get_password.rb +15 -0
- data/lib/mtproto/tl/objects/get_state.rb +15 -0
- data/lib/mtproto/tl/objects/get_users.rb +20 -0
- data/lib/mtproto/tl/objects/help_config.rb +77 -0
- data/lib/mtproto/tl/objects/import_login_token.rb +39 -0
- data/lib/mtproto/tl/objects/init_connection.rb +59 -0
- data/lib/mtproto/tl/objects/invoke_with_layer.rb +22 -0
- data/lib/mtproto/tl/objects/login_token.rb +82 -0
- data/lib/mtproto/tl/objects/pq_inner_data.rb +69 -0
- data/lib/mtproto/tl/objects/req_dh_params.rb +65 -0
- data/lib/mtproto/tl/objects/req_pq_multi.rb +23 -0
- data/lib/mtproto/tl/objects/res_pq.rb +75 -0
- data/lib/mtproto/tl/objects/send_code.rb +50 -0
- data/lib/mtproto/tl/objects/sent_code.rb +79 -0
- data/lib/mtproto/tl/objects/server_dh_inner_data.rb +74 -0
- data/lib/mtproto/tl/objects/server_dh_params.rb +53 -0
- data/lib/mtproto/tl/objects/set_client_dh_params.rb +48 -0
- data/lib/mtproto/tl/objects/sign_in.rb +47 -0
- data/lib/mtproto/tl/objects/update.rb +80 -0
- data/lib/mtproto/tl/objects/update_short.rb +22 -0
- data/lib/mtproto/tl/objects/update_short_message.rb +67 -0
- data/lib/mtproto/tl/objects/updates_difference.rb +157 -0
- data/lib/mtproto/tl/objects/updates_state.rb +37 -0
- data/lib/mtproto/tl/objects/users.rb +86 -0
- data/lib/mtproto/transport/abridged_packet_codec.rb +35 -12
- data/lib/mtproto/transport/connection.rb +23 -0
- data/lib/mtproto/transport/errors.rb +11 -0
- data/lib/mtproto/transport/packet.rb +19 -0
- data/lib/mtproto/transport/tcp_connection.rb +57 -46
- data/lib/mtproto/{tl → type}/bad_msg_notification.rb +11 -11
- data/lib/mtproto/{tl → type}/client_dh_inner_data.rb +1 -1
- data/lib/mtproto/{tl → type}/gzip_packed.rb +6 -4
- data/lib/mtproto/{tl → type}/message.rb +3 -3
- data/lib/mtproto/{tl → type}/msg_container.rb +1 -1
- data/lib/mtproto/{tl → type}/new_session_created.rb +1 -1
- data/lib/mtproto/{tl/p_q_inner_data.rb → type/pq_inner_data.rb} +1 -1
- data/lib/mtproto/{tl → type}/rpc_error.rb +1 -2
- data/lib/mtproto/{tl → type}/serializer.rb +1 -1
- data/lib/mtproto/{tl → type}/server_dh_inner_data.rb +1 -1
- data/lib/mtproto/updates_poller.rb +37 -33
- data/lib/mtproto/version.rb +1 -1
- data/lib/mtproto.rb +21 -22
- data/scripts/generate_constructors.rb +65 -0
- metadata +80 -49
- data/lib/mtproto/rpc/get_config.rb +0 -37
- data/lib/mtproto/rpc/get_contacts.rb +0 -22
- data/lib/mtproto/rpc/get_updates_difference.rb +0 -33
- data/lib/mtproto/rpc/get_updates_state.rb +0 -22
- data/lib/mtproto/rpc/get_users.rb +0 -22
- data/lib/mtproto/rpc/ping.rb +0 -26
- data/lib/mtproto/rpc/send_code.rb +0 -44
- data/lib/mtproto/rpc/send_message.rb +0 -31
- data/lib/mtproto/rpc/sign_in.rb +0 -52
- data/lib/mtproto/tl/auth_key/dh_gen_response.rb +0 -37
- data/lib/mtproto/tl/auth_key/req_dh_params.rb +0 -31
- data/lib/mtproto/tl/auth_key/req_pq_multi.rb +0 -18
- data/lib/mtproto/tl/auth_key/res_pq.rb +0 -62
- data/lib/mtproto/tl/auth_key/server_dh_params.rb +0 -43
- data/lib/mtproto/tl/auth_key/set_client_dh_params.rb +0 -25
- data/lib/mtproto/tl/code_settings.rb +0 -25
- data/lib/mtproto/tl/config.rb +0 -124
- data/lib/mtproto/tl/method_builder.rb +0 -29
- data/lib/mtproto/tl/rpc/auth/authorization.rb +0 -107
- data/lib/mtproto/tl/rpc/auth/send_code.rb +0 -28
- data/lib/mtproto/tl/rpc/auth/sent_code.rb +0 -36
- data/lib/mtproto/tl/rpc/auth/sign_in.rb +0 -32
- data/lib/mtproto/tl/rpc/contacts/contacts.rb +0 -155
- data/lib/mtproto/tl/rpc/contacts/get_contacts.rb +0 -18
- data/lib/mtproto/tl/rpc/help/config.rb +0 -35
- data/lib/mtproto/tl/rpc/help/get_config.rb +0 -17
- data/lib/mtproto/tl/rpc/messages/send_message.rb +0 -43
- data/lib/mtproto/tl/rpc/messages/updates.rb +0 -87
- data/lib/mtproto/tl/rpc/ping.rb +0 -18
- data/lib/mtproto/tl/rpc/pong.rb +0 -46
- data/lib/mtproto/tl/rpc/updates/difference.rb +0 -332
- data/lib/mtproto/tl/rpc/updates/get_difference.rb +0 -42
- data/lib/mtproto/tl/rpc/updates/get_state.rb +0 -17
- data/lib/mtproto/tl/rpc/updates/state.rb +0 -59
- data/lib/mtproto/tl/rpc/users/get_users.rb +0 -25
- data/lib/mtproto/tl/rpc/users/users.rb +0 -99
- data/lib/mtproto/tl/sent_code.rb +0 -128
|
@@ -5,86 +5,97 @@ require 'timeout'
|
|
|
5
5
|
|
|
6
6
|
module MTProto
|
|
7
7
|
module Transport
|
|
8
|
-
class ConnectionError < StandardError; end
|
|
9
|
-
|
|
10
8
|
class TCPConnection
|
|
11
|
-
attr_reader :host, :port
|
|
9
|
+
attr_reader :host, :port
|
|
10
|
+
attr_accessor :wait_timeout, :read_timeout
|
|
12
11
|
|
|
13
|
-
def initialize(host, port,
|
|
12
|
+
def initialize(host, port, codec_class: AbridgedPacketCodec, wait_timeout: 60, read_timeout: 3)
|
|
14
13
|
@host = host
|
|
15
14
|
@port = port
|
|
16
|
-
@
|
|
15
|
+
@codec_class = codec_class
|
|
16
|
+
@wait_timeout = wait_timeout
|
|
17
|
+
@read_timeout = read_timeout
|
|
17
18
|
@socket = nil
|
|
19
|
+
@codec = nil
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def connect!
|
|
21
23
|
return if connected?
|
|
22
24
|
|
|
23
25
|
@socket = TCPSocket.new(@host, @port)
|
|
26
|
+
@codec = @codec_class.new(@socket)
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
write_init_tag
|
|
26
29
|
end
|
|
27
30
|
|
|
28
|
-
def
|
|
29
|
-
|
|
31
|
+
def disconnect!
|
|
32
|
+
return unless @socket
|
|
33
|
+
|
|
34
|
+
@socket.close
|
|
35
|
+
rescue StandardError
|
|
36
|
+
nil
|
|
37
|
+
ensure
|
|
38
|
+
@socket = nil
|
|
39
|
+
@codec = nil
|
|
30
40
|
end
|
|
31
41
|
|
|
32
|
-
def
|
|
33
|
-
|
|
42
|
+
def not_connected?
|
|
43
|
+
@socket.nil? || @socket.closed?
|
|
44
|
+
end
|
|
34
45
|
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
def connected?
|
|
47
|
+
not not_connected?
|
|
37
48
|
end
|
|
38
49
|
|
|
39
|
-
def
|
|
40
|
-
raise
|
|
50
|
+
def send(packet)
|
|
51
|
+
raise NotConnectedError, 'Not connected' unless connected?
|
|
41
52
|
|
|
42
|
-
|
|
43
|
-
read_packet
|
|
44
|
-
end
|
|
45
|
-
rescue Timeout::Error
|
|
46
|
-
raise ConnectionError, 'Receive timeout'
|
|
53
|
+
@codec.send(packet)
|
|
47
54
|
end
|
|
48
55
|
|
|
49
|
-
def
|
|
50
|
-
|
|
56
|
+
def receive(&)
|
|
57
|
+
raise NotConnectedError, 'Not connected' unless connected?
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
if block_given?
|
|
60
|
+
receive_loop(&)
|
|
61
|
+
else
|
|
62
|
+
receive_once
|
|
63
|
+
end
|
|
57
64
|
end
|
|
58
65
|
|
|
59
66
|
private
|
|
60
67
|
|
|
61
|
-
def
|
|
62
|
-
|
|
63
|
-
@socket.write(tag) if tag
|
|
64
|
-
end
|
|
68
|
+
def receive_once
|
|
69
|
+
return nil unless @socket.wait_readable(@wait_timeout)
|
|
65
70
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
length = first_byte.unpack1('C')
|
|
71
|
+
read_packet
|
|
72
|
+
end
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
def receive_loop
|
|
75
|
+
loop do
|
|
76
|
+
@socket.wait_readable
|
|
77
|
+
packet = read_packet
|
|
78
|
+
yield packet, nil
|
|
79
|
+
rescue ConnectionClosedError, NotConnectedError
|
|
80
|
+
raise
|
|
81
|
+
rescue PacketReadError => e
|
|
82
|
+
yield nil, e
|
|
73
83
|
end
|
|
84
|
+
end
|
|
74
85
|
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
def read_packet
|
|
87
|
+
Timeout.timeout(@read_timeout) { @codec.scan }
|
|
88
|
+
rescue Timeout::Error
|
|
89
|
+
raise PacketReadError, 'Packet read timeout'
|
|
90
|
+
rescue IOError, Errno::ECONNRESET => e
|
|
91
|
+
raise ConnectionClosedError, e.message
|
|
77
92
|
end
|
|
78
93
|
|
|
79
|
-
def
|
|
80
|
-
|
|
81
|
-
while result.bytesize < bytes_needed
|
|
82
|
-
chunk = @socket.read(bytes_needed - result.bytesize)
|
|
83
|
-
raise ConnectionError, 'EOF while reading' if chunk.nil? || chunk.empty?
|
|
94
|
+
def write_init_tag
|
|
95
|
+
return unless @codec_class.const_defined?(:TAG)
|
|
84
96
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
result
|
|
97
|
+
tag = @codec_class.const_get(:TAG)
|
|
98
|
+
@socket.write tag if tag
|
|
88
99
|
end
|
|
89
100
|
end
|
|
90
101
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MTProto
|
|
4
|
-
module
|
|
4
|
+
module Type
|
|
5
5
|
class BadMsgNotification
|
|
6
6
|
CONSTRUCTOR = 0xa7eff811
|
|
7
7
|
|
|
@@ -28,16 +28,16 @@ module MTProto
|
|
|
28
28
|
|
|
29
29
|
def error_message
|
|
30
30
|
case @error_code
|
|
31
|
-
when 16 then
|
|
32
|
-
when 17 then
|
|
33
|
-
when 18 then
|
|
34
|
-
when 19 then
|
|
35
|
-
when 20 then
|
|
36
|
-
when 32 then
|
|
37
|
-
when 33 then
|
|
38
|
-
when 34 then
|
|
39
|
-
when 35 then
|
|
40
|
-
when 48 then
|
|
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
41
|
else "unknown error code #{@error_code}"
|
|
42
42
|
end
|
|
43
43
|
end
|
|
@@ -4,7 +4,7 @@ require 'zlib'
|
|
|
4
4
|
require 'stringio'
|
|
5
5
|
|
|
6
6
|
module MTProto
|
|
7
|
-
module
|
|
7
|
+
module Type
|
|
8
8
|
module GzipPacked
|
|
9
9
|
CONSTRUCTOR = 0x3072cfa1
|
|
10
10
|
|
|
@@ -19,11 +19,11 @@ module MTProto
|
|
|
19
19
|
|
|
20
20
|
if length_byte == 254
|
|
21
21
|
length_bytes = data[offset, 3]
|
|
22
|
-
length =
|
|
22
|
+
length = "#{length_bytes}\u0000".unpack1('L<')
|
|
23
23
|
offset += 3
|
|
24
24
|
puts " [GZIP] Extended length: #{length} bytes" if $DEBUG
|
|
25
25
|
elsif length_byte == 255
|
|
26
|
-
raise
|
|
26
|
+
raise 'Invalid TL string length: 255'
|
|
27
27
|
else
|
|
28
28
|
length = length_byte
|
|
29
29
|
puts " [GZIP] Short length: #{length} bytes" if $DEBUG
|
|
@@ -32,7 +32,9 @@ module MTProto
|
|
|
32
32
|
raise "Invalid length: #{length.inspect}" unless length.is_a?(Integer) && length > 0
|
|
33
33
|
|
|
34
34
|
compressed_data = data[offset, length]
|
|
35
|
-
|
|
35
|
+
if compressed_data.nil? || compressed_data.bytesize < length
|
|
36
|
+
raise "Not enough data: expected #{length}, got #{compressed_data&.bytesize}"
|
|
37
|
+
end
|
|
36
38
|
|
|
37
39
|
Zlib::GzipReader.new(StringIO.new(compressed_data)).read.force_encoding(Encoding::BINARY)
|
|
38
40
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MTProto
|
|
4
|
-
module
|
|
4
|
+
module Type
|
|
5
5
|
class Message
|
|
6
6
|
attr_reader :auth_key_id, :msg_id, :body
|
|
7
7
|
|
|
@@ -22,8 +22,8 @@ module MTProto
|
|
|
22
22
|
def self.deserialize(data)
|
|
23
23
|
if data.bytesize < 20
|
|
24
24
|
raise(ArgumentError,
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
'Invalid MTProto message: expected at least 20 bytes, ' \
|
|
26
|
+
"got #{data.bytesize} bytes (hex: #{data.unpack1('H*')})")
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
auth_key_id = data[0, 8].unpack1('Q<')
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module MTProto
|
|
4
|
-
module
|
|
4
|
+
module Type
|
|
5
5
|
class RpcError
|
|
6
6
|
CONSTRUCTOR = 0x2144ca19
|
|
7
7
|
|
|
@@ -16,7 +16,6 @@ module MTProto
|
|
|
16
16
|
offset += 1
|
|
17
17
|
|
|
18
18
|
error_message = data[offset, message_length]
|
|
19
|
-
offset += message_length
|
|
20
19
|
|
|
21
20
|
new(error_code: error_code, error_message: error_message)
|
|
22
21
|
end
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative 'rpc/get_updates_state'
|
|
4
|
-
require_relative 'rpc/get_updates_difference'
|
|
5
|
-
|
|
6
3
|
module MTProto
|
|
7
4
|
class UpdatesPoller
|
|
8
5
|
attr_reader :state, :running
|
|
@@ -14,7 +11,7 @@ module MTProto
|
|
|
14
11
|
@running = false
|
|
15
12
|
@on_message_callbacks = []
|
|
16
13
|
@on_update_callbacks = []
|
|
17
|
-
@users_cache = {}
|
|
14
|
+
@users_cache = {}
|
|
18
15
|
end
|
|
19
16
|
|
|
20
17
|
def on_message(&block)
|
|
@@ -27,11 +24,11 @@ module MTProto
|
|
|
27
24
|
|
|
28
25
|
def start
|
|
29
26
|
raise 'Already running' if @running
|
|
30
|
-
raise 'Auth key not
|
|
27
|
+
raise 'Auth key not set' unless @client.auth_key?
|
|
31
28
|
|
|
32
29
|
@running = true
|
|
33
30
|
|
|
34
|
-
@state =
|
|
31
|
+
@state = call_with_retry { @client.api.get_updates_state }
|
|
35
32
|
|
|
36
33
|
poll_loop
|
|
37
34
|
end
|
|
@@ -45,65 +42,72 @@ module MTProto
|
|
|
45
42
|
def poll_loop
|
|
46
43
|
while @running
|
|
47
44
|
begin
|
|
48
|
-
difference =
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
difference = call_with_retry do
|
|
46
|
+
@client.api.get_updates_difference(
|
|
47
|
+
pts: @state.pts,
|
|
48
|
+
date: @state.date,
|
|
49
|
+
qts: @state.qts
|
|
50
|
+
)
|
|
51
|
+
end
|
|
53
52
|
|
|
54
53
|
process_difference(difference)
|
|
55
54
|
|
|
56
|
-
if difference
|
|
57
|
-
@state =
|
|
58
|
-
elsif difference
|
|
59
|
-
@state =
|
|
60
|
-
elsif difference
|
|
61
|
-
@state
|
|
55
|
+
if difference.state
|
|
56
|
+
@state = difference.state
|
|
57
|
+
elsif difference.type == :too_long
|
|
58
|
+
@state = call_with_retry { @client.api.get_updates_state }
|
|
59
|
+
elsif difference.date
|
|
60
|
+
@state.date = difference.date
|
|
62
61
|
end
|
|
63
62
|
|
|
64
63
|
sleep @poll_interval
|
|
65
64
|
rescue MTProto::RpcError => e
|
|
66
|
-
|
|
65
|
+
warn "RPC Error during polling: #{e.message}"
|
|
67
66
|
sleep @poll_interval
|
|
68
67
|
rescue StandardError => e
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
warn "Error during polling: #{e.class} - #{e.message}"
|
|
69
|
+
warn e.backtrace.first(5).join("\n")
|
|
71
70
|
sleep @poll_interval
|
|
72
71
|
end
|
|
73
72
|
end
|
|
74
73
|
end
|
|
75
74
|
|
|
75
|
+
def call_with_retry(max_retries: 5)
|
|
76
|
+
retries = 0
|
|
77
|
+
begin
|
|
78
|
+
yield
|
|
79
|
+
rescue MTProto::UnexpectedConstructorError, RuntimeError
|
|
80
|
+
retries += 1
|
|
81
|
+
retry if retries < max_retries
|
|
82
|
+
raise
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
76
86
|
def process_difference(difference)
|
|
77
|
-
case difference
|
|
87
|
+
case difference.type
|
|
78
88
|
when :empty
|
|
79
89
|
nil
|
|
80
90
|
when :difference, :slice, :short_message
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if user[:access_hash]
|
|
84
|
-
@users_cache[user[:id]] = user[:access_hash]
|
|
85
|
-
end
|
|
86
|
-
end
|
|
91
|
+
difference.users&.each do |user|
|
|
92
|
+
@users_cache[user[:id]] = user[:access_hash] if user[:access_hash]
|
|
87
93
|
end
|
|
88
94
|
|
|
89
|
-
if difference
|
|
90
|
-
difference
|
|
95
|
+
if difference.new_messages && !difference.new_messages.empty?
|
|
96
|
+
difference.new_messages.each do |message|
|
|
91
97
|
process_message(message)
|
|
92
98
|
end
|
|
93
99
|
end
|
|
94
100
|
|
|
95
101
|
@on_update_callbacks.each { |callback| callback.call(difference) }
|
|
96
102
|
when :too_long
|
|
97
|
-
puts "Update gap too long (pts=#{difference
|
|
103
|
+
puts "Update gap too long (pts=#{difference.pts}), refreshing state..."
|
|
98
104
|
end
|
|
99
105
|
end
|
|
100
106
|
|
|
101
107
|
def process_message(message)
|
|
102
108
|
return unless message
|
|
103
109
|
|
|
104
|
-
if message[:user_id] && @users_cache[message[:user_id]]
|
|
105
|
-
message[:access_hash] = @users_cache[message[:user_id]]
|
|
106
|
-
end
|
|
110
|
+
message[:access_hash] = @users_cache[message[:user_id]] if message[:user_id] && @users_cache[message[:user_id]]
|
|
107
111
|
|
|
108
112
|
@on_message_callbacks.each { |callback| callback.call(message) }
|
|
109
113
|
end
|
data/lib/mtproto/version.rb
CHANGED
data/lib/mtproto.rb
CHANGED
|
@@ -2,21 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative 'mtproto/version'
|
|
4
4
|
require_relative 'mtproto/errors'
|
|
5
|
+
require_relative 'mtproto/binary'
|
|
6
|
+
require_relative 'mtproto/delegate_methods'
|
|
7
|
+
require_relative 'mtproto/transport/errors'
|
|
8
|
+
require_relative 'mtproto/transport/packet'
|
|
5
9
|
require_relative 'mtproto/transport/abridged_packet_codec'
|
|
6
10
|
require_relative 'mtproto/transport/tcp_connection'
|
|
7
|
-
require_relative 'mtproto/
|
|
8
|
-
require_relative 'mtproto/
|
|
9
|
-
require_relative 'mtproto/tl/
|
|
10
|
-
require_relative 'mtproto/tl/
|
|
11
|
-
require_relative 'mtproto/tl/
|
|
12
|
-
require_relative 'mtproto/tl/
|
|
13
|
-
require_relative 'mtproto/tl/
|
|
14
|
-
require_relative 'mtproto/
|
|
15
|
-
require_relative 'mtproto/
|
|
16
|
-
require_relative 'mtproto/
|
|
17
|
-
require_relative 'mtproto/
|
|
18
|
-
require_relative 'mtproto/
|
|
19
|
-
require_relative 'mtproto/
|
|
11
|
+
require_relative 'mtproto/transport/connection'
|
|
12
|
+
require_relative 'mtproto/message/message'
|
|
13
|
+
require_relative 'mtproto/tl/constructors'
|
|
14
|
+
require_relative 'mtproto/tl/object'
|
|
15
|
+
require_relative 'mtproto/tl/objects/update'
|
|
16
|
+
require_relative 'mtproto/tl/objects/update_short'
|
|
17
|
+
require_relative 'mtproto/tl/objects/update_short_message'
|
|
18
|
+
require_relative 'mtproto/type/message'
|
|
19
|
+
require_relative 'mtproto/type/serializer'
|
|
20
|
+
require_relative 'mtproto/type/pq_inner_data'
|
|
21
|
+
require_relative 'mtproto/type/server_dh_inner_data'
|
|
22
|
+
require_relative 'mtproto/type/client_dh_inner_data'
|
|
23
|
+
require_relative 'mtproto/type/bad_msg_notification'
|
|
24
|
+
require_relative 'mtproto/type/msg_container'
|
|
25
|
+
require_relative 'mtproto/type/new_session_created'
|
|
26
|
+
require_relative 'mtproto/type/rpc_error'
|
|
27
|
+
require_relative 'mtproto/type/gzip_packed'
|
|
20
28
|
require_relative 'mtproto/crypto/rsa_key'
|
|
21
29
|
require_relative 'mtproto/crypto/factorization'
|
|
22
30
|
require_relative 'mtproto/crypto/aes_ige'
|
|
@@ -29,15 +37,6 @@ require_relative 'mtproto/auth_key_generator'
|
|
|
29
37
|
require_relative 'mtproto/session'
|
|
30
38
|
require_relative 'mtproto/encrypted_message'
|
|
31
39
|
require_relative 'mtproto/client'
|
|
32
|
-
require_relative 'mtproto/rpc/ping'
|
|
33
|
-
require_relative 'mtproto/rpc/get_config'
|
|
34
|
-
require_relative 'mtproto/rpc/send_code'
|
|
35
|
-
require_relative 'mtproto/rpc/sign_in'
|
|
36
|
-
require_relative 'mtproto/rpc/get_users'
|
|
37
|
-
require_relative 'mtproto/rpc/send_message'
|
|
38
|
-
require_relative 'mtproto/rpc/get_updates_state'
|
|
39
|
-
require_relative 'mtproto/rpc/get_updates_difference'
|
|
40
|
-
require_relative 'mtproto/rpc/get_contacts'
|
|
41
40
|
require_relative 'mtproto/updates_poller'
|
|
42
41
|
|
|
43
42
|
module MTProto
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'net/http'
|
|
6
|
+
require 'uri'
|
|
7
|
+
|
|
8
|
+
SCHEMAS = {
|
|
9
|
+
'https://core.telegram.org/schema/mtproto-json' => 'MTProto',
|
|
10
|
+
'https://core.telegram.org/schema/json' => 'API'
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
def fetch_schema(url)
|
|
14
|
+
uri = URI(url)
|
|
15
|
+
response = Net::HTTP.get(uri)
|
|
16
|
+
JSON.parse(response)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def signed_to_unsigned(id)
|
|
20
|
+
id = id.to_i
|
|
21
|
+
id < 0 ? id + (2**32) : id
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
entries = {}
|
|
25
|
+
|
|
26
|
+
SCHEMAS.each do |url, label|
|
|
27
|
+
schema = fetch_schema(url)
|
|
28
|
+
puts "#{label}: #{schema['constructors'].size} constructors, #{schema['methods'].size} methods"
|
|
29
|
+
|
|
30
|
+
schema['constructors'].each do |c|
|
|
31
|
+
hex = signed_to_unsigned(c['id'])
|
|
32
|
+
entries[hex] = c['predicate']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
schema['methods'].each do |m|
|
|
36
|
+
hex = signed_to_unsigned(m['id'])
|
|
37
|
+
entries[hex] = m['method']
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
puts "Total: #{entries.size} entries"
|
|
42
|
+
|
|
43
|
+
lines = entries.sort_by { |hex, _| hex }.map do |hex, name|
|
|
44
|
+
" 0x#{hex.to_s(16).rjust(8, '0')} => '#{name}'"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
output = <<~RUBY
|
|
48
|
+
# frozen_string_literal: true
|
|
49
|
+
|
|
50
|
+
# Auto-generated from Telegram TL schemas.
|
|
51
|
+
# Run: ruby scripts/generate_constructors.rb
|
|
52
|
+
|
|
53
|
+
module MTProto
|
|
54
|
+
module TL
|
|
55
|
+
module Constructors
|
|
56
|
+
NAMES = {
|
|
57
|
+
#{lines.join(",\n")}
|
|
58
|
+
}.freeze
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
RUBY
|
|
63
|
+
|
|
64
|
+
File.write(File.expand_path('../lib/mtproto/tl/constructors.rb', __dir__), output)
|
|
65
|
+
puts 'Written to lib/mtproto/tl/constructors.rb'
|