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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/data/tl-schema.json +42686 -0
  3. data/ext/aes_ige/extconf.rb +1 -1
  4. data/ext/factorization/extconf.rb +1 -1
  5. data/lib/mtproto/client/api/get_dialogs.rb +21 -0
  6. data/lib/mtproto/client/api/get_history.rb +20 -0
  7. data/lib/mtproto/client/api.rb +8 -0
  8. data/lib/mtproto/client/rpc.rb +4 -7
  9. data/lib/mtproto/client.rb +7 -7
  10. data/lib/mtproto/errors.rb +8 -0
  11. data/lib/mtproto/tl/constructor_names.rb +2271 -0
  12. data/lib/mtproto/tl/constructors.rb +91 -2261
  13. data/lib/mtproto/tl/object.rb +1 -1
  14. data/lib/mtproto/tl/objects/account_password.rb +2 -5
  15. data/lib/mtproto/tl/objects/authorization.rb +2 -5
  16. data/lib/mtproto/tl/objects/check_password.rb +2 -5
  17. data/lib/mtproto/tl/objects/client_dh_inner_data.rb +1 -3
  18. data/lib/mtproto/tl/objects/dh_gen_response.rb +3 -7
  19. data/lib/mtproto/tl/objects/dialogs.rb +453 -0
  20. data/lib/mtproto/tl/objects/export_login_token.rb +2 -5
  21. data/lib/mtproto/tl/objects/get_config.rb +1 -3
  22. data/lib/mtproto/tl/objects/get_dialogs.rb +51 -0
  23. data/lib/mtproto/tl/objects/get_difference.rb +1 -3
  24. data/lib/mtproto/tl/objects/get_history.rb +49 -0
  25. data/lib/mtproto/tl/objects/get_password.rb +1 -3
  26. data/lib/mtproto/tl/objects/get_state.rb +1 -3
  27. data/lib/mtproto/tl/objects/get_users.rb +3 -7
  28. data/lib/mtproto/{type → tl/objects}/gzip_packed.rb +1 -3
  29. data/lib/mtproto/tl/objects/help_config.rb +4 -5
  30. data/lib/mtproto/tl/objects/import_login_token.rb +1 -3
  31. data/lib/mtproto/tl/objects/init_connection.rb +1 -3
  32. data/lib/mtproto/tl/objects/invoke_with_layer.rb +1 -3
  33. data/lib/mtproto/tl/objects/login_token.rb +3 -7
  34. data/lib/mtproto/{type → tl/objects}/message.rb +1 -1
  35. data/lib/mtproto/tl/objects/messages.rb +162 -0
  36. data/lib/mtproto/{type → tl/objects}/msg_container.rb +1 -3
  37. data/lib/mtproto/{type → tl/objects}/new_session_created.rb +1 -3
  38. data/lib/mtproto/tl/objects/pq_inner_data.rb +1 -4
  39. data/lib/mtproto/tl/objects/req_dh_params.rb +1 -3
  40. data/lib/mtproto/tl/objects/req_pq_multi.rb +1 -3
  41. data/lib/mtproto/tl/objects/res_pq.rb +2 -4
  42. data/lib/mtproto/{type → tl/objects}/rpc_error.rb +1 -3
  43. data/lib/mtproto/tl/objects/send_code.rb +2 -5
  44. data/lib/mtproto/tl/objects/sent_code.rb +4 -4
  45. data/lib/mtproto/tl/objects/server_dh_inner_data.rb +3 -3
  46. data/lib/mtproto/tl/objects/server_dh_params.rb +3 -3
  47. data/lib/mtproto/tl/objects/set_client_dh_params.rb +1 -3
  48. data/lib/mtproto/tl/objects/sign_in.rb +1 -3
  49. data/lib/mtproto/tl/objects/update.rb +3 -6
  50. data/lib/mtproto/tl/objects/update_short.rb +0 -2
  51. data/lib/mtproto/tl/objects/update_short_message.rb +0 -2
  52. data/lib/mtproto/tl/objects/updates_difference.rb +6 -11
  53. data/lib/mtproto/tl/objects/updates_state.rb +1 -3
  54. data/lib/mtproto/tl/objects/users.rb +2 -5
  55. data/lib/mtproto/tl/schema.rb +102 -0
  56. data/lib/mtproto/version.rb +1 -1
  57. data/lib/mtproto.rb +6 -10
  58. metadata +15 -11
  59. data/lib/mtproto/type/bad_msg_notification.rb +0 -46
  60. data/lib/mtproto/type/client_dh_inner_data.rb +0 -29
  61. data/lib/mtproto/type/pq_inner_data.rb +0 -41
  62. data/lib/mtproto/type/serializer.rb +0 -55
  63. data/lib/mtproto/type/server_dh_inner_data.rb +0 -85
