mtproto 0.0.32 → 0.0.34

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/docs/test_architecture_level1.md +23 -107
  3. data/lib/mtproto/auth_key_generator.rb +3 -1
  4. data/lib/mtproto/client/api/resolve_username.rb +18 -0
  5. data/lib/mtproto/client/api/send_message.rb +5 -2
  6. data/lib/mtproto/client/api/set_typing.rb +4 -4
  7. data/lib/mtproto/client/api/stream_draft.rb +13 -0
  8. data/lib/mtproto/client/api.rb +2 -0
  9. data/lib/mtproto/crypto/dh_key_exchange.rb +2 -1
  10. data/lib/mtproto/draft_stream.rb +52 -0
  11. data/lib/mtproto/tl/constructors.rb +1 -0
  12. data/lib/mtproto/tl/objects/authorization.rb +4 -3
  13. data/lib/mtproto/tl/objects/channel_difference.rb +13 -32
  14. data/lib/mtproto/tl/objects/contacts.rb +7 -89
  15. data/lib/mtproto/tl/objects/dialogs.rb +14 -352
  16. data/lib/mtproto/tl/objects/edit_message.rb +1 -1
  17. data/lib/mtproto/tl/objects/media_parts.rb +68 -0
  18. data/lib/mtproto/tl/objects/message.rb +14 -0
  19. data/lib/mtproto/tl/objects/message_service.rb +40 -0
  20. data/lib/mtproto/tl/objects/messages.rb +7 -32
  21. data/lib/mtproto/tl/objects/reply_keyboard_force_reply.rb +46 -0
  22. data/lib/mtproto/tl/objects/resolved_peer.rb +29 -0
  23. data/lib/mtproto/tl/objects/send_message.rb +1 -1
  24. data/lib/mtproto/tl/objects/send_message_text_draft_action.rb +52 -0
  25. data/lib/mtproto/tl/objects/send_multi_media.rb +52 -0
  26. data/lib/mtproto/tl/objects/update.rb +3 -35
  27. data/lib/mtproto/tl/objects/updates.rb +4 -6
  28. data/lib/mtproto/tl/objects/updates_difference.rb +9 -29
  29. data/lib/mtproto/tl/objects/upload_media.rb +26 -0
  30. data/lib/mtproto/tl/peers.rb +236 -0
  31. data/lib/mtproto/tl/reader.rb +29 -2
  32. data/lib/mtproto/updates/event_builder.rb +20 -32
  33. data/lib/mtproto/updates/parser.rb +9 -8
  34. data/lib/mtproto/updates/state_machine.rb +7 -7
  35. data/lib/mtproto/version.rb +1 -1
  36. data/lib/mtproto.rb +1 -0
  37. metadata +12 -1
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../tl/reader'
4
4
  require_relative '../tl/objects/message'
5
+ require_relative '../tl/objects/message_service'
5
6
  require_relative '../tl/objects/updates'
6
7
  require_relative 'event'
7
8
 
@@ -27,7 +28,6 @@ module MTProto
27
28
  UPDATE_BOT_GUEST_CHAT_QUERY = 0xcdd4093d
28
29
  UPDATE_MANAGED_BOT = 0x4880ed9a
29
30
 
30
- MESSAGE_SERVICE = 0x7a800e0a
31
31
  ACTION_CHAT_ADD_USER = 0x15cefd00
32
32
  ACTION_JOINED_BY_LINK = 0x031224c3
33
33
  ACTION_CHAT_DELETE_USER = 0xa43f30cc
@@ -76,16 +76,13 @@ module MTProto
76
76
  bot_id: data[offset + 12, 8].unpack1('Q<'))
77
77
  end
78
78
 
79
- # A Vector<Message> entry (a difference's new_messages) a :message / :join /
80
- # :leave Event WITHOUT pts (the protocol omits per-message pts there), or nil.
79
+ # One message — an entry of a Vector<Message>, or the one inside an
80
+ # updateNew(Channel)Message a :message / :join / :leave Event, or nil.
81
81
  # `channel` is the envelope's kind (true for a channelDifference), since the
82
82
  # message itself doesn't say.
83
- def message_or_service(data, offset, ctor, channel:)
84
- if ctor == TL::Constructors::MESSAGE
85
- message_event(data, offset, ctor, kind: :message, channel: channel, pts: nil, pts_count: nil)
86
- elsif ctor == MESSAGE_SERVICE
87
- service_event(data, offset, channel: channel, pts: nil, pts_count: nil)
88
- end
83
+ def message_or_service(data, offset, ctor, channel:, pts:, pts_count:)
84
+ message_event(data, offset, ctor, kind: :message, channel: channel, pts: pts, pts_count: pts_count) ||
85
+ service_event(data, offset, ctor, channel: channel, pts: pts, pts_count: pts_count)
89
86
  end
90
87
 
91
88
  # updateNew(Channel)Message: the update tag, an inner Message (plain message, or
@@ -95,11 +92,7 @@ module MTProto
95
92
  inner_ctor = data[inner_off, 4].unpack1('L<')
96
93
  pts, pts_count = pts_after(data, inner_off)
97
94
 
98
- if inner_ctor == TL::Constructors::MESSAGE
99
- message_event(data, inner_off, inner_ctor, kind: :message, channel: channel, pts: pts, pts_count: pts_count)
100
- elsif inner_ctor == MESSAGE_SERVICE
101
- service_event(data, inner_off, channel: channel, pts: pts, pts_count: pts_count)
102
- end
95
+ message_or_service(data, inner_off, inner_ctor, channel: channel, pts: pts, pts_count: pts_count)
103
96
  end
104
97
 
105
98
  def edit_message(data, offset, channel:)
@@ -127,19 +120,11 @@ module MTProto
127
120
 
128
121
  # messageService carrying a membership action → a :join / :leave Event, else nil.
129
122
  # peer_id is the service message's own chat (where the event happened).
130
- def service_event(data, offset, channel:, pts:, pts_count:)
131
- io = offset + 4
132
- flags = data[io, 4].unpack1('L<')
133
- io += 8 # flags + id
134
- _from_type, from_id, io = TL::Reader.parse_peer(data, io) if flags.anybits?(1 << 8) # from_id
135
- peer_type, peer_id, io = TL::Reader.parse_peer(data, io)
136
- io = TL::Reader.schema.skip(data, io) if flags.anybits?(1 << 28) # saved_peer_id
137
- io = TL::Reader.schema.skip(data, io) if flags.anybits?(1 << 3) # reply_to
138
- io += 4 # date
139
- action = data[io, 4].unpack1('L<')
140
- id = data[offset + 8, 4].unpack1('l<')
123
+ def service_event(data, offset, ctor, channel:, pts:, pts_count:)
124
+ header = TL::MessageService.deserialize(data, offset, ctor)
125
+ return unless header
141
126
 
142
- event = membership_event(data, io, action, from_id, peer_type, peer_id, id)
127
+ event = membership_event(data, header)
143
128
  return unless event
144
129
 
145
130
  event.channel = channel
@@ -150,19 +135,22 @@ module MTProto
150
135
  nil
151
136
  end
152
137
 
153
- def membership_event(data, io, action, from_id, peer_type, peer_id, id)
154
- case action
138
+ def membership_event(data, header)
139
+ io = header.action_offset
140
+ case data[io, 4].unpack1('L<')
155
141
  when ACTION_CHAT_ADD_USER
156
- joined = from_id
142
+ joined = header.from_id
157
143
  if data[io + 4, 4].unpack1('L<') == VECTOR && data[io + 8, 4].unpack1('L<').positive?
158
144
  joined = data[io + 12, 8].unpack1('Q<')
159
145
  end
160
- Event.new(kind: :join, joined_user_id: joined, peer_type: peer_type, peer_id: peer_id, msg_id: id)
146
+ Event.new(kind: :join, joined_user_id: joined,
147
+ peer_type: header.peer_type, peer_id: header.peer_id, msg_id: header.id)
161
148
  when ACTION_JOINED_BY_LINK
162
- Event.new(kind: :join, joined_user_id: from_id, peer_type: peer_type, peer_id: peer_id, msg_id: id)
149
+ Event.new(kind: :join, joined_user_id: header.from_id,
150
+ peer_type: header.peer_type, peer_id: header.peer_id, msg_id: header.id)
163
151
  when ACTION_CHAT_DELETE_USER
164
152
  Event.new(kind: :leave, left_user_id: data[io + 4, 8].unpack1('Q<'),
165
- peer_type: peer_type, peer_id: peer_id, msg_id: id)
153
+ peer_type: header.peer_type, peer_id: header.peer_id, msg_id: header.id)
166
154
  end
167
155
  end
168
156
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative '../tl/reader'
4
- require_relative '../tl/objects/dialogs'
4
+ require_relative '../tl/peers'
5
5
  require_relative '../tl/objects/updates_state'
6
6
  require_relative 'event_builder'
7
7
 
@@ -74,8 +74,8 @@ module MTProto
74
74
  # (updatesCombined only inserts seq_start before the trailing seq, past date).
75
75
  def parse_updates(data)
76
76
  events, channel_too_long, offset = updates_vector(data, 4)
77
- users, offset = TL::Dialogs.users_at(data, offset)
78
- chats, offset = TL::Dialogs.chats_at(data, offset)
77
+ users, offset = TL::Peers.users_at(data, offset)
78
+ chats, offset = TL::Peers.chats_at(data, offset)
79
79
  date = data[offset, 4].unpack1('L<')
80
80
  attach_peers(events, users, chats)
81
81
  Batch.new(events: events, users: users, chats: chats,
@@ -128,8 +128,8 @@ module MTProto
128
128
  msg_events, offset = messages_vector(data, 4, channel: false)
129
129
  offset = TL::Reader.schema.skip_vector(data, offset) # new_encrypted_messages
130
130
  upd_events, channel_too_long, offset = updates_vector(data, offset)
131
- chats, offset = TL::Dialogs.chats_at(data, offset)
132
- users, offset = TL::Dialogs.users_at(data, offset)
131
+ chats, offset = TL::Peers.chats_at(data, offset)
132
+ users, offset = TL::Peers.users_at(data, offset)
133
133
  state = TL::UpdatesState.deserialize(data[offset..])
134
134
 
135
135
  events = msg_events + upd_events
@@ -151,8 +151,8 @@ module MTProto
151
151
 
152
152
  msg_events, offset = messages_vector(data, offset, channel: true)
153
153
  upd_events, channel_too_long, offset = updates_vector(data, offset)
154
- chats, offset = TL::Dialogs.chats_at(data, offset)
155
- users, = TL::Dialogs.users_at(data, offset)
154
+ chats, offset = TL::Peers.chats_at(data, offset)
155
+ users, = TL::Peers.users_at(data, offset)
156
156
 
157
157
  events = msg_events + upd_events
158
158
  attach_peers(events, users, chats)
@@ -169,7 +169,8 @@ module MTProto
169
169
 
170
170
  events = []
171
171
  count.times do
172
- event = EventBuilder.message_or_service(data, offset, data[offset, 4].unpack1('L<'), channel: channel)
172
+ event = EventBuilder.message_or_service(data, offset, data[offset, 4].unpack1('L<'),
173
+ channel: channel, pts: nil, pts_count: nil)
173
174
  events << event if event
174
175
  offset = TL::Reader.schema.skip(data, offset)
175
176
  end
@@ -51,14 +51,14 @@ module MTProto
51
51
 
52
52
  def dispatch(batch, &)
53
53
  remember_channels(batch.chats)
54
- batch.events.each { |event| ingest(event, &) }
54
+ batch.events.each { |event| ingest(event, batch, &) }
55
55
  batch.channel_too_long.each { |channel_id| recover_channel(channel_id, &) }
56
56
  catch_up(&) if batch.too_long
57
57
  end
58
58
 
59
- def ingest(event, &)
59
+ def ingest(event, batch, &)
60
60
  detect_gap(event, &)
61
- emit(event, &)
61
+ emit(event, batch, &)
62
62
  end
63
63
 
64
64
  # A live update whose pts jumps past our stored position means updates were
@@ -80,11 +80,11 @@ module MTProto
80
80
  # host's transaction (atomic with the host's own handling); the in-memory @pts is
81
81
  # advanced only AFTER the transaction commits, so a rollback can never leave the
82
82
  # cache ahead of the store and silently drop later account updates.
83
- def emit(event, &block)
83
+ def emit(event, batch, &block)
84
84
  return if outdated?(event)
85
85
 
86
86
  @store.transaction do
87
- block.call(event)
87
+ block.call(event, batch)
88
88
  checkpoint(event)
89
89
  end
90
90
  cache_account_position(event)
@@ -142,7 +142,7 @@ module MTProto
142
142
 
143
143
  def apply_difference(diff, &)
144
144
  remember_channels(diff.chats)
145
- diff.events.each { |event| emit(event, &) }
145
+ diff.events.each { |event| emit(event, diff, &) }
146
146
  diff.channel_too_long.each { |channel_id| recover_channel(channel_id, &) }
147
147
  @pts = diff.pts if diff.pts
148
148
  @qts = diff.qts if diff.qts
@@ -164,7 +164,7 @@ module MTProto
164
164
  return catch_up(&) if diff.type == :too_long
165
165
 
166
166
  remember_channels(diff.chats)
167
- diff.events.each { |event| emit(event, &) }
167
+ diff.events.each { |event| emit(event, diff, &) }
168
168
  if diff.pts&.positive?
169
169
  from = diff.pts
170
170
  @store.set_channel_pts(channel_id, diff.pts)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MTProto
4
- VERSION = '0.0.32'
4
+ VERSION = '0.0.34'
5
5
  end
data/lib/mtproto.rb CHANGED
@@ -14,6 +14,7 @@ require_relative 'mtproto/unencrypted_message'
14
14
  require_relative 'mtproto/tl/constructors'
15
15
  require_relative 'mtproto/tl/constructor_names'
16
16
  require_relative 'mtproto/tl/reader'
17
+ require_relative 'mtproto/tl/peers'
17
18
  require_relative 'mtproto/tl/message_entity'
18
19
  require_relative 'mtproto/markdown'
19
20
  require_relative 'mtproto/tl/object'
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.32
4
+ version: 0.0.34
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Levenkov
@@ -80,10 +80,12 @@ files:
80
80
  - lib/mtproto/client/api/import_bot_authorization.rb
81
81
  - lib/mtproto/client/api/import_login_token.rb
82
82
  - lib/mtproto/client/api/pin_message.rb
83
+ - lib/mtproto/client/api/resolve_username.rb
83
84
  - lib/mtproto/client/api/send_code.rb
84
85
  - lib/mtproto/client/api/send_message.rb
85
86
  - lib/mtproto/client/api/set_typing.rb
86
87
  - lib/mtproto/client/api/sign_in.rb
88
+ - lib/mtproto/client/api/stream_draft.rb
87
89
  - lib/mtproto/client/api/unpin_all_messages.rb
88
90
  - lib/mtproto/client/rpc.rb
89
91
  - lib/mtproto/client/rpc/response.rb
@@ -99,6 +101,7 @@ files:
99
101
  - lib/mtproto/crypto/srp.rb
100
102
  - lib/mtproto/dc.rb
101
103
  - lib/mtproto/delegate_methods.rb
104
+ - lib/mtproto/draft_stream.rb
102
105
  - lib/mtproto/encrypted_message.rb
103
106
  - lib/mtproto/errors.rb
104
107
  - lib/mtproto/file_downloader.rb
@@ -169,7 +172,9 @@ files:
169
172
  - lib/mtproto/tl/objects/invoke_with_layer.rb
170
173
  - lib/mtproto/tl/objects/keyboard_button_callback.rb
171
174
  - lib/mtproto/tl/objects/login_token.rb
175
+ - lib/mtproto/tl/objects/media_parts.rb
172
176
  - lib/mtproto/tl/objects/message.rb
177
+ - lib/mtproto/tl/objects/message_service.rb
173
178
  - lib/mtproto/tl/objects/messages.rb
174
179
  - lib/mtproto/tl/objects/messages_add_chat_user.rb
175
180
  - lib/mtproto/tl/objects/messages_create_chat.rb
@@ -179,6 +184,7 @@ files:
179
184
  - lib/mtproto/tl/objects/pq_inner_data.rb
180
185
  - lib/mtproto/tl/objects/raw_response.rb
181
186
  - lib/mtproto/tl/objects/reply_inline_markup.rb
187
+ - lib/mtproto/tl/objects/reply_keyboard_force_reply.rb
182
188
  - lib/mtproto/tl/objects/reply_keyboard_markup.rb
183
189
  - lib/mtproto/tl/objects/req_dh_params.rb
184
190
  - lib/mtproto/tl/objects/req_pq_multi.rb
@@ -186,6 +192,7 @@ files:
186
192
  - lib/mtproto/tl/objects/res_pq.rb
187
193
  - lib/mtproto/tl/objects/reset_bot_commands.rb
188
194
  - lib/mtproto/tl/objects/resolve_username.rb
195
+ - lib/mtproto/tl/objects/resolved_peer.rb
189
196
  - lib/mtproto/tl/objects/rpc_error.rb
190
197
  - lib/mtproto/tl/objects/save_big_file_part.rb
191
198
  - lib/mtproto/tl/objects/save_file_part.rb
@@ -195,6 +202,8 @@ files:
195
202
  - lib/mtproto/tl/objects/send_media.rb
196
203
  - lib/mtproto/tl/objects/send_message.rb
197
204
  - lib/mtproto/tl/objects/send_message_action.rb
205
+ - lib/mtproto/tl/objects/send_message_text_draft_action.rb
206
+ - lib/mtproto/tl/objects/send_multi_media.rb
198
207
  - lib/mtproto/tl/objects/send_reaction.rb
199
208
  - lib/mtproto/tl/objects/sent_code.rb
200
209
  - lib/mtproto/tl/objects/server_dh_inner_data.rb
@@ -217,8 +226,10 @@ files:
217
226
  - lib/mtproto/tl/objects/updates.rb
218
227
  - lib/mtproto/tl/objects/updates_difference.rb
219
228
  - lib/mtproto/tl/objects/updates_state.rb
229
+ - lib/mtproto/tl/objects/upload_media.rb
220
230
  - lib/mtproto/tl/objects/upload_profile_photo.rb
221
231
  - lib/mtproto/tl/objects/users.rb
232
+ - lib/mtproto/tl/peers.rb
222
233
  - lib/mtproto/tl/reader.rb
223
234
  - lib/mtproto/tl/schema.rb
224
235
  - lib/mtproto/transport/abridged_packet_codec.rb