/// <summary> /// 创建一个 <see cref="CQAppContainer"/> 单例对象。 /// </summary> /// <returns>一个 <see cref="CQAppContainer"/> 对象。</returns> public static CQAppContainer GetInstance() { if (_instance == null) { _instance = new CQAppContainer(); } return(_instance); }
/// <summary> /// /// </summary> public void Start() { //初始化插件容器。 CQAppContainer.GetInstance(); string ipAddress = "127.0.0.1"; int port = 18139; string folder = Path.Combine(CQ.GetCQAppFolder(), "app"); folder = Path.Combine(folder, "cc.flexlive.cqeproxy"); if (Directory.Exists(folder)) { string iniFile = Path.Combine(folder, "cc.flexlive.cqeproxy.ini"); if (File.Exists(iniFile)) { ipAddress = IniFileHelper.GetStringValue(iniFile, "代理配置", "服务器地址", "127.0.0.1"); string strPort = IniFileHelper.GetStringValue(iniFile, "代理配置", "服务器端口", "18139"); port = Convert.ToInt32(strPort); } } IPAddress ip = IPAddress.Parse(ipAddress); int listenPort = port; IPEndPoint listenIPEndPoint = new IPEndPoint(ip, listenPort); //定义网络类型,数据连接类型和网络协议UDP this.mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //绑定网络地址 this.mySocket.Bind(listenIPEndPoint); //得到客户机IP int clientPort = 18131; IPEndPoint ipep = new IPEndPoint(ip, clientPort); RemotePoint = (EndPoint)(ipep); //启动一个新的线程,执行方法this.ReceiveHandle, //以便在一个独立的进程中执行数据接收的操作 RunningFlag = true; Thread thread = new Thread(new ThreadStart(this.ReceiveMessage)); thread.IsBackground = true; thread.Start(); }
/// <summary> /// 代理为NativeClr方式时,调用执行方法。 /// </summary> /// <param name="methodName"></param> /// <param name="parameters"></param> private static void CallMethod(string methodName, object[] parameters) { //获取插件应用目录。 string pluginFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CSharpPlugins"); foreach (string pluginFile in Directory.GetFiles(pluginFolder, "*.dll")) { try { string pluginFileName = Path.GetFileNameWithoutExtension(pluginFile); if (!CSPluginsConfigManager.GetInstance().GetLoadingStatus(pluginFileName)) { continue; } //将Dll加载到二进制数组,再从数组加载Dll类。 Assembly assembly = Assembly.Load(File.ReadAllBytes(pluginFile)); //遍历程序集中所有的数据类型。 foreach (Type type in assembly.GetTypes()) { if (!type.IsClass || type.IsNotPublic) { continue; } //获取全部继承的接口。 Type[] tempInterfaces = type.GetInterfaces(); //判断是否继承自ICQAssembly。 if (tempInterfaces.Select(s => s.Name).Contains("ICQAssembly")) { //Object theObj = Activator.CreateInstance(type); Object theObj = CQAppContainer.GetInstance().ClrApps[pluginFile]; //反射到初始化方法,并执行。 //MethodInfo mi = type.GetMethod(methodName); Dictionary <string, MethodInfo> dicMethods = CQAppContainer.GetInstance().ClrMethods[pluginFile]; MethodInfo mi = dicMethods[methodName]; Object returnValue = mi.Invoke(theObj, parameters); } } } catch { } } }
/// <summary> /// 接收数据。 /// </summary> public void ReceiveMessage(string msg) { //接收数据处理线程 try { CQ.ProxyType = CQProxyType.NativeClr; CQAppContainer.GetInstance(); Thread thread = new Thread(new ParameterizedThreadStart(this.AnalyzeMessage)); thread.IsBackground = true; thread.Start(msg); } catch { } }
/// <summary> /// 解析数据。 /// </summary> /// <param name="data"></param> public static void Analyze(string data) { lock (_syncRoot) { string[] args = data.Split(new char[] { '|' }); if (args.Length == 12) { string eventType = args[0]; //1事件类型 int subType = Convert.ToInt32(args[1]); //2子类型 int sendTime = String.IsNullOrEmpty(args[2]) ? 0 : Convert.ToInt32(args[2]); //3发送时间(时间戳) long fromGroup = String.IsNullOrEmpty(args[3]) ? 0 : Convert.ToInt64(args[3]); //4来源群号 long fromDiscuss = String.IsNullOrEmpty(args[4]) ? 0 : Convert.ToInt64(args[4]); //5来源讨论组 long fromQQ = String.IsNullOrEmpty(args[5]) ? 0 : Convert.ToInt64(args[5]); //6来源QQ string fromAnonymous = args[6]; //7来源匿名者 long beingOperateQQ = String.IsNullOrEmpty(args[7]) ? 0 : Convert.ToInt64(args[7]); //8被操作QQ string msg = args[8].Replace("$内容分割$", "|"); //9消息内容 int font = String.IsNullOrEmpty(args[9]) ? 0 : Convert.ToInt32(args[9]); //10字体 string responseFlag = args[10]; //11反馈标识(处理请求用) string file = args[11]; //12上传文件信息 if (CQ.ProxyType == CQProxyType.UDP) { foreach (CQAppAbstract app in CQAppContainer.GetInstance().Apps) { if (!app.RunningStatus) { continue; } switch (eventType) { case "PrivateMessage": //私聊消息 app.PrivateMessage(subType, sendTime, fromQQ, msg, font); break; case "GroupMessage": //群消息 app.GroupMessage(subType, sendTime, fromGroup, fromQQ, fromAnonymous, msg, font); break; case "DiscussMessage": //讨论组消息 app.DiscussMessage(subType, sendTime, fromDiscuss, fromQQ, msg, font); break; case "GroupUpload": //群文件上传事件 app.GroupUpload(subType, sendTime, fromGroup, fromQQ, file); break; case "GroupAdmin": //群事件-管理员变动 app.GroupAdmin(subType, sendTime, fromGroup, beingOperateQQ); break; case "GroupMemberDecrease": //群事件-群成员减少 app.GroupMemberDecrease(subType, sendTime, fromGroup, fromQQ, beingOperateQQ); break; case "GroupMemberIncrease": //群事件-群成员增加 app.GroupMemberIncrease(subType, sendTime, fromGroup, fromQQ, beingOperateQQ); break; case "FriendAdded": //好友事件-好友已添加 app.FriendAdded(subType, sendTime, fromQQ); break; case "RequestAddFriend": //请求-好友添加 app.RequestAddFriend(subType, sendTime, fromQQ, msg, responseFlag); break; case "RequestAddGroup": //请求-群添加 app.RequestAddGroup(subType, sendTime, fromGroup, fromQQ, msg, responseFlag); break; } } } if (CQ.ProxyType == CQProxyType.NativeClr) { List <object> parameters = new List <object>(); switch (eventType) { case "PrivateMessage": //私聊消息 parameters = new List <object>() { subType, sendTime, fromQQ, msg, font }; break; case "GroupMessage": //群消息 parameters = new List <object>() { subType, sendTime, fromGroup, fromQQ, fromAnonymous, msg, font }; break; case "DiscussMessage": //讨论组消息 parameters = new List <object>() { subType, sendTime, fromDiscuss, fromQQ, msg, font }; break; case "GroupUpload": //群文件上传事件 parameters = new List <object>() { subType, sendTime, fromGroup, fromQQ, file }; break; case "GroupAdmin": //群事件-管理员变动 parameters = new List <object>() { subType, sendTime, fromGroup, beingOperateQQ }; break; case "GroupMemberDecrease": //群事件-群成员减少 parameters = new List <object>() { subType, sendTime, fromGroup, fromQQ, beingOperateQQ }; break; case "GroupMemberIncrease": //群事件-群成员增加 parameters = new List <object>() { subType, sendTime, fromGroup, fromQQ, beingOperateQQ }; break; case "FriendAdded": //好友事件-好友已添加 parameters = new List <object>() { subType, sendTime, fromQQ }; break; case "RequestAddFriend": //请求-好友添加 parameters = new List <object>() { subType, sendTime, fromQQ, msg, responseFlag }; break; case "RequestAddGroup": //请求-群添加 parameters = new List <object>() { subType, sendTime, fromGroup, fromQQ, msg, responseFlag }; break; } CallMethod(eventType, parameters.ToArray()); } } } }
/// <summary> /// /// </summary> public void Start() { //初始化插件容器。 CQAppContainer.GetInstance(); string ipAddress = "127.0.0.1"; int port = 18139; string folder = Path.Combine(CQ.GetCQAppFolder(), "app"); folder = Path.Combine(folder, "cc.flexlive.cqeproxy"); if (Directory.Exists(folder)) { string iniFile = Path.Combine(folder, "cc.flexlive.cqeproxy.ini"); if (File.Exists(iniFile)) { ipAddress = IniFileHelper.GetStringValue(iniFile, "代理配置", "服务器地址", "127.0.0.1"); string strPort = IniFileHelper.GetStringValue(iniFile, "代理配置", "服务器端口", "18139"); port = Convert.ToInt32(strPort); } } IPAddress ip = IPAddress.Parse(ipAddress); int listenPort = port; IPEndPoint listenIPEndPoint = new IPEndPoint(ip, listenPort); //定义网络类型,数据连接类型和网络协议UDP this.mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //绑定网络地址 this.mySocket.Bind(listenIPEndPoint); //得到客户机IP int clientPort = 18131; IPEndPoint ipep = new IPEndPoint(ip, clientPort); RemotePoint = (EndPoint)(ipep); //启动一个新的线程,执行方法this.ReceiveHandle, //以便在一个独立的进程中执行数据接收的操作 RunningFlag = true; Thread thread = new Thread(new ThreadStart(this.ReceiveMessage)); thread.IsBackground = true; thread.Start(); HttpListener httpListener = new HttpListener(); httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; httpListener.Prefixes.Add("http://localhost:3147/"); httpListener.Start(); new Thread(new ThreadStart(delegate { while (true) { HttpListenerContext httpListenerContext = httpListener.GetContext(); httpListenerContext.Response.StatusCode = 200; String uri = httpListenerContext.Request.Url.LocalPath; if (!uri.Equals("/ssAPI/jabber.ashx")) { continue; } try { long groupId = long.Parse(httpListenerContext.Request.QueryString["groupId"]); String msg = httpListenerContext.Request.QueryString["msg"]; if (msg == null || msg.Equals("")) { continue; } CQ.SendGroupMessage(groupId, msg); using (StreamWriter writer = new StreamWriter(httpListenerContext.Response.OutputStream)) { writer.WriteLine("OK"); } } catch (Exception ex) { using (StreamWriter writer = new StreamWriter(httpListenerContext.Response.OutputStream)) { writer.WriteLine("ERROR:" + ex.Message); } } } })).Start(); }