Example #1
0
        private static void Main(string[] args)
        {
#if DEBUG
            logger("DEBUG", "WARNING: Running in debug mode.");
            DEBUGMODE = true;
            Thread.Sleep(5000);
#endif
            DateTime start = DateTime.Now;
            //string ipv4_ip = NetworkInfo.GetLocalIpAddress();
            MainHolder.logger = logger;
            bool      booted = false;
            Exception exc    = null;

            #region 读取配置
            StreamReader cfile  = new StreamReader("config.json");
            JObject      config = (JObject)JsonConvert.DeserializeObject(cfile.ReadToEnd());
            cfile.Close();
            host  = config["mirai"].Value <string>("server");
            me_qq = config["mirai"].Value <long>("user");
            key   = config["mirai"].Value <string>("key");
            try
            {
                port = config["mirai"].Value <int>("port");
            }
            catch
            {
                port = 8080;
            }
            authenti                 = config["auth"].Value <string>("name");
            MainHolder.LiveRoom      = config["bili"].Value <int>("roomid");
            MainHolder.BiliWatchUIDs = new List <int>();
            foreach (JToken j in config["bili"]["uids"])
            {
                MainHolder.BiliWatchUIDs.Add(j.Value <int>());
            }
            MainHolder.useBiliRecFuncs   = config["auth"].Value <bool>("rectfunc");
            MainHolder.enableNativeFuncs = config["auth"].Value <bool>("nativefuncs");
            //如果是本地ip就走本地
            //if (host == ipv4_ip && Environment.OSVersion.Platform != PlatformID.Win32NT)
            //{
            //    logger("MainThread", "Running on the same server! Using 127.0.0.1 to connect mirai.");
            //    host = "127.0.0.1";
            //}
            #endregion

            while (true)//故障自动重启
            {
                try
                {
                    //Console.Title = "ManageBot By Developer_ken - Initializing...";
                    logger("MainThread", "Pushing up the engine...", ConsoleColor.Black, ConsoleColor.Green);
                    {
                        IServiceProvider services = new ServiceCollection().AddMiraiBaseFramework()   // 表示使用基于基础框架的构建器
                                                    .AddHandler <tech.msgp.groupmanager.Code.EventHandlers.EventHandler>()
                                                    .Services
                                                    .AddDefaultMiraiHttpFramework()                                           // 表示使用 mirai-api-http 实现的构建器
                                                    .ResolveParser <tech.msgp.groupmanager.Code.EventHandlers.EventHandler>() // 只提前解析 DynamicPlugin 将要用到的消息解析器
                                                    .AddInvoker <MiraiHttpMessageHandlerInvoker>()                            // 使用默认的调度器
                                                    .AddClient <MiraiHttpSession>()                                           // 使用默认的客户端
                                                    .Services
                                                                                                                              // 由于 IMiraiHttpSession 使用 IOptions<MiraiHttpSessionOptions>, 其作为 Singleton 被注册
                                                                                                                              // 配置此项将配置基于此 IServiceProvider 全局的连接配置
                                                                                                                              // 如果你想一个作用域一个配置的话
                                                                                                                              // 自行做一个实现类, 继承IMiraiHttpSession, 构造参数中使用 IOptionsSnapshot<MiraiHttpSessionOptions>
                                                                                                                              // 并将其传递给父类的构造参数
                                                                                                                              // 然后在每一个作用域中!先!配置好 IOptionsSnapshot<MiraiHttpSessionOptions>, 再尝试获取 IMiraiHttpSession
                                                    .Configure <MiraiHttpSessionOptions>(options =>
                        {
                            options.Host    = host;
                            options.Port    = port;                         // 端口
                            options.AuthKey = key;                          // 凭据
                        })
                                                    .AddLogging()
                                                    .BuildServiceProvider();
                        IServiceScope scope = services.CreateScope();
                        //var x = (IAsyncDisposable)scope;
                        //await using AsyncServiceScope scope = services.CreateAsyncScope(); // 自 .NET 6.0 起才可以如此操作代替上边两句
                        services = scope.ServiceProvider;
                        IMiraiHttpSession session = services.GetRequiredService <IMiraiHttpSession>(); // 大部分服务都基于接口注册, 请使用接口作为类型解析
                        session.ConnectAsync(me_qq).Wait();                                            // 填入期望连接到的机器人QQ号
                        MainHolder.session = session;
                    }
                    //MainHolder.session.GetFriendListAsync().Wait();
                    logger("MainThread", "BotAPI is up.", ConsoleColor.Black, ConsoleColor.Green);
                    pool            = new pThreadPool();
                    MainHolder.pool = pool;
                    logger("MainThread", "Threadpool is UP.", ConsoleColor.Black, ConsoleColor.Green);
                    pool.submitWorkload(() =>
                    {
                        while (true)
                        {
                            /*
                             *  logger("threadpool", "threads= " + pool.min_size + "<" + pool.size + "/" + pool.busythread + "<" + pool.max_size +
                             *  " | works= " + pool.queuelen + "<" + pool.queue_max_len + " | errors= " + pool.excepttionlen + "<" + pool.exceptionmaxlen
                             *  );
                             */
                            Dictionary <Guid, Exception> err = pool.popException();
                            if (err != null)
                            {
                                foreach (KeyValuePair <Guid, Exception> e in err)
                                {
                                    logger("threadpool_exception", "Work-" + e.Key + " -> " + e.Value.Message, ConsoleColor.DarkRed);
                                    logger("threadpool_exception", "Work-" + e.Key + " -> " + e.Value.StackTrace, ConsoleColor.DarkRed);
                                }
                            }
                            pool.clearExceptions();
                            Thread.Sleep(1000);
                        }
                    });
                    pool.onWorkloadStartProcess += startwork;
                    pool.onWorkloadStopProcess  += stopwork;
                    logger("MainThread", "Events registered.", ConsoleColor.Black, ConsoleColor.Green);
                    MainHolder.INIT(config);
                    //string xml = "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID=\"35\" templateID=\"1\" action=\"viewMultiMsg\" brief=\"[聊天记录]\" m_resid=\"y0oBW4IOb1T2mMOQXiMI9tajqUkTEioFVMFc66YCia2fQEx2+Sp1Bogtcn80e6R+\" m_fileName=\"6858932750478640422\" tSum=\"34\" sourceMsgId=\"0\" url=\"\" flag=\"3\" adverSign=\"0\" multiMsgFlag=\"0\"><item layout=\"1\" advertiser_id=\"0\" aid=\"0\"><title size=\"34\" maxLines=\"2\" lineSpace=\"12\">群聊的聊天记录</title><title size=\"26\" color=\"#777777\" maxLines=\"4\" lineSpace=\"12\">古小艺:  《迷惑行为》新增1个影像</title><title size=\"26\" color=\"#777777\" maxLines=\"4\" lineSpace=\"12\">柠檬味的海鲜龙:  嗯呢</title><title size=\"26\" color=\"#777777\" maxLines=\"4\" lineSpace=\"12\">一只鸡蛋:  新的机器人核心功能已经快移植好了\n现在是离线状态\n这几天要辛苦大家手动处理这些…</ title >< title size =\"26\" color=\"#777777\" maxLines=\"4\" lineSpace=\"12\">呆 萌呆萌瓜:  ohhhhhhh</title><hr hidden=\"false\" style=\"0\" /><summary size=\"26\" color=\"#777777\">查看34条转发消息</summary></item><source name=\"聊天记录\" icon=\"\" action=\"\" appid=\"-1\" /></msg>";
                    //api.sendXmlMessage(417944217, xml, MsgType.GROUP);
                    //Console.Title = "ManageBot By Developer_ken - Standby";
                    try
                    {
                        /*
                         * MainHolder.session.GroupMessageEvt += new Event_GroupMessage().GroupMessage;
                         * MainHolder.session.GroupApplyEvt += new GroupEnterRequest().GroupApply;
                         * MainHolder.session.GroupMemberJoinedEvt += new GroupMemberIncrease().GroupMemberJoined;
                         * GroupMemberLeave gleave = new GroupMemberLeave();
                         * MainHolder.session.GroupMemberKickedEvt += gleave.GroupMemberKicked;
                         * MainHolder.session.GroupMemberPositiveLeaveEvt += gleave.GroupMemberPositiveLeave;
                         * PrivMessageHan pmsg = new PrivMessageHan();
                         * MainHolder.session.TempMessageEvt += pmsg.TempMessage;
                         * MainHolder.session.FriendMessageEvt += pmsg.FriendMessage;
                         * /*
                         * han.onGroupMessageReceive += new Event_GroupMessage().GroupMessage;
                         * han.onPrivateMessageReceive += new Event_PrivMessage().PrivateMessage;
                         * han.onGroupMemberIncrease += new Event_GroupMemberIncrease().GroupMemberIncrease;
                         * han.onGroupMemberDecrease += new Event_GroupMemberLeave().GroupMemberDecrease;
                         * han.onGroupEnterRequest += new Event_GroupMemberRequest().GroupAddRequest;
                         * han.onGroupMessageSendOkay += onSendSuccess;
                         */
                        logger("MainThread", "Event Recevier is UP.", ConsoleColor.Black, ConsoleColor.White);
                    }
                    catch (Exception)
                    {
                        logger("MainThread", "Event Recevier FAILED.", ConsoleColor.Black, ConsoleColor.Red);
                    }
                    logger("MainThread", "Stand by.  The bot is up and ready to go. Type to set an log filter.", ConsoleColor.Black, ConsoleColor.Green);
#if RELEASE
                    MainHolder.broadcaster.BroadcastToAdminGroup("[启动报告]\n" +
                                                                 (DEBUGMODE ? "⚠当前处于调试模式,不适合长期运行⚠\n" : "") +
                                                                 "当前版本:" + codeName + version + "\n" +
                                                                 "启用耗时:" + (DateTime.Now - start).TotalSeconds + "s\n" +
                                                                 "当前授权:" + authenti + "\n" +
                                                                 "授权约束:" + (MainHolder.useBiliRecFuncs ? "" : "[MainHolder.useBiliRecFuncs=False]\n") +
                                                                 (MainHolder.enableNativeFuncs ? "" : "[MainHolder.enableNativeFuncs=False]\n"))
                    ;
#endif
                    if (booted)
                    {
                        MainHolder.broadcaster.BroadcastToAdminGroup("严重故障\n机器人遭遇了不可恢复的错误,主线程无法继续运行。为了确保稳定运行," +
                                                                     "主线程已被系统重置。该操作成功完成,程序将会继续运行,但未保存的工作可能已经丢失。\n");
                        MainHolder.broadcaster.BroadcastToAdminGroup("错误报告\n" + exc.Message + "\nStackTrace >" + exc.StackTrace);
                    }

                    booted = true;


                    while (true)
                    {
                        try
                        {
                            string field = "";
                            do
                            {
                                ConsoleKeyInfo k = Console.ReadKey(true);
                                if (k.Key == ConsoleKey.Enter)
                                {
                                    break;
                                }

                                if (k.Key == ConsoleKey.Backspace)
                                {
                                    if (field.Length >= 1)
                                    {
                                        field = field.Substring(0, field.Length - 1);
                                    }
                                    continue;
                                }
                                if (k.Key == ConsoleKey.Delete)
                                {
                                    field = "";
                                    continue;
                                }
                                field += k.KeyChar;
                                //Console.Title = "input>" + field + " | Press [Enter] to " + (field.Length >= 1 ? "set" : "remove") + " a filter.";
                            } while (true);
                            keyword = field;
                            if (keyword != "")
                            {
                                logger("control", "Filter set.", ConsoleColor.Black, ConsoleColor.Green);
                                //Console.Title = "Filter: " + keyword + " | Press [Enter] to remove filter";
                            }
                            else
                            {
                                logger("control", "Filter removed.", ConsoleColor.Black, ConsoleColor.Green);
                                //Console.Title = "ManageBot By Developer_ken - Standby";
                            }
                        }
                        catch
                        {
                            Thread.Sleep(int.MaxValue);
                        }
                    }
                    ;
                }
                catch (Exception err)
                {
                    exc = err;
                    logger("EXCEPTION", "E_FATAL " + err.Message, ConsoleColor.Black, ConsoleColor.Red);
                    logger("EXCEPTION", "STACKTRACE " + err.StackTrace, ConsoleColor.Black, ConsoleColor.Red);
                    //throw;
                }
            }
        }
#pragma warning disable CS1998 // 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。
        public async Task HandleMessageAsync(IMiraiHttpSession client, IGroupMessageEventArgs e)
#pragma warning restore CS1998 // 此异步方法缺少 "await" 运算符,将以同步方式运行。请考虑使用 "await" 运算符等待非阻止的 API 调用,或者使用 "await Task.Run(...)" 在后台线程上执行占用大量 CPU 的工作。
        {
            try
            {
                var session = MainHolder.session;

                WatchDog.FeedDog("grpmsg");
                pThreadPool pool = MainHolder.pool;
                //MainHolder.Logger.Debug("CQPLUGIN", "Event_GroupMessageFired");
                MainHolder.MsgCount++;
                SecondlyTask.lastrecv = DateTime.Now;
                if (true)
                {
                    IGroupInfo       gpinfo = e.Sender.Group;
                    IGroupMemberInfo gminfo = e.Sender;
                    string           gpname = DataBase.me.getGroupName(gpinfo.Id);
                    if (!DataBase.me.connected)
                    {
                        MainHolder.Logger.Error("数据库", "数据库未连接");
                    }

                    foreach (IChatMessage msg in e.Chain)
                    {
                        if (msg is not UnknownChatMessage)//不处理UnknownChatMessage
                        {
                            switch (msg.Type)
                            {
                            case "Plain":
                            {
                                PlainMessage message = (PlainMessage)msg;
                                if (!DataBase.me.recQQmsg(e.Sender.Id, e.Sender.Group.Id, message.Message))
                                {
                                    MainHolder.Logger.Error("数据库", "未能将消息存入数据库");
                                }
                                //message.Message
                                {
                                    string abvn = AVFinder.abvFromString(message.Message);
                                    if (abvn != null && abvn != "")
                                    {
                                        processVideoBilibili(e, abvn);
                                    }
                                }
                                Commands.Proc(session, e, message.Message);
                            }
                            break;

                            case "Xml":
                            {
                                XmlMessage message = (XmlMessage)msg;
                                if (!DataBase.me.recQQmsg(e.Sender.Id, e.Sender.Group.Id, message.Xml))
                                {
                                    MainHolder.Logger.Error("数据库", "未能将消息存入数据库");
                                }

                                if (Commands.cocogroup == e.Sender.Group.Id)
                                {
                                    MainHolder.broadcaster.SendToGroup(e.Sender.Group.Id, "[Xml解析]\n" + message.Xml);
                                }

                                XmlDocument doc = new XmlDocument();
                                doc.LoadXml(message.Xml);
                                {
                                    if (doc["msg"] == null)
                                    {
                                        MainHolder.broadcaster.SendToAnEgg(e.Sender.Group.Id + "无msg标签的Xml消息\n" + message.Xml);
                                    }
                                    if (doc["msg"].HasAttribute("action") && doc["msg"].GetAttribute("action") == "viewMultiMsg" && DataBase.me.isAdminGroup(e.Sender.Group.Id))
                                    {
                                        string fname      = doc["msg"].GetAttribute("m_fileName");
                                        string fresid     = doc["msg"].GetAttribute("m_resid");
                                        int    tsum       = int.Parse(doc["msg"].GetAttribute("tSum"));
                                        int    flag       = int.Parse(doc["msg"].GetAttribute("flag"));
                                        int    serviceID  = int.Parse(doc["msg"].GetAttribute("serviceID"));
                                        int    m_fileSize = int.Parse(doc["msg"].GetAttribute("m_fileSize"));
                                        DataBase.me.saveMessageGroup(fname, fresid, tsum, flag, serviceID, m_fileSize);
                                        MainHolder.broadcaster.SendToGroup(e.Sender.Group.Id, "[消息存证]\n该条消息记录已提交至腾讯服务器\n存根ID:" + fname);
                                        return;
                                        //不再处理该条消息
                                    }
                                    if (doc["msg"]["source"] != null && doc["msg"]["source"].HasAttribute("name"))
                                    {
                                        switch (doc["msg"]["source"].GetAttribute("name"))
                                        {
                                        case "哔哩哔哩":                                                               //B站分享
                                            if (doc["msg"].GetAttribute("url").IndexOf("/live.bilibili.com/") > 0) //直播分享
                                            {
                                            }
                                            if (doc["msg"].GetAttribute("url").IndexOf("/b23.tv/") > 0)            //可能是视频分享
                                            {
                                                try
                                                {
                                                    string bvn = BiliApi.AVFinder.bvFromB23url(doc["msg"].GetAttribute("url"));
                                                    if (bvn != null)            //真的是视频分享
                                                    {
                                                        processVideoBilibili(e, bvn);
                                                        return;
                                                    }
                                                }
                                                catch (Exception)
                                                {
                                                }
                                            }
                                            break;

                                        case "网页分享":
                                            if (doc["msg"].GetAttribute("url").IndexOf("/live.bilibili.com/") > 0)            //直播分享
                                            {
                                            }
                                            if (doc["msg"].GetAttribute("url").IndexOf("/www.bilibili.com/video/") > 0)            //视频分享
                                            {
                                                string bvn = BiliApi.AVFinder.bvFromPlayURL(doc["msg"].GetAttribute("url"));
                                                if (bvn != null)            //真的是视频分享
                                                {
                                                    processVideoBilibili(e, bvn);
                                                    return;
                                                }
                                            }
                                            break;

                                        default:
                                            break;
                                        }
                                    }
                                }
                            }
                            break;

                            case "Json":
                            {
                                JsonMessage message = (JsonMessage)msg;
                                if (Commands.cocogroup == e.Sender.Group.Id)
                                {
                                    MainHolder.broadcaster.SendToGroup(e.Sender.Group.Id, "[Json解析]\n" + message.Json);
                                }
                                if (!DataBase.me.recQQmsg(e.Sender.Id, e.Sender.Group.Id, message.Json))
                                {
                                    MainHolder.Logger.Error("数据库", "未能将消息存入数据库");
                                }
                            }
                            break;

                            case "App":
                            {
                                AppMessage message = (AppMessage)msg;
                                if (Commands.cocogroup == e.Sender.Group.Id)
                                {
                                    MainHolder.broadcaster.SendToGroup(e.Sender.Group.Id, "[AppContent解析]\n" + message.Content);
                                }
                                if (!DataBase.me.recQQmsg(e.Sender.Id, e.Sender.Group.Id, message.Content))
                                {
                                    MainHolder.Logger.Error("数据库", "未能将消息存入数据库");
                                }
                                {
                                    string abvn = null;
                                    try
                                    {
                                        JObject jb = JObject.Parse(message.Content);
                                        abvn = AVFinder.bvFromB23url(jb["meta"]["detail_1"]["qqdocurl"].ToString());
                                    }
                                    catch
                                    {
                                    }
                                    if (abvn != null && abvn != "")
                                    {
                                        processVideoBilibili(e, abvn);
                                    }
                                }
                            }
                            break;

                            case "Source":
                                break;

                            case "Image":
                            {
                                /*try
                                 * {
                                 *  ImageMessage message = (ImageMessage)msg;
                                 *  Ticket t = TicketCoder.Decode(new Bitmap(PicLoader.loadPictureFromURL(message.Url)));
                                 *  string l = "未知";
                                 *  switch (t.Data.Level)
                                 *  {
                                 *      case Ticket.CrewLevel.舰长:
                                 *          l = "舰长";
                                 *          break;
                                 *      case Ticket.CrewLevel.总督:
                                 *          l = "总督";
                                 *          break;
                                 *      case Ticket.CrewLevel.提督:
                                 *          l = "提督";
                                 *          break;
                                 *  }
                                 *  BiliUser bu = new BiliUser(t.Data.Uid, MainHolder.biliapi);
                                 *  MainHolder.broadcaster.SendToGroup(e.Sender.Group.Id, "[船票]\n" +
                                 *      "版本=" + t.Data.SpecType + "\n" +
                                 *      "绑定账号=" + bu.name + "#" + t.Data.Uid + "\n" +
                                 *      "签发时间=" + t.Data.GenerateTime.ToString("yyyy MM dd HH:mm:ss") + "\n" +
                                 *      "等级=" + l + "\n" +
                                 *      "签名有效");
                                 * }
                                 * catch (SignatureInvalidException err)
                                 * {
                                 *  MainHolder.broadcaster.SendToGroup(e.Sender.Group.Id, "该船票签名无效");
                                 * }
                                 * catch { }
                                 */
                            }
                            break;

                            default:
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception err)
            {
                MainHolder.broadcaster.BroadcastToAdminGroup("[Exception]\n这条消息可能意味着机器人发生了错误。它仍在继续运行,但可能不是很稳定。下面的信息用来帮助鸡蛋定位错误,管理不必在意。\n[群消息接收处理]" + err.Message + "\n\n堆栈跟踪:\n" + err.StackTrace);
            }
            return;
        }