@@ -3,8 +3,6 @@
3
3
  module MTProto
4
4
  module TL
5
5
  class UpdateShort
6
- CONSTRUCTOR = 0x78d4dec1
7
-
8
6
  attr_reader :update, :date
9
7
 
10
8
  def initialize(update, date)
@@ -3,8 +3,6 @@
3
3
  module MTProto
4
4
  module TL
5
5
  class UpdateShortMessage
6
- CONSTRUCTOR = 0x313bc7f8
7
-
8
6
  attr_reader :flags, :id, :user_id, :text, :pts, :pts_count, :date
9
7
 
10
8
  def initialize(flags:, id:, user_id:, text:, pts:, pts_count:, date:)
@@ -3,11 +3,6 @@
3
3
  module MTProto
4
4
  module TL
5
5
  class UpdatesDifference
6
- CONSTRUCTOR_EMPTY = 0x5d75a138
7
- CONSTRUCTOR_DIFFERENCE = 0x00f49ca0
8
- CONSTRUCTOR_SLICE = 0xa8fb1981
9
- CONSTRUCTOR_TOO_LONG = 0x4afe8f6d
10
-
11
6
  attr_reader :type, :date, :seq, :new_messages, :users, :pts, :state
12
7
 
13
8
  def initialize(type:, date: nil, seq: nil, new_messages: [], users: [], pts: nil, state: nil)
@@ -24,11 +19,11 @@ module MTProto
24
19
  constructor = data[0, 4].unpack1('L<')
25
20
 
26
21
  case constructor
27
- when CONSTRUCTOR_EMPTY
22
+ when Constructors::UPDATES_DIFFERENCE_EMPTY
28
23
  parse_empty(data)
29
- when CONSTRUCTOR_DIFFERENCE, CONSTRUCTOR_SLICE
24
+ when Constructors::UPDATES_DIFFERENCE, Constructors::UPDATES_DIFFERENCE_SLICE
30
25
  parse_difference(data, constructor)
31
- when CONSTRUCTOR_TOO_LONG
26
+ when Constructors::UPDATES_DIFFERENCE_TOO_LONG
32
27
  new(type: :too_long, pts: data[4, 4].unpack1('L<'))
33
28
  else
34
29
  warn "Unknown Difference constructor: 0x#{constructor.to_s(16)}, treating as empty"
@@ -57,7 +52,7 @@ module MTProto
57
52
  users, = parse_users_vector(data, offset)
58
53
 
59
54
  new(
60
- type: constructor == CONSTRUCTOR_DIFFERENCE ? :difference : :slice,
55
+ type: constructor == Constructors::UPDATES_DIFFERENCE ? :difference : :slice,
61
56
  new_messages: messages,
62
57
  users: users
63
58
  )
@@ -80,7 +75,7 @@ module MTProto
80
75
  msg_constructor = data[offset, 4].unpack1('L<')
81
76
  offset += 4
82
77
 
83
- return [nil, offset] unless msg_constructor == 0x452c0e65
78
+ return [nil, offset] unless msg_constructor == Constructors::MESSAGE
84
79
 
85
80
  flags = data[offset, 4].unpack1('L<')
86
81
  offset += 4
@@ -108,7 +103,7 @@ module MTProto
108
103
  count.times do
109
104
  user_constructor = data[offset, 4].unpack1('L<')
110
105
  offset += 4
111
- next unless user_constructor == 0x20b1422
106
+ next unless user_constructor == Constructors::USER
112
107
 
113
108
  flags = data[offset, 4].unpack1('L<')
114
109
  offset += 4
@@ -3,8 +3,6 @@
3
3
  module MTProto
4
4
  module TL
5
5
  class UpdatesState
6
- CONSTRUCTOR = 0xa56c2a3e
7
-
8
6
  attr_accessor :pts, :qts, :date, :seq, :unread_count
9
7
 
10
8
  def initialize(pts:, qts:, date:, seq:, unread_count:)
@@ -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 == CONSTRUCTOR
18
+ raise UnexpectedConstructorError, constructor unless constructor == Constructors::UPDATES_STATE
21
19
 
22
20
  offset = 4
23
21
  pts = data[offset, 4].unpack1('L<')
@@ -3,15 +3,12 @@
3
3
  module MTProto
4
4
  module TL
5
5
  class Users
6
- VECTOR_CONSTRUCTOR = 0x1cb5c415
7
- USER_CONSTRUCTOR = 0x020b1422
8
-
9
6
  User = Struct.new(:id, :access_hash, :first_name, :last_name, :username, :phone, :flags, :flags2,
10
7
  keyword_init: true)
11
8
 
12
9
  def self.parse(data)
13
10
  constructor = data[0, 4].unpack1('L<')
14
- raise "Expected Vector constructor, got 0x#{constructor.to_s(16)}" unless constructor == VECTOR_CONSTRUCTOR
11
+ raise "Expected Vector constructor, got 0x#{constructor.to_s(16)}" unless constructor == Constructors::VECTOR
15
12
 
16
13
  offset = 4
17
14
  count = data[offset, 4].unpack1('L<')
@@ -21,7 +18,7 @@ module MTProto
21
18
  count.times do
22
19
  user_constructor = data[offset, 4].unpack1('L<')
23
20
  offset += 4
24
- next unless user_constructor == USER_CONSTRUCTOR
21
+ next unless user_constructor == Constructors::USER
25
22
 
26
23
  flags = data[offset, 4].unpack1('L<')
27
24
  offset += 4
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module MTProto
6
+ module TL
7
+ class Schema
8
+ PRIMITIVES = {
9
+ 'int' => 4, 'long' => 8, 'double' => 8,
10
+ 'int128' => 16, 'int256' => 32
11
+ }.freeze
12
+
13
+ def initialize(path)
14
+ raw = JSON.parse(File.read(path))
15
+ @constructors = {}
16
+ raw['constructors'].each do |c|
17
+ uid = c['id'].to_i & 0xFFFFFFFF
18
+ @constructors[uid] = c['params']
19
+ end
20
+ end
21
+
22
+ def skip(data, offset)
23
+ constructor = data[offset, 4].unpack1('L<')
24
+ offset += 4
25
+ skip_params(data, offset, constructor)
26
+ end
27
+
28
+ def skip_vector(data, offset, &block)
29
+ offset += 4 # vector constructor 0x1cb5c415
30
+ count = data[offset, 4].unpack1('L<')
31
+ offset += 4
32
+ count.times { offset = block ? yield(data, offset) : skip(data, offset) }
33
+ offset
34
+ end
35
+
36
+ def skip_params(data, offset, constructor)
37
+ params = @constructors[constructor]
38
+ raise "Unknown constructor: 0x#{constructor.to_s(16).rjust(8, '0')}" unless params
39
+
40
+ flag_values = {}
41
+
42
+ params.each do |param|
43
+ type = param['type']
44
+
45
+ if type == '#'
46
+ flag_values[param['name']] = data[offset, 4].unpack1('L<')
47
+ offset += 4
48
+ next
49
+ end
50
+
51
+ if (m = type.match(/\A(\w+)\.(\d+)\?(.+)\z/))
52
+ flag_name = m[1]
53
+ bit = m[2].to_i
54
+ inner_type = m[3]
55
+ next if inner_type == 'true'
56
+ next unless flag_values[flag_name]&.anybits?(1 << bit)
57
+
58
+ offset = skip_type(data, offset, inner_type)
59
+ else
60
+ offset = skip_type(data, offset, type)
61
+ end
62
+ end
63
+ offset
64
+ end
65
+
66
+ private
67
+
68
+ def skip_type(data, offset, type)
69
+ if (size = PRIMITIVES[type])
70
+ return offset + size
71
+ end
72
+
73
+ case type
74
+ when 'string', 'bytes'
75
+ skip_tl_string(data, offset)
76
+ when 'Bool'
77
+ offset + 4
78
+ when /\AVector<(.+)>\z/
79
+ inner = Regexp.last_match(1)
80
+ skip_vector(data, offset) { |d, o| skip_type(d, o, inner) }
81
+ else
82
+ skip(data, offset)
83
+ end
84
+ end
85
+
86
+ def skip_tl_string(data, offset)
87
+ first_byte = data.getbyte(offset)
88
+ if first_byte == 254
89
+ len = data.getbyte(offset + 1) |
90
+ (data.getbyte(offset + 2) << 8) |
91
+ (data.getbyte(offset + 3) << 16)
92
+ total = 4 + len
93
+ else
94
+ len = first_byte
95
+ total = 1 + len
96
+ end
97
+ padding = (4 - (total % 4)) % 4
98
+ offset + total + padding
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MTProto
4
- VERSION = '0.0.9'
4
+ VERSION = '0.0.11'
5
5
  end
data/lib/mtproto.rb CHANGED
@@ -11,20 +11,16 @@ require_relative 'mtproto/transport/tcp_connection'
11
11
  require_relative 'mtproto/transport/connection'
12
12
  require_relative 'mtproto/message/message'
13
13
  require_relative 'mtproto/tl/constructors'
14
+ require_relative 'mtproto/tl/constructor_names'
14
15
  require_relative 'mtproto/tl/object'
15
16
  require_relative 'mtproto/tl/objects/update'
16
17
  require_relative 'mtproto/tl/objects/update_short'
17
18
  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'
19
+ require_relative 'mtproto/tl/objects/message'
20
+ require_relative 'mtproto/tl/objects/msg_container'
21
+ require_relative 'mtproto/tl/objects/new_session_created'
22
+ require_relative 'mtproto/tl/objects/rpc_error'
23
+ require_relative 'mtproto/tl/objects/gzip_packed'
28
24
  require_relative 'mtproto/crypto/rsa_key'
29
25
  require_relative 'mtproto/crypto/factorization'
30
26
  require_relative 'mtproto/crypto/aes_ige'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mtproto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Levenkov
@@ -50,6 +50,7 @@ files:
50
50
  - ".env.example"
51
51
  - ".ruby-version"
52
52
  - Rakefile
53
+ - data/tl-schema.json
53
54
  - ext/aes_ige/aes_ige.c
54
55
  - ext/aes_ige/extconf.rb
55
56
  - ext/factorization/extconf.rb
@@ -61,6 +62,8 @@ files:
61
62
  - lib/mtproto/client/api.rb
62
63
  - lib/mtproto/client/api/check_password.rb
63
64
  - lib/mtproto/client/api/export_login_token.rb
65
+ - lib/mtproto/client/api/get_dialogs.rb
66
+ - lib/mtproto/client/api/get_history.rb
64
67
  - lib/mtproto/client/api/get_updates_difference.rb
65
68
  - lib/mtproto/client/api/get_updates_state.rb
66
69
  - lib/mtproto/client/api/get_users.rb
@@ -84,6 +87,7 @@ files:
84
87
  - lib/mtproto/message/message.rb
85
88
  - lib/mtproto/message_id.rb
86
89
  - lib/mtproto/session.rb
90
+ - lib/mtproto/tl/constructor_names.rb
87
91
  - lib/mtproto/tl/constructors.rb
88
92
  - lib/mtproto/tl/object.rb
89
93
  - lib/mtproto/tl/objects/account_password.rb
@@ -91,21 +95,30 @@ files:
91
95
  - lib/mtproto/tl/objects/check_password.rb
92
96
  - lib/mtproto/tl/objects/client_dh_inner_data.rb
93
97
  - lib/mtproto/tl/objects/dh_gen_response.rb
98
+ - lib/mtproto/tl/objects/dialogs.rb
94
99
  - lib/mtproto/tl/objects/export_login_token.rb
95
100
  - lib/mtproto/tl/objects/get_config.rb
101
+ - lib/mtproto/tl/objects/get_dialogs.rb
96
102
  - lib/mtproto/tl/objects/get_difference.rb
103
+ - lib/mtproto/tl/objects/get_history.rb
97
104
  - lib/mtproto/tl/objects/get_password.rb
98
105
  - lib/mtproto/tl/objects/get_state.rb
99
106
  - lib/mtproto/tl/objects/get_users.rb
107
+ - lib/mtproto/tl/objects/gzip_packed.rb
100
108
  - lib/mtproto/tl/objects/help_config.rb
101
109
  - lib/mtproto/tl/objects/import_login_token.rb
102
110
  - lib/mtproto/tl/objects/init_connection.rb
103
111
  - lib/mtproto/tl/objects/invoke_with_layer.rb
104
112
  - lib/mtproto/tl/objects/login_token.rb
113
+ - lib/mtproto/tl/objects/message.rb
114
+ - lib/mtproto/tl/objects/messages.rb
115
+ - lib/mtproto/tl/objects/msg_container.rb
116
+ - lib/mtproto/tl/objects/new_session_created.rb
105
117
  - lib/mtproto/tl/objects/pq_inner_data.rb
106
118
  - lib/mtproto/tl/objects/req_dh_params.rb
107
119
  - lib/mtproto/tl/objects/req_pq_multi.rb
108
120
  - lib/mtproto/tl/objects/res_pq.rb
121
+ - lib/mtproto/tl/objects/rpc_error.rb
109
122
  - lib/mtproto/tl/objects/send_code.rb
110
123
  - lib/mtproto/tl/objects/sent_code.rb
111
124
  - lib/mtproto/tl/objects/server_dh_inner_data.rb
@@ -118,21 +131,12 @@ files:
118
131
  - lib/mtproto/tl/objects/updates_difference.rb
119
132
  - lib/mtproto/tl/objects/updates_state.rb
120
133
  - lib/mtproto/tl/objects/users.rb
134
+ - lib/mtproto/tl/schema.rb
121
135
  - lib/mtproto/transport/abridged_packet_codec.rb
122
136
  - lib/mtproto/transport/connection.rb
123
137
  - lib/mtproto/transport/errors.rb
124
138
  - lib/mtproto/transport/packet.rb
125
139
  - lib/mtproto/transport/tcp_connection.rb
126
- - lib/mtproto/type/bad_msg_notification.rb
127
- - lib/mtproto/type/client_dh_inner_data.rb
128
- - lib/mtproto/type/gzip_packed.rb
129
- - lib/mtproto/type/message.rb
130
- - lib/mtproto/type/msg_container.rb
131
- - lib/mtproto/type/new_session_created.rb
132
- - lib/mtproto/type/pq_inner_data.rb
133
- - lib/mtproto/type/rpc_error.rb
134
- - lib/mtproto/type/serializer.rb
135
- - lib/mtproto/type/server_dh_inner_data.rb
136
140
  - lib/mtproto/updates_poller.rb
137
141
  - lib/mtproto/version.rb
138
142
  - scripts/generate_constructors.rb
@@ -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,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,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MTProto
4
- module Type
5
- module Serializer
6
- module_function
7
-
8
- def serialize_int(value)
9
- [value].pack('L<')
10
- end
11
-
12
- def serialize_long(value)
13
- [value].pack('Q<')
14
- end
15
-
16
- def serialize_int128(value)
17
- value.is_a?(String) ? value : [value].pack('Q<Q<')
18
- end
19
-
20
- def serialize_int256(value)
21
- value.is_a?(String) ? value : [value].pack('Q<Q<Q<Q<')
22
- end
23
-
24
- def serialize_bytes(bytes)
25
- length = bytes.bytesize
26
-
27
- if length <= 253
28
- [length].pack('C').b + bytes.b + padding(length + 1)
29
- else
30
- [254].pack('C').b + [length].pack('L<')[0, 3].b + bytes.b + padding(length + 4)
31
- end
32
- end
33
-
34
- def serialize_string(str)
35
- serialize_bytes(str)
36
- end
37
-
38
- def padding(current_length)
39
- pad_length = (4 - (current_length % 4)) % 4
40
- ("\x00" * pad_length).b
41
- end
42
-
43
- def integer_to_bytes(int)
44
- return "\x00" if int.zero?
45
-
46
- bytes = []
47
- while int > 0
48
- bytes.unshift(int & 0xff)
49
- int >>= 8
50
- end
51
- bytes.pack('C*')
52
- end
53
- end
54
- end
55
- end
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MTProto
4
- module Type
5
- class ServerDHInnerData
6
- CONSTRUCTOR = 0xb5890dba
7
-
8
- attr_reader :nonce, :server_nonce, :g, :dh_prime, :g_a, :server_time
9
-
10
- def self.deserialize(data)
11
- constructor = data[0, 4].unpack1('L<')
12
- raise "Unexpected constructor: 0x#{constructor.to_s(16)}" unless constructor == CONSTRUCTOR
13
-
14
- offset = 4
15
-
16
- nonce = data[offset, 16]
17
- offset += 16
18
-
19
- server_nonce = data[offset, 16]
20
- offset += 16
21
-
22
- g = data[offset, 4].unpack1('L<')
23
- offset += 4
24
-
25
- dh_prime_length_byte = data[offset].ord
26
- offset += 1
27
-
28
- if dh_prime_length_byte == 254
29
- length_bytes = data[offset, 3].bytes
30
- dh_prime_length = length_bytes[0] | (length_bytes[1] << 8) | (length_bytes[2] << 16)
31
- offset += 3
32
- else
33
- dh_prime_length = dh_prime_length_byte
34
- end
35
-
36
- dh_prime = data[offset, dh_prime_length]
37
- offset += dh_prime_length
38
- offset += padding_length(dh_prime_length_byte == 254 ? dh_prime_length + 4 : dh_prime_length + 1)
39
-
40
- g_a_length_byte = data[offset].ord
41
- offset += 1
42
-
43
- if g_a_length_byte == 254
44
- length_bytes = data[offset, 3].bytes
45
- g_a_length = length_bytes[0] | (length_bytes[1] << 8) | (length_bytes[2] << 16)
46
- offset += 3
47
- else
48
- g_a_length = g_a_length_byte
49
- end
50
-
51
- g_a = data[offset, g_a_length]
52
- offset += g_a_length
53
- offset += padding_length(g_a_length_byte == 254 ? g_a_length + 4 : g_a_length + 1)
54
-
55
- server_time = data[offset, 4].unpack1('L<')
56
-
57
- new(
58
- nonce: nonce,
59
- server_nonce: server_nonce,
60
- g: g,
61
- dh_prime: dh_prime,
62
- g_a: g_a,
63
- server_time: server_time
64
- )
65
- end
66
-
67
- def initialize(nonce:, server_nonce:, g:, dh_prime:, g_a:, server_time:)
68
- @nonce = nonce
69
- @server_nonce = server_nonce
70
- @g = g
71
- @dh_prime = dh_prime
72
- @g_a = g_a
73
- @server_time = server_time
74
- end
75
-
76
- def self.padding_length(length)
77
- (4 - (length % 4)) % 4
78
- end
79
-
80
- def padding_length(length)
81
- self.class.padding_length(length)
82
- end
83
- end
84
- end
85
- end