257 lines
7.5 KiB
JavaScript
257 lines
7.5 KiB
JavaScript
const utils = require('../Utils')
|
|
const types = require('../tl').constructors
|
|
const Session = require('./Abstract')
|
|
|
|
class MemorySession extends Session {
|
|
constructor() {
|
|
super()
|
|
|
|
this._serverAddress = null
|
|
this._dcId = 0
|
|
this._port = null
|
|
this._takeoutId = null
|
|
|
|
this._entities = new Set()
|
|
this._updateStates = {}
|
|
}
|
|
|
|
setDC(dcId, serverAddress, port) {
|
|
this._dcId = dcId | 0
|
|
this._serverAddress = serverAddress
|
|
this._port = port
|
|
}
|
|
|
|
get dcId() {
|
|
return this._dcId
|
|
}
|
|
|
|
get serverAddress() {
|
|
return this._serverAddress
|
|
}
|
|
|
|
get port() {
|
|
return this._port
|
|
}
|
|
|
|
get authKey() {
|
|
return this._authKey
|
|
}
|
|
|
|
set authKey(value) {
|
|
this._authKey = value
|
|
}
|
|
/* CONTEST
|
|
get takeoutId() {
|
|
return this._takeoutId
|
|
}
|
|
|
|
set takeoutId(value) {
|
|
this._takeoutId = value
|
|
}
|
|
|
|
|
|
getUpdateState(entityId) {
|
|
return this._updateStates[entityId]
|
|
}
|
|
|
|
setUpdateState(entityId, state) {
|
|
return this._updateStates[entityId] = state
|
|
}
|
|
|
|
close() {
|
|
}
|
|
|
|
save() {
|
|
}
|
|
|
|
async load() {
|
|
|
|
}
|
|
|
|
delete() {
|
|
}
|
|
|
|
_entityValuesToRow(id, hash, username, phone, name) {
|
|
// While this is a simple implementation it might be overrode by,
|
|
// other classes so they don't need to implement the plural form
|
|
// of the method. Don't remove.
|
|
return [id, hash, username, phone, name]
|
|
}
|
|
|
|
_entityToRow(e) {
|
|
if (!(e.classType === "constructor")) {
|
|
return
|
|
}
|
|
let p
|
|
let markedId
|
|
try {
|
|
p = utils.getInputPeer(e, false)
|
|
markedId = utils.getPeerId(p)
|
|
} catch (e) {
|
|
// Note: `get_input_peer` already checks for non-zero `accessHash`.
|
|
// See issues #354 and #392. It also checks that the entity
|
|
// is not `min`, because its `accessHash` cannot be used
|
|
// anywhere (since layer 102, there are two access hashes).
|
|
return
|
|
}
|
|
let pHash
|
|
if (p instanceof types.InputPeerUser || p instanceof types.InputPeerChannel) {
|
|
pHash = p.accessHash
|
|
} else if (p instanceof types.InputPeerChat) {
|
|
pHash = 0
|
|
} else {
|
|
return
|
|
}
|
|
|
|
let username = e.username
|
|
if (username) {
|
|
username = username.toLowerCase()
|
|
}
|
|
const phone = e.phone
|
|
const name = utils.getDisplayName(e)
|
|
return this._entityValuesToRow(markedId, pHash, username, phone, name)
|
|
}
|
|
|
|
_entitiesToRows(tlo) {
|
|
let entities = []
|
|
if (tlo.classType === "constructor" && utils.isListLike(tlo)) {
|
|
// This may be a list of users already for instance
|
|
entities = tlo
|
|
} else {
|
|
if (tlo instanceof Object) {
|
|
if ('user' in tlo) {
|
|
entities.push(tlo.user)
|
|
}
|
|
if ('chats' in tlo && utils.isListLike(tlo.chats)) {
|
|
entities.concat(tlo.chats)
|
|
}
|
|
if ('users' in tlo && utils.isListLike(tlo.users)) {
|
|
entities.concat(tlo.users)
|
|
}
|
|
}
|
|
}
|
|
const rows = [] // Rows to add (id, hash, username, phone, name)
|
|
for (const e of entities) {
|
|
const row = this._entityToRow(e)
|
|
if (row) {
|
|
rows.push(row)
|
|
}
|
|
}
|
|
return rows
|
|
}
|
|
|
|
processEntities(tlo) {
|
|
const entitiesSet = this._entitiesToRows(tlo)
|
|
for (const e of entitiesSet) {
|
|
this._entities.add(e)
|
|
}
|
|
}
|
|
|
|
getEntityRowsByPhone(phone) {
|
|
for (const e of this._entities) { // id, hash, username, phone, name
|
|
if (e[3] === phone) {
|
|
return [e[0], e[1]]
|
|
}
|
|
}
|
|
}
|
|
|
|
getEntityRowsByUsername(username) {
|
|
for (const e of this._entities) { // id, hash, username, phone, name
|
|
if (e[2] === username) {
|
|
return [e[0], e[1]]
|
|
}
|
|
}
|
|
}
|
|
|
|
getEntityRowsByName(name) {
|
|
for (const e of this._entities) { // id, hash, username, phone, name
|
|
if (e[4] === name) {
|
|
return [e[0], e[1]]
|
|
}
|
|
}
|
|
}
|
|
|
|
getEntityRowsById(id, exact = true) {
|
|
if (exact) {
|
|
for (const e of this._entities) { // id, hash, username, phone, name
|
|
if (e[0] === id) {
|
|
return [e[0], e[1]]
|
|
}
|
|
}
|
|
} else {
|
|
const ids = [utils.getPeerId(new types.PeerUser({ userId: id })),
|
|
utils.getPeerId(new types.PeerChat({ chatId: id })),
|
|
utils.getPeerId(new types.PeerChannel({ channelId: id })),
|
|
]
|
|
for (const e of this._entities) { // id, hash, username, phone, name
|
|
if (ids.includes(e[0])) {
|
|
return [e[0], e[1]]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
getInputEntity(key) {
|
|
let exact
|
|
if (key.SUBCLASS_OF_ID !== undefined) {
|
|
if ([0xc91c90b6, 0xe669bf46, 0x40f202fd].includes(key.SUBCLASS_OF_ID)) {
|
|
// hex(crc32(b'InputPeer', b'InputUser' and b'InputChannel'))
|
|
// We already have an Input version, so nothing else required
|
|
return key
|
|
}
|
|
// Try to early return if this key can be casted as input peer
|
|
return utils.getInputPeer(key)
|
|
} else {
|
|
// Not a TLObject or can't be cast into InputPeer
|
|
if (key.classType === 'constructor') {
|
|
key = utils.getPeerId(key)
|
|
exact = true
|
|
} else {
|
|
exact = !(typeof key == 'number') || key < 0
|
|
}
|
|
}
|
|
let result = null
|
|
if (typeof key === 'string') {
|
|
const phone = utils.parsePhone(key)
|
|
if (phone) {
|
|
result = this.getEntityRowsByPhone(phone)
|
|
} else {
|
|
const { username, isInvite } = utils.parseUsername(key)
|
|
if (username && !isInvite) {
|
|
result = this.getEntityRowsByUsername(username)
|
|
} else {
|
|
const tup = utils.resolveInviteLink(key)[1]
|
|
if (tup) {
|
|
result = this.getEntityRowsById(tup, false)
|
|
}
|
|
}
|
|
}
|
|
} else if (typeof key === 'number') {
|
|
result = this.getEntityRowsById(key, exact)
|
|
}
|
|
if (!result && typeof key === 'string') {
|
|
result = this.getEntityRowsByName(key)
|
|
}
|
|
|
|
if (result) {
|
|
let entityId = result[0] // unpack resulting tuple
|
|
const entityHash = result[1]
|
|
const resolved = utils.resolveId(entityId)
|
|
entityId = resolved[0]
|
|
const kind = resolved[1]
|
|
// removes the mark and returns type of entity
|
|
if (kind === types.PeerUser) {
|
|
return new types.InputPeerUser({ userId: entityId, accessHash: entityHash })
|
|
} else if (kind === types.PeerChat) {
|
|
return new types.InputPeerChat({ chatId: entityId })
|
|
} else if (kind === types.PeerChannel) {
|
|
return new types.InputPeerChannel({ channelId: entityId, accessHash: entityHash })
|
|
}
|
|
} else {
|
|
throw new Error('Could not find input entity with key ' + key)
|
|
}
|
|
}*/
|
|
}
|
|
|
|
module.exports = MemorySession
|