mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2026-01-04 15:50:01 +01:00
Experimental collection of id/access_hash pairs
This commit is contained in:
parent
0d5546bee5
commit
4174b21a83
|
|
@ -307,7 +307,7 @@ namespace WTelegram
|
|||
throw new ApplicationException($"Received a packet encrypted with unexpected key {authKeyId:X}");
|
||||
if (authKeyId == 0) // Unencrypted message
|
||||
{
|
||||
using var reader = new BinaryReader(new MemoryStream(data, 8, data.Length - 8));
|
||||
using var reader = new TL.BinaryReader(new MemoryStream(data, 8, data.Length - 8), this);
|
||||
long msgId = _lastRecvMsgId = reader.ReadInt64();
|
||||
if ((msgId & 1) == 0) throw new ApplicationException($"Invalid server msgId {msgId}");
|
||||
int length = reader.ReadInt32();
|
||||
|
|
@ -327,7 +327,7 @@ namespace WTelegram
|
|||
byte[] decrypted_data = EncryptDecryptMessage(data.AsSpan(24), false, _session.AuthKey, msgKeyLarge);
|
||||
if (decrypted_data.Length < 36) // header below+ctorNb
|
||||
throw new ApplicationException($"Decrypted packet too small: {decrypted_data.Length}");
|
||||
using var reader = new BinaryReader(new MemoryStream(decrypted_data));
|
||||
using var reader = new TL.BinaryReader(new MemoryStream(decrypted_data), this);
|
||||
var serverSalt = reader.ReadInt64(); // int64 salt
|
||||
var sessionId = reader.ReadInt64(); // int64 session_id
|
||||
var msgId = _lastRecvMsgId = reader.ReadInt64();// int64 message_id
|
||||
|
|
@ -385,7 +385,7 @@ namespace WTelegram
|
|||
};
|
||||
}
|
||||
|
||||
internal MsgContainer ReadMsgContainer(BinaryReader reader)
|
||||
internal MsgContainer ReadMsgContainer(TL.BinaryReader reader)
|
||||
{
|
||||
int count = reader.ReadInt32();
|
||||
var array = new _Message[count];
|
||||
|
|
@ -422,7 +422,7 @@ namespace WTelegram
|
|||
return new MsgContainer { messages = array };
|
||||
}
|
||||
|
||||
private RpcResult ReadRpcResult(BinaryReader reader)
|
||||
private RpcResult ReadRpcResult(TL.BinaryReader reader)
|
||||
{
|
||||
long msgId = reader.ReadInt64();
|
||||
var (type, tcs) = PullPendingRequest(msgId);
|
||||
|
|
@ -838,5 +838,34 @@ namespace WTelegram
|
|||
reply_to_msg_id: reply_to_msg_id, entities: entities, schedule_date: schedule_date);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>Enable the collection of id/access_hash pairs (experimental)</summary>
|
||||
public bool CollectAccessHash { get; set; }
|
||||
readonly Dictionary<Type, Dictionary<long, long>> _accessHashes = new();
|
||||
public IEnumerable<KeyValuePair<long, long>> AllAccessHashesFor<T>() where T : ITLObject
|
||||
=> _accessHashes.GetValueOrDefault(typeof(T));
|
||||
/// <summary>Retrieve the access_hash associated with this id (for a TL class)</summary>
|
||||
/// <typeparam name="T">a TL object class. For example User, Channel or Photo</typeparam>
|
||||
public long? GetAccessHashFor<T>(long id) where T : ITLObject
|
||||
{
|
||||
lock (_accessHashes)
|
||||
return _accessHashes.GetOrCreate(typeof(T)).TryGetValue(id, out var access_hash) ? access_hash : null;
|
||||
}
|
||||
public void SetAccessHashFor<T>(long id, long access_hash) where T : ITLObject
|
||||
{
|
||||
lock (_accessHashes)
|
||||
_accessHashes.GetOrCreate(typeof(T))[id] = access_hash;
|
||||
}
|
||||
internal void UpdateAccessHash(object obj, Type type, object access_hash)
|
||||
{
|
||||
if (!CollectAccessHash) return;
|
||||
if (access_hash is not long accessHash) return;
|
||||
if (type.GetField("id") is not FieldInfo idField) return;
|
||||
if (idField.GetValue(obj) is not long id)
|
||||
if (idField.GetValue(obj) is not int idInt) return;
|
||||
else id = idInt;
|
||||
lock (_accessHashes)
|
||||
_accessHashes.GetOrCreate(type)[id] = accessHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ namespace WTelegram
|
|||
var (tmp_aes_key, tmp_aes_iv) = ConstructTmpAESKeyIV(resPQ.server_nonce, pqInnerData.new_nonce);
|
||||
var answer = AES_IGE_EncryptDecrypt(serverDHparamsOk.encrypted_answer, tmp_aes_key, tmp_aes_iv, false);
|
||||
|
||||
using var encryptedReader = new BinaryReader(new MemoryStream(answer));
|
||||
using var encryptedReader = new TL.BinaryReader(new MemoryStream(answer), client);
|
||||
var answerHash = encryptedReader.ReadBytes(20);
|
||||
var answerObj = encryptedReader.ReadTLObject();
|
||||
if (answerObj is not ServerDHInnerData serverDHinnerData) throw new ApplicationException("not server_DH_inner_data");
|
||||
|
|
|
|||
19
src/TL.cs
19
src/TL.cs
|
|
@ -24,7 +24,7 @@ namespace TL
|
|||
internal static T Deserialize<T>(byte[] bytes) where T : ITLObject
|
||||
{
|
||||
using var memStream = new MemoryStream(bytes);
|
||||
using var reader = new BinaryReader(memStream);
|
||||
using var reader = new BinaryReader(memStream, null);
|
||||
return (T)reader.ReadTLObject();
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ namespace TL
|
|||
if (!Table.TryGetValue(ctorNb, out var type))
|
||||
throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}");
|
||||
var obj = Activator.CreateInstance(type);
|
||||
var fields = obj.GetType().GetFields().GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g);
|
||||
var fields = type.GetFields().GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g);
|
||||
int flags = 0;
|
||||
IfFlagAttribute ifFlag;
|
||||
foreach (var field in fields)
|
||||
|
|
@ -64,9 +64,10 @@ namespace TL
|
|||
if (((ifFlag = field.GetCustomAttribute<IfFlagAttribute>()) != null) && (flags & (1 << ifFlag.Bit)) == 0) continue;
|
||||
object value = reader.ReadTLValue(field.FieldType);
|
||||
field.SetValue(obj, value);
|
||||
if (field.Name.Equals("Flags", StringComparison.OrdinalIgnoreCase)) flags = (int)value;
|
||||
if (field.Name == "flags") flags = (int)value;
|
||||
else if (field.Name == "access_hash") reader.Client?.UpdateAccessHash(obj, type, value);
|
||||
}
|
||||
return type == typeof(GzipPacked) ? UnzipPacket((GzipPacked)obj) : (ITLObject)obj;
|
||||
return type == typeof(GzipPacked) ? UnzipPacket((GzipPacked)obj, reader.Client) : (ITLObject)obj;
|
||||
}
|
||||
|
||||
internal static void WriteTLValue(this BinaryWriter writer, object value)
|
||||
|
|
@ -220,9 +221,9 @@ namespace TL
|
|||
writer.Write(0); // null arrays are serialized as empty
|
||||
}
|
||||
|
||||
internal static ITLObject UnzipPacket(GzipPacked obj)
|
||||
internal static ITLObject UnzipPacket(GzipPacked obj, WTelegram.Client client)
|
||||
{
|
||||
using var reader = new BinaryReader(new GZipStream(new MemoryStream(obj.packed_data), CompressionMode.Decompress));
|
||||
using var reader = new BinaryReader(new GZipStream(new MemoryStream(obj.packed_data), CompressionMode.Decompress), client);
|
||||
var result = reader.ReadTLObject();
|
||||
return result;
|
||||
}
|
||||
|
|
@ -234,6 +235,12 @@ namespace TL
|
|||
#endif
|
||||
}
|
||||
|
||||
public class BinaryReader : System.IO.BinaryReader
|
||||
{
|
||||
public readonly WTelegram.Client Client;
|
||||
public BinaryReader(Stream stream, WTelegram.Client client) : base(stream) => Client = client;
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class TLDefAttribute : Attribute
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue