simplify ITLFunction<X> into ITLFunction

This commit is contained in:
Wizou 2021-08-12 12:37:56 +02:00
parent 83c0991770
commit 5e6421d76e
4 changed files with 31 additions and 31 deletions

View file

@ -27,7 +27,7 @@ namespace WTelegram
private TcpClient _tcpClient; private TcpClient _tcpClient;
private NetworkStream _networkStream; private NetworkStream _networkStream;
private int _frame_seqTx = 0, _frame_seqRx = 0; private int _frame_seqTx = 0, _frame_seqRx = 0;
private ITLFunction<object> _lastSentMsg; private ITLFunction _lastSentMsg;
private Type _lastRpcResultType = typeof(object); private Type _lastRpcResultType = typeof(object);
private readonly List<long> _msgsToAck = new(); private readonly List<long> _msgsToAck = new();
private int _unexpectedSaltChange; private int _unexpectedSaltChange;
@ -96,8 +96,8 @@ namespace WTelegram
if (_session.AuthKey == null) if (_session.AuthKey == null)
await CreateAuthorizationKey(this, _session); await CreateAuthorizationKey(this, _session);
TLConfig = await InvokeWithLayer(Schema.Layer, TLConfig = await InvokeWithLayer<Config>(Schema.Layer,
InitConnection<Config>(_apiId, InitConnection(_apiId,
Config("device_model"), Config("device_model"),
Config("system_version"), Config("system_version"),
Config("app_version"), Config("app_version"),
@ -140,13 +140,13 @@ namespace WTelegram
} }
public Task SendAsync(ITLObject msg, bool isContent = true) public Task SendAsync(ITLObject msg, bool isContent = true)
=> SendAsync<object>(writer => => SendAsync(writer =>
{ {
writer.WriteTLObject(msg); writer.WriteTLObject(msg);
return msg.GetType().Name; return msg.GetType().Name;
}, isContent); }, isContent);
public async Task SendAsync<X>(ITLFunction<X> msgSerializer, bool isContent = true) public async Task SendAsync(ITLFunction msgSerializer, bool isContent = true)
{ {
if (_session.AuthKeyID != 0) await CheckMsgsToAck(); if (_session.AuthKeyID != 0) await CheckMsgsToAck();
using var memStream = new MemoryStream(1024); using var memStream = new MemoryStream(1024);
@ -215,7 +215,7 @@ namespace WTelegram
//TODO: support Transport obfuscation? //TODO: support Transport obfuscation?
await _networkStream.WriteAsync(frame); await _networkStream.WriteAsync(frame);
_lastSentMsg = writer => msgSerializer(writer); _lastSentMsg = msgSerializer;
} }
internal async Task<ITLObject> RecvInternalAsync() internal async Task<ITLObject> RecvInternalAsync()
@ -239,8 +239,9 @@ namespace WTelegram
int length = reader.ReadInt32(); int length = reader.ReadInt32();
if (length != data.Length - 20) throw new ApplicationException($"Unexpected unencrypted length {length} != {data.Length - 20}"); if (length != data.Length - 20) throw new ApplicationException($"Unexpected unencrypted length {length} != {data.Length - 20}");
return reader.ReadTLObject((type, _) => var obj = reader.ReadTLObject();
Helpers.Log(1, $"Receiving {type.Name,-50} timestamp={_session.MsgIdToStamp(msgId)} isResponse={(msgId & 2) != 0} unencrypted")); Helpers.Log(1, $"Receiving {obj.GetType().Name,-50} timestamp={_session.MsgIdToStamp(msgId)} isResponse={(msgId & 2) != 0} unencrypted");
return obj;
} }
else if (authKeyId != _session.AuthKeyID) else if (authKeyId != _session.AuthKeyID)
throw new ApplicationException($"Received a packet encrypted with unexpected key {authKeyId:X}"); throw new ApplicationException($"Received a packet encrypted with unexpected key {authKeyId:X}");
@ -282,13 +283,12 @@ namespace WTelegram
if (!data.AsSpan(8, 16).SequenceEqual(_sha256.Hash.AsSpan(8, 16))) if (!data.AsSpan(8, 16).SequenceEqual(_sha256.Hash.AsSpan(8, 16)))
throw new ApplicationException($"Mismatch between MsgKey & decrypted SHA1"); throw new ApplicationException($"Mismatch between MsgKey & decrypted SHA1");
#endif #endif
return reader.ReadTLObject((type, obj) => var obj = reader.ReadTLObject(type => type == typeof(RpcResult));
{ if (obj is RpcResult rpcResult)
Helpers.Log(1, $"Receiving {type.Name,-50} timestamp={_session.MsgIdToStamp(msgId)} isResponse={(msgId & 2) != 0} {(seqno == -1 ? "clearText" : "isContent")}={(seqno & 1) != 0}"); DeserializeRpcResult(reader, rpcResult); // necessary hack because some RPC return bare types like bool or int[]
if (type == typeof(RpcResult)) Helpers.Log(1, $"Receiving {obj.GetType().Name,-50} timestamp={_session.MsgIdToStamp(msgId)} isResponse={(msgId & 2) != 0} {(seqno == -1 ? "clearText" : "isContent")}={(seqno & 1) != 0}");
DeserializeRpcResult(reader, (RpcResult)obj); // necessary hack because some RPC return bare types like bool or int[] return obj;
}); }
}
static string TransportError(int error_code) => error_code switch static string TransportError(int error_code) => error_code switch
{ {
@ -350,7 +350,7 @@ namespace WTelegram
public RpcException(int code, string message) : base(message) => Code = code; public RpcException(int code, string message) : base(message) => Code = code;
} }
public async Task<X> CallAsync<X>(ITLFunction<X> request) public async Task<X> CallAsync<X>(ITLFunction request)
{ {
await SendAsync(request); await SendAsync(request);
// TODO: create a background reactor system that handles incoming packets and wake up awaiting tasks when their result has arrived // TODO: create a background reactor system that handles incoming packets and wake up awaiting tasks when their result has arrived

View file

@ -156,7 +156,7 @@ namespace WTelegram
{ {
var parentClass = typeInfo.NeedAbstract != 0 ? typeInfo.ReturnName : "ITLObject"; var parentClass = typeInfo.NeedAbstract != 0 ? typeInfo.ReturnName : "ITLObject";
var genericType = typeInfo.ReturnName.Length == 1 ? $"<{typeInfo.ReturnName}>" : null; var genericType = typeInfo.ReturnName.Length == 1 ? $"<{typeInfo.ReturnName}>" : null;
if (isMethod) parentClass = $"ITLFunction<{MapType(typeInfo.ReturnName, "")}>"; if (isMethod) parentClass = "ITLFunction";
bool needNewLine = true; bool needNewLine = true;
if (typeInfo.NeedAbstract == -1 && allTypes.Add(layerPrefix + parentClass)) if (typeInfo.NeedAbstract == -1 && allTypes.Add(layerPrefix + parentClass))
{ {
@ -293,7 +293,7 @@ namespace WTelegram
else if (type == "Object") else if (type == "Object")
return "ITLObject"; return "ITLObject";
else if (type == "!X") else if (type == "!X")
return "ITLFunction<X>"; return "ITLFunction";
else if (typeInfos.TryGetValue(type, out var typeInfo)) else if (typeInfos.TryGetValue(type, out var typeInfo))
return typeInfo.ReturnName; return typeInfo.ReturnName;
else if (type == "int") else if (type == "int")
@ -345,7 +345,7 @@ namespace WTelegram
if (style == -1) return; if (style == -1) return;
sw.WriteLine(); sw.WriteLine();
if (method.type.Length == 1) funcName += $"<{returnType}>"; if (method.type.Length == 1 && style != 1) funcName += $"<{returnType}>";
if (currentJson != "TL.MTProto") if (currentJson != "TL.MTProto")
sw.WriteLine($"{tabIndent}///<summary>See <a href=\"https://core.telegram.org/method/{method.method}\"/></summary>"); sw.WriteLine($"{tabIndent}///<summary>See <a href=\"https://core.telegram.org/method/{method.method}\"/></summary>");
else else
@ -358,7 +358,7 @@ namespace WTelegram
if (style == 0) sw.WriteLine($"{tabIndent}public Task<{returnType}> {funcName}() => CallAsync<{returnType}>({funcName});"); if (style == 0) sw.WriteLine($"{tabIndent}public Task<{returnType}> {funcName}() => CallAsync<{returnType}>({funcName});");
if (style == 0) sw.Write($"{tabIndent}public static string {funcName}(BinaryWriter writer"); if (style == 0) sw.Write($"{tabIndent}public static string {funcName}(BinaryWriter writer");
if (style == 1) sw.Write($"{tabIndent}public static ITLFunction<{returnType}> {funcName}("); if (style == 1) sw.Write($"{tabIndent}public static ITLFunction {funcName}(");
if (style == 2) sw.Write($"{tabIndent}public Task<{returnType}> {funcName}("); if (style == 2) sw.Write($"{tabIndent}public Task<{returnType}> {funcName}(");
bool first = style != 0; bool first = style != 0;
foreach (var parm in method.@params) // output non-optional parameters foreach (var parm in method.@params) // output non-optional parameters

View file

@ -6209,7 +6209,7 @@ namespace WTelegram // ---functions---
public partial class Client public partial class Client
{ {
///<summary>See <a href="https://core.telegram.org/method/invokeAfterMsg"/></summary> ///<summary>See <a href="https://core.telegram.org/method/invokeAfterMsg"/></summary>
public Task<X> InvokeAfterMsg<X>(long msg_id, ITLFunction<X> query) public Task<X> InvokeAfterMsg<X>(long msg_id, ITLFunction query)
=> CallAsync<X>(writer => => CallAsync<X>(writer =>
{ {
writer.Write(0xCB9F372D); writer.Write(0xCB9F372D);
@ -6219,7 +6219,7 @@ namespace WTelegram // ---functions---
}); });
///<summary>See <a href="https://core.telegram.org/method/invokeAfterMsgs"/></summary> ///<summary>See <a href="https://core.telegram.org/method/invokeAfterMsgs"/></summary>
public Task<X> InvokeAfterMsgs<X>(long[] msg_ids, ITLFunction<X> query) public Task<X> InvokeAfterMsgs<X>(long[] msg_ids, ITLFunction query)
=> CallAsync<X>(writer => => CallAsync<X>(writer =>
{ {
writer.Write(0x3DC4B4F0); writer.Write(0x3DC4B4F0);
@ -7027,7 +7027,7 @@ namespace WTelegram // ---functions---
}); });
///<summary>See <a href="https://core.telegram.org/method/initConnection"/></summary> ///<summary>See <a href="https://core.telegram.org/method/initConnection"/></summary>
public static ITLFunction<X> InitConnection<X>(int api_id, string device_model, string system_version, string app_version, string system_lang_code, string lang_pack, string lang_code, ITLFunction<X> query, InputClientProxy proxy = null, JSONValue params_ = null) public static ITLFunction InitConnection(int api_id, string device_model, string system_version, string app_version, string system_lang_code, string lang_pack, string lang_code, ITLFunction query, InputClientProxy proxy = null, JSONValue params_ = null)
=> writer => => writer =>
{ {
writer.Write(0xC1CD5EA9); writer.Write(0xC1CD5EA9);
@ -7044,7 +7044,7 @@ namespace WTelegram // ---functions---
if (params_ != null) if (params_ != null)
writer.WriteTLObject(params_); writer.WriteTLObject(params_);
query(writer); query(writer);
return "InitConnection<X>"; return "InitConnection";
}; };
///<summary>See <a href="https://core.telegram.org/method/help.getSupport"/></summary> ///<summary>See <a href="https://core.telegram.org/method/help.getSupport"/></summary>
@ -7138,7 +7138,7 @@ namespace WTelegram // ---functions---
}); });
///<summary>See <a href="https://core.telegram.org/method/invokeWithLayer"/></summary> ///<summary>See <a href="https://core.telegram.org/method/invokeWithLayer"/></summary>
public Task<X> InvokeWithLayer<X>(int layer, ITLFunction<X> query) public Task<X> InvokeWithLayer<X>(int layer, ITLFunction query)
=> CallAsync<X>(writer => => CallAsync<X>(writer =>
{ {
writer.Write(0xDA9B0D0D); writer.Write(0xDA9B0D0D);
@ -7300,7 +7300,7 @@ namespace WTelegram // ---functions---
}); });
///<summary>See <a href="https://core.telegram.org/method/invokeWithoutUpdates"/></summary> ///<summary>See <a href="https://core.telegram.org/method/invokeWithoutUpdates"/></summary>
public Task<X> InvokeWithoutUpdates<X>(ITLFunction<X> query) public Task<X> InvokeWithoutUpdates<X>(ITLFunction query)
=> CallAsync<X>(writer => => CallAsync<X>(writer =>
{ {
writer.Write(0xBF9459B7); writer.Write(0xBF9459B7);
@ -8889,7 +8889,7 @@ namespace WTelegram // ---functions---
}); });
///<summary>See <a href="https://core.telegram.org/method/invokeWithMessagesRange"/></summary> ///<summary>See <a href="https://core.telegram.org/method/invokeWithMessagesRange"/></summary>
public Task<X> InvokeWithMessagesRange<X>(MessageRange range, ITLFunction<X> query) public Task<X> InvokeWithMessagesRange<X>(MessageRange range, ITLFunction query)
=> CallAsync<X>(writer => => CallAsync<X>(writer =>
{ {
writer.Write(0x365275F2); writer.Write(0x365275F2);
@ -8899,7 +8899,7 @@ namespace WTelegram // ---functions---
}); });
///<summary>See <a href="https://core.telegram.org/method/invokeWithTakeout"/></summary> ///<summary>See <a href="https://core.telegram.org/method/invokeWithTakeout"/></summary>
public Task<X> InvokeWithTakeout<X>(long takeout_id, ITLFunction<X> query) public Task<X> InvokeWithTakeout<X>(long takeout_id, ITLFunction query)
=> CallAsync<X>(writer => => CallAsync<X>(writer =>
{ {
writer.Write(0xACA9FD2E); writer.Write(0xACA9FD2E);

View file

@ -11,7 +11,7 @@ using WTelegram;
namespace TL namespace TL
{ {
public interface ITLObject { } public interface ITLObject { }
public delegate string ITLFunction<out X>(BinaryWriter writer); public delegate string ITLFunction(BinaryWriter writer);
public static partial class Schema public static partial class Schema
{ {
@ -51,14 +51,14 @@ namespace TL
} }
} }
internal static ITLObject ReadTLObject(this BinaryReader reader, Action<Type, object> notifyType = null) internal static ITLObject ReadTLObject(this BinaryReader reader, Func<Type, bool> customRead = null)
{ {
var ctorNb = reader.ReadUInt32(); var ctorNb = reader.ReadUInt32();
if (ctorNb == NullCtor) return null; if (ctorNb == NullCtor) return null;
if (!Table.TryGetValue(ctorNb, out var type)) if (!Table.TryGetValue(ctorNb, out var type))
throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}"); throw new ApplicationException($"Cannot find type for ctor #{ctorNb:x}");
var obj = Activator.CreateInstance(type); var obj = Activator.CreateInstance(type);
notifyType?.Invoke(type, obj); if (customRead?.Invoke(type) == true) return (ITLObject)obj;
var fields = obj.GetType().GetFields().GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g); var fields = obj.GetType().GetFields().GroupBy(f => f.DeclaringType).Reverse().SelectMany(g => g);
int flags = 0; int flags = 0;
IfFlagAttribute ifFlag; IfFlagAttribute ifFlag;