mtprotoPlainSender.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. const helpers = require("../utils/Helpers").helpers;
  2. /**
  3. * MTProto Mobile Protocol plain sender (https://core.telegram.org/mtproto/description#unencrypted-messages)
  4. */
  5. class MtProtoPlainSender {
  6. constructor(transport) {
  7. this._sequence = 0;
  8. this._timeOffset = 0;
  9. this._lastMsgId = 0;
  10. this._transport = transport;
  11. }
  12. /**
  13. * Sends a plain packet (auth_key_id = 0) containing the given message body (data)
  14. * @param data
  15. */
  16. send(data) {
  17. let packet = Buffer.alloc(8, 0);
  18. packet.writeBigInt64LE(this.getNewMsgId(), packet.byteLength);
  19. packet.writeInt32LE(data.length, packet.byteLength);
  20. packet.write(data, packet.byteLength);
  21. this._transport.send(packet);
  22. }
  23. /**
  24. * Receives a plain packet, returning the body of the response
  25. * @returns {Buffer}
  26. */
  27. receive() {
  28. let {seq, body} = this._transport.receive();
  29. let message_length = body.readInt32LE(16);
  30. return body.slice(20, message_length);
  31. }
  32. /**
  33. * Generates a new message ID based on the current time (in ms) since epoch
  34. * @returns {BigInt}
  35. */
  36. getNewMsgId() {
  37. //See https://core.telegram.org/mtproto/description#message-identifier-msg-id
  38. let msTime = Date.now();
  39. let newMsgId = ((BigInt(Math.floor(msTime / 1000)) << BigInt(32)) | // "must approximately equal unixtime*2^32"
  40. (BigInt(msTime % 1000) << BigInt(32)) | // "approximate moment in time the message was created"
  41. BigInt(helpers.getRandomInt(0, 524288)) << BigInt(2));// "message identifiers are divisible by 4"
  42. //Ensure that we always return a message ID which is higher than the previous one
  43. if (this._lastMsgId >= newMsgId) {
  44. newMsgId = this._lastMsgId + 4
  45. }
  46. this._lastMsgId = newMsgId;
  47. return BigInt(newMsgId);
  48. }
  49. }
  50. exports.MtProtoPlainSender = MtProtoPlainSender;