old_flsystem/类库/Chat.Framework/WXSdk/IPAD/WechatPack.cs

373 lines
14 KiB
C#
Raw Normal View History

2022-09-20 03:10:29 +00:00
using Chat.Framework.WXSdk.Implement;
using Google.Protobuf;
using System;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using WechatProto;
using System.Linq;
using System.Text.RegularExpressions;
using Chat.Framework.WXSdk.Events;
using Grpc.Core;
namespace Chat.Framework.WXSdk.IPAD
{
/// <summary>
/// 协议发送包
/// </summary>
public class WechatPack
{
public class PackMsg
{
//(WechatCmd cmd, bool isAnalysis, object data = null, ByteString longHead = null,string text=""
public WechatCmd cmd { get; set; }
public object data { get; set; }
}
WXClientImpl_IPAD client;
JavaScriptSerializer js = new JavaScriptSerializer();
public WechatPack(WXClientImpl_IPAD client)
{
this.client = client;
this.js.MaxJsonLength = int.MaxValue;
}
public WechatMsg Req { get; private set; }
private int ReadInt(byte[] buf, int index)
{
if (buf.Length >= 16)
{
var seqBuf = new byte[4];
Buffer.BlockCopy(buf, index, seqBuf, 0, 4);
return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(seqBuf, 0));
}
return 1;
}
public byte[] Analysis(int cmd, byte[] data)
{
return Send(cmd > 0 ? cmd * -1 : cmd, data);
}
public byte[] Analysis(WechatCmd cmd, object data)
{
return Send((int)cmd * -1, data);
}
public byte[] Analysis(byte[] data)
{
int cmd = Req.BaseMsg.Cmd * -1;
return Send(cmd, data);
}
/// <summary>
/// 发送完整包,并解析微信返回信息
/// </summary>
public byte[] SendAll(WechatCmd cmd, bool isAnalysis, object data = null, ByteString longHead = null, string text = "")
{
var _data = Send(cmd, data, longHead);
if (_data != null && !IsShortResult)//判断数据不为空,并且不是腾讯短连接返回的结果
{
_data = SendWx(_data, text: text);
}
if (isAnalysis)
{
if (_data == null) return null;
return this.Analysis(_data);
}
return _data;
}
private bool IsShortResult { get; set; }
public byte[] Send(WechatCmd cmd, object data = null, ByteString longHead = null)
{
return Send((int)cmd, data, longHead);
}
public byte[] Send(WechatCmd cmd, byte[] data, ByteString longHead = null)
{
return Send((int)cmd, data, longHead);
}
// GrpcClient grpcClient = null;
private GrpcClient GetGrpcClient(WechatMsg req)
{
//if (grpcClient != null && grpcClient.IsConnected) return grpcClient;
GrpcClient grpcClient = null;
if (codes.Contains(req.BaseMsg.Cmd))
{
grpcClient = client.GetGrpcClient(GrpcType.Huangfan);
//grpcClient = new GrpcClient(GrpcConfig.Get(GrpcType.Huangfan, false)); //client.GetGrpcClient(GrpcType.Huangfan);
}
else
{
grpcClient = client.GetGrpcClient(GrpcType.Laoyao);
}
return grpcClient;
}
public byte[] Send(WechatMsg req)
{
int number = 0;
//GrpcClient grpc_client = null;
try
{
Next:
IsShortResult = false;
number++;
var msg = req.BaseMsg;
var grpc = GetGrpcClient(req);
//WechatMsg _req = SendGRPC(req, client).Result;
WechatMsg _req = grpc.Send(req, client).Result;
if (_req != null) Req = _req;
else
{
if (number < 3)
{
Thread.Sleep(100);
goto Next;
}
else throw new Exception("无法获取GRPC返回包!");
}
var Data = new byte[Req.BaseMsg.LongHead.Length + Req.BaseMsg.Payloads.Length];
var Head = Req.BaseMsg.LongHead.ToByteArray();
var Seq = ReadInt(Head, 12);
if (msg.Cmd < 0 && (int)WechatCmd. != msg.Cmd)
{
ByteString key = null;
if (Req.BaseMsg.User.AutoAuthKey.Length != 0)
{
key = Req.BaseMsg.User.AutoAuthKey;
}
else if (client.User.User.AutoAuthKey.Length != 0)
key = client.User.User.AutoAuthKey;
if (msg.Cmd == -138 || msg.Cmd == -1002 || msg.Cmd == -702 || msg.Cmd == -1001 || msg.Cmd == -380)
{
client.User.User = Req.BaseMsg.User;
}
if (key != null)
{
client.User.User.AutoAuthKey = key;
}
return Req.BaseMsg.Payloads.ToByteArray();
}
if (msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd. || msg.Cmd == 179 || msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd. || msg.Cmd == 281 || msg.Cmd == 851 || msg.Cmd == 551 || msg.Cmd == 805 || msg.Cmd == 610 || msg.Cmd == 385 || msg.Cmd == 945 || msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd. || msg.Cmd == (int)WechatCmd.)
{
IsShortResult = true;
var data = client.Socket.SendWeChatPost(Req.BaseMsg.Payloads.ToByteArray(), Req.BaseMsg.CmdUrl, 3);
//if (data == null)
//{
// return this.SendWx(data);
//}
//else
return data; //byte[] _data = null;
//CsharpHttpHelper.HttpHelper http = new CsharpHttpHelper.HttpHelper();
//for (int i = 0; i < 2; i++)
//{
// try
// {
// var item = new CsharpHttpHelper.HttpItem()
// {
// URL = "http://" + client.Host.GetSort() + Req.BaseMsg.CmdUrl,
// Method = "post",
// PostdataByte = Req.BaseMsg.Payloads.ToByteArray(),
// UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
// ContentType = "application/x-www-form-urlencoded",
// Allowautoredirect = true,
// Timeout = 5000,
// ReadWriteTimeout = 5000,
// ResultType = CsharpHttpHelper.Enum.ResultType.Byte,
// PostDataType = CsharpHttpHelper.Enum.PostDataType.Byte
// };
// _data = http.GetHtml(item).ResultByte;
// if (_data == null) continue;
// if (_data[0] != 191) continue;
// break;
// }
// catch (Exception)
// {
// }
//}
//return _data;
}
try
{
var Body = Req.BaseMsg.Payloads.ToByteArray();
Buffer.BlockCopy(Head, 0, Data, 0, 16);
Buffer.BlockCopy(Body, 0, Data, 16, Body.Length);
return Data;
}
catch (Exception ex)
{
if (number < 3)
{
Thread.Sleep(100);
goto Next;
}
else throw ex;
}
}
catch (Exception ex)
{
throw ex;
}
}
private static int[] codes = new int[] { };//1111, 2222, 702, 3333, 380
public byte[] Send(int cmd, object data, ByteString longHead = null)
{
try
{
ByteString param = null;
if (data != null)
{
if (typeof(string) == data.GetType())
{
param = ByteString.CopyFrom(Encoding.UTF8.GetBytes(data.ToString()));
}
else if (typeof(byte[]) != data.GetType())
{
var json = js.Serialize(data);
param = ByteString.CopyFrom(json, Encoding.UTF8);
}
else if (typeof(byte[]) == data.GetType())
{
var _data = data as byte[];
param = ByteString.CopyFrom(_data);
}
}
WechatProto.BaseMsg msg = null;
if (param != null)
msg = new BaseMsg() { Cmd = cmd, Payloads = param, User = client.User.User };
else
msg = new BaseMsg() { Cmd = cmd, User = client.User.User };
if (longHead != null) msg.LongHead = longHead;
Req = new WechatMsg
{
Token = WXClientTool.machine_code,
Version = "7.0.3",
TimeStamp = Util.GetTimeTotalSeconds(),
IP = client.clientIp,
BaseMsg = msg
};
return Send(Req);
}
catch (Exception ex)
{
LogHelper.GetSingleObj().Error("发送GRPC-" + cmd, ex.Message);
}
return null;
}
public byte[] GetResult(int seq)
{
var buffers = this.client.Socket.GetResult(seq);
var start = DateTime.Now;
while (buffers == null)
{
Thread.Sleep(20);
buffers = this.client.Socket.GetResult(seq);
if (null == buffers && (DateTime.Now - start).Seconds > 10)//发送文字超时时间设置成40s
{
break;
}
}
return buffers;
}
public byte[] SendWx(byte[] Data, int Seq = 0, int retry_number = 1, string text = "")
{
if (Seq == 0)
{
byte[] head = Data;
Seq = Util.ReadInt(head, 12);
}
//执行此方法无须解包 必须删除字典里的未解包
// this.client.Socket.SendToWeChat(Seq,Data).Result;
for (int i = 1; i <= retry_number; i++)
{
this.client.Socket.SendToWechat(Data, text);
//if (!string.IsNullOrEmpty(rst))
//{
// this.client.WriteLog("发送失败:" + rst);
// continue;
//}
var buffer = GetResult(Seq);
if (buffer != null) return buffer;
}
LogHelper.GetSingleObj().Error("SendWx", $"{(string.IsNullOrEmpty(this.client.WeixinHao) ? string.Empty : this.client.WeixinHao)}执行{Seq},数据包发送失败!");
return null;
//FastSocket 重构
//return client.Socket.SendToWeChat(Seq, Data);
// int number = 0;
//Next:
// try
// {
// number++;
// var source = new TaskCompletionSource<byte[]>();//
// byte[] data = null;
// var seq = Seq == 0 ? Req.BaseMsg.Cmd.ToString() : DateTime.Now.Ticks.ToString();
// var socket = client.Socket as FastSocket;
// var request = socket.WeChatClient.NewRequest(seq, Data, 5000 * 3,
// //绑定异常回调
// ex =>
// { //接收超时也会触发断开链接并且重连并自动清除队列
// //fClient.SocketNote.BeginInvoke(false, null, null);
// Console.WriteLine("WeChat Socket Error:" + ex.Message);
// source.TrySetException(ex);
// },
// //绑定返回请求的回调
// onResultMessage =>
// {
// //触发此回调必有数据
// //不触发则异常 发送收取超时等
// data = onResultMessage.Msg.BaseMsg.Payloads.ToByteArray();
// source.TrySetResult(data);
// }
// );
// socket.Send(request);
// var Body = source.Task.Result;
// //长链接解包判定
// if (Body != null && Body.Length > 16 && Body[16] != 191 && number <= 3)
// {
// //client.EventManage.OnEvent(this, QrcodeReq.BaseMsg.Cmd + ",非191,重试发包.."+number);
// goto Next;
// }
// return source.Task;
// }
// catch (Exception ex)
// {
// client.WriteLog("SendWx(byte[] Data, int Seq = 0) Error:" + ex.Message);
// throw ex;
// }
}
private PackMsg NextSendData;
public void SetNextData(PackMsg nextData)
{
this.NextSendData = nextData;
}
public void SendNextData()
{
try
{
this.SendAll(this.NextSendData.cmd, false, this.NextSendData.data);
}
catch (Exception)
{
}
}
}
}