Ejemplo n.º 1
0
        public static async Task Configure()
        {
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(ConfigurationManager.AppSettings.Get("host"),
                                                                          Convert.ToInt32(ConfigurationManager.AppSettings.Get("port")),
                                                                          ConfigurationManager.AppSettings.Get("authKey"));

            groupID = Convert.ToInt64(ConfigurationManager.AppSettings.Get("groupID"));

            // session 使用 DisposeAsync 模式, 所以使用 await using 自动调用 DisposeAsync 方法。
            // 你也可以不在这里 await using, 不过使用完 session 后请务必调用 DisposeAsync 方法
            session = new MiraiHttpSession();
            // 把你实现了 Mirai_CSharp.Plugin.Interfaces 下的接口的类给 new 出来, 然后作为插件塞给 session
            Plugin plugin = new Plugin();

            // 你也可以一个个绑定事件。比如 session.GroupMessageEvt += plugin.GroupMessage;
            // 手动绑定事件后不要再调用AddPlugin, 否则可能导致重复调用
            session.AddPlugin(plugin);
            try
            {
                // 使用上边提供的信息异步连接到 mirai-api-http
                await session.ConnectAsync(options, Convert.ToInt64(ConfigurationManager.AppSettings.Get("qqNumber"))); // 自己填机器人QQ号
            }
            catch
            {
                MessageBox.Show("程序连接Mirai服务器失败,该程序目前只能测试弹幕使用,如需正常使用,请配置正确后重新启动程序。");
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 异步注册指令
        /// </summary>
        /// <exception cref="InvalidAuthKeyException"/>
        /// <exception cref="InvalidOperationException"/>
        /// <param name="options">连接信息</param>
        /// <param name="name">指令名</param>
        /// <param name="alias">指令别名</param>
        /// <param name="description">指令描述</param>
        /// <param name="usage">指令用法, 会在指令执行错误时显示</param>
        public static async Task RegisterCommandAsync(MiraiHttpSessionOptions options, string name, string[] alias = null, string description = null, string usage = null)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("指令名必须非空。", nameof(name));
            }
            byte[] payload = JsonSerializer.SerializeToUtf8Bytes(new
            {
                authKey = options.AuthKey,
                name,
                alias = alias ?? Array.Empty <string>(),
                description,
                usage
            });
            string json = await HttpHelper.HttpPostAsync($"{options.BaseUrl}/command/register", payload).GetStringAsync();

            try
            {
                using JsonDocument j = JsonDocument.Parse(json);
                JsonElement root = j.RootElement;
                ProcessResponse(in root);
            }
            catch (JsonException) // 返回值非json就是执行失败, 把返回信息重新抛出
            {
                throw new InvalidOperationException(json);
            }
        }
Ejemplo n.º 3
0
        public static async Task Main()
        {
            // 把你要连接到的 mirai-api-http 所需的主机名/IP, 端口 和 AuthKey 全部填好
            // !! 最好不要用我例子里边的 key 和 端口, 请自己生成一个, 比如 System.Guid.NewGuid().ToString("n") !!
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions("127.0.0.1", 8080, "INITKEYVCo5ktPW");

            // session 使用 DisposeAsync 模式, 所以使用 await using 自动调用 DisposeAsync 方法。
            // 你也可以不在这里 await using, 不过使用完 session 后请务必调用 DisposeAsync 方法
            await using MiraiHttpSession session = new MiraiHttpSession();
            // 把你实现了 Mirai_CSharp.Plugin.Interfaces 下的接口的类给 new 出来, 然后作为插件塞给 session
            GamePlugin plugin = new GamePlugin();

            // 你也可以一个个绑定事件。比如 session.GroupMessageEvt += plugin.GroupMessage;
            // 手动绑定事件后不要再调用AddPlugin, 否则可能导致重复调用
            session.AddPlugin(plugin);
            // 使用上边提供的信息异步连接到 mirai-api-http
            await session.ConnectAsync(options, 1018429593); // 自己填机器人QQ号

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 4
0
        public static async Task Main()
        {
            // 把你要连接到的 mirai-api-http 所需的主机名/IP, 端口 和 AuthKey 全部填好
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions("127.0.0.1", 33111, "8d726307dd7b468d8550a95f236444f7");

            // session 使用 DisposeAsync 模式, 所以使用 await using 自动调用 DisposeAsync 方法。
            // 你也可以不在这里 await using, 不过使用完 session 后请务必调用 DisposeAsync 方法
            await using MiraiHttpSession session = new MiraiHttpSession();
            // 把你实现了 Mirai_CSharp.Plugin.Interfaces 下的接口的类给 new 出来, 然后作为插件塞给 session
            ExamplePlugin plugin = new ExamplePlugin();

            // 你也可以一个个绑定事件。比如 session.GroupMessageEvt += plugin.GroupMessage;
            // 手动绑定事件后不要再调用AddPlugin, 否则可能导致重复调用
            session.AddPlugin(plugin);
            // 使用上边提供的信息异步连接到 mirai-api-http
            await session.ConnectAsync(options, 0); // 自己填机器人QQ号

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 5
0
        public async Task Launch()
        {
            Logger.Log("Session host:", SessionHost);
            Logger.Log("Session port:", SessionPort);
            Logger.Log("Session key:", SessionKey);
            var sessionOptions = new MiraiHttpSessionOptions(SessionHost, SessionPort, SessionKey);

            Logger.Log("Mirai session created");
            _session = new MiraiHttpSession();

            foreach (var plugin in Plugins)
            {
                _session.AddPlugin(plugin);
                Logger.Log("Plugin:", plugin.GetType().Name, "added");
            }

            try
            {
                await _session.ConnectAsync(sessionOptions, BotQQ);

                Logger.Log("Successful connected", BotQQ, "to Mirai session");
                Logger.Log("Bot launched!");
            }
            catch (Exception e)
            {
                Logger.Log("Connect to", BotQQ, "failed");
                Logger.Log("Reason:", e.Message);
            }
        }
Ejemplo n.º 6
0
        public static async Task Main()
        {
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions("127.0.0.1", 8080, "1c783ceb3f5344d097781ab771021efc");

            await using MiraiHttpSession session = new MiraiHttpSession();
            var plugin = new Plugins();

            session.GroupMessageEvt += plugin.ImageMonitor;
            session.GroupMessageEvt += plugin.MemberBan;
            session.GroupMessageEvt += plugin.Accept;
            session.GroupMessageEvt += plugin.OnAt;
            session.DisconnectedEvt += plugin.Disconnected;
            session.GroupMessageEvt += plugin.MemberKick;
            session.GroupMessageEvt += plugin.ManagementUsingAt;
            await session.ConnectAsync(options, 3197173556);

            // await UnitTest.Run(session, 947904856);
            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 7
0
        private async static System.Threading.Tasks.Task <bool> Session_DisconnectedEvt(IMiraiHttpSession sender, Exception e)
        {
            logger("Connection", e.Message);
            while (true)
            {
                try
                {
                    logger("Connection", "Reconnecting...");
                    MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(host, port, key);
                    await sender.ConnectAsync(me_qq);

                    if (!e.Message.Contains("未知的消息类型"))
                    {
                        MainHolder.broadcaster.BroadcastToAdminGroup("[断线重连]\n诊断报告:" + e.Message + "\n" + e.StackTrace);
                    }
                    break;
                }
                catch (Exception err)
                {
                    logger("Connection", err.Message);
                    await Task.Delay(1000);
                }
            }
            return(false);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 异步执行指令
        /// </summary>
        /// <exception cref="InvalidAuthKeyException"/>
        /// <exception cref="InvalidOperationException"/>
        /// <exception cref="TargetNotFoundException"/>
        /// <param name="options">连接信息</param>
        /// <param name="name">指令名</param>
        /// <param name="args">指令参数</param>
        public static async Task ExecuteCommandAsync(MiraiHttpSessionOptions options, string name, params string[] args)
        {
            byte[] payload = JsonSerializer.SerializeToUtf8Bytes(new
            {
                authKey = options.AuthKey,
                name,
                args
            });
            string json = await HttpHelper.HttpPostAsync($"{options.BaseUrl}/command/send", payload).GetStringAsync();

            try
            {
                using JsonDocument j = JsonDocument.Parse(json);
                JsonElement root = j.RootElement;
                ProcessResponse(in root);
            }
            catch (JsonException) // 返回值非json就是执行失败, 把返回信息重新抛出
            {
                throw new InvalidOperationException(json);
            }
            catch (TargetNotFoundException e) // 指令不存在
            {
                e._message = "给定的指令不存在。";
                throw e;
            }
        }
Ejemplo n.º 9
0
        static async Task Main(string[] args)
        {
            // 把你要连接到的 mirai-api-http 所需的主机名/IP, 端口 和 AuthKey 全部填好
            // !! 最好不要用我例子里边的 key 和 端口, 请自己生成一个, 比如 System.Guid.NewGuid().ToString("n") !!
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(Setting.Host, Setting.Port, Setting.AuthKey);

            // session 使用 DisposeAsync 模式, 所以使用 await using 自动调用 DisposeAsync 方法。
            // 你也可以不在这里 await using, 不过使用完 session 后请务必调用 DisposeAsync 方法
            await using MiraiHttpSession session = new MiraiHttpSession();
            // 把你实现了 Mirai_CSharp.Plugin.Interfaces 下的接口的类给 new 出来, 然后作为插件塞给 session
            NormalPlugin plugin = new NormalPlugin();

            // 你也可以一个个绑定事件。比如 session.GroupMessageEvt += plugin.GroupMessage;
            // 手动绑定事件后不要再调用AddPlugin, 否则可能导致重复调用
            session.AddPlugin(plugin);
            // 实例化MQ
            MQUtil.InitMQ();
            // 使用上边提供的信息异步连接到 mirai-api-http
            await session.ConnectAsync(options, Setting.QQ); // 自己填机器人QQ号

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 10
0
        public static async Task <bool> Start(BotStartupConfig config)
        {
            if (connecting || session.Connected)
            {
                return(false);
            }
            else
            {
                connecting = true;
            }
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(config.host, config.port, config.authKey);

            try
            {
                await session.ConnectAsync(options, config.qqID);
            }
            catch
            {
                connecting = false;
                return(false);
            }
            if (session.Connected)
            {
                session.AddPlugin(new MainPlugin());
                await BotCore.Init(session, config);

                connecting = false;
                return(true);
            }
            else
            {
                connecting = false;
                return(false);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 异步执行指令
        /// </summary>
        /// <exception cref="InvalidAuthKeyException"/>
        /// <exception cref="InvalidOperationException"/>
        /// <exception cref="TargetNotFoundException"/>
        /// <param name="client">要进行请求的 <see cref="HttpClient"/></param>
        /// <param name="options">连接信息</param>
        /// <param name="name">指令名</param>
        /// <param name="args">指令参数</param>
        /// <returns>表示此异步操作的 <see cref="Task"/></returns>
        public static async Task ExecuteCommandAsync(HttpClient client, MiraiHttpSessionOptions options, string name, params string[] args)
        {
            var payload = new
            {
                authKey = options.AuthKey,
                name,
                args
            };
            string json = await client.PostAsJsonAsync($"{options.BaseUrl}/command/send", payload).GetStringAsync();

            try
            {
                using JsonDocument j = JsonDocument.Parse(json);
                JsonElement root = j.RootElement;
                int         code = root.GetProperty("code").GetInt32();
                if (code != 0)
                {
                    throw GetCommonException(code, in root);
                }
            }
            catch (JsonException) // 返回值非json就是执行失败, 把响应正文重新抛出
            {
                throw new InvalidOperationException(json);
            }
            catch (TargetNotFoundException e) // 指令不存在
            {
                e._message = "给定的指令不存在。";
                throw;
            }
        }
Ejemplo n.º 12
0
        public static async Task Main()
        {
            // 把你要连接到的 mirai-api-http 所需的主机名/IP, 端口 和 AuthKey 全部填好
            // !! 最好不要用我例子里边的 key 和 端口, 请自己生成一个, 比如 System.Guid.NewGuid().ToString("n") !!
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions("47.242.52.67", 5200, "zheng12321");

            // session 使用 DisposeAsync 模式, 所以使用 await using 自动调用 DisposeAsync 方法。
            // 你也可以不在这里 await using, 不过使用完 session 后请务必调用 DisposeAsync 方法
            await using MiraiHttpSession session = new MiraiHttpSession();
            // 把你实现了 Mirai_CSharp.Plugin.Interfaces 下的接口的类给 new 出来, 然后作为插件塞给 session
            ExamplePlugin plugin = new ExamplePlugin();

            // 你也可以一个个绑定事件。比如 session.GroupMessageEvt += plugin.GroupMessage;
            // 手动绑定事件后不要再调用AddPlugin, 否则可能导致重复调用
            session.AddPlugin(plugin);

            // 使用上边提供的信息异步连接到 mirai-api-http
            await session.ConnectAsync(options, 2593894146); // 自己填机器人QQ号  481503471   478893039   859255432

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// 异步注册指令
        /// </summary>
        /// <exception cref="InvalidAuthKeyException"/>
        /// <exception cref="InvalidOperationException"/>
        /// <param name="client">要进行请求的 <see cref="HttpClient"/></param>
        /// <param name="options">连接信息</param>
        /// <param name="name">指令名</param>
        /// <param name="alias">指令别名</param>
        /// <param name="description">指令描述</param>
        /// <param name="usage">指令用法, 会在指令执行错误时显示</param>
        /// <returns>表示此异步操作的 <see cref="Task"/></returns>
        public static async Task RegisterCommandAsync(HttpClient client, MiraiHttpSessionOptions options, string name, string[]?alias = null, string?description = null, string?usage = null)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("指令名必须非空。", nameof(name));
            }
            var payload = new
            {
                authKey = options.AuthKey,
                name,
                alias = alias ?? Array.Empty <string>(),
                description,
                usage
            };
            string json = await client.PostAsJsonAsync($"{options.BaseUrl}/command/register", payload).GetStringAsync();

            try
            {
                using JsonDocument j = JsonDocument.Parse(json);
                JsonElement root = j.RootElement;
                int         code = root.GetProperty("code").GetInt32();
                if (code != 0)
                {
                    throw GetCommonException(code, in root);
                }
            }
            catch (JsonException) // 返回值非json就是执行失败, 把响应正文重新抛出
            {
                throw new InvalidOperationException(json);
            }
        }
Ejemplo n.º 14
0
        /// <exception cref="InvalidAuthKeyException"/>
        /// <param name="client">要进行请求的 <see cref="HttpClient"/></param>
        /// <param name="options">连接信息</param>
        /// <inheritdoc cref="ExecuteCommandAsync(string, string[], CancellationToken)"/>
        public static async Task ExecuteCommandAsync(HttpClient client, MiraiHttpSessionOptions options, string name, string[]?args, CancellationToken token)
        {
            var payload = new
            {
                authKey = options.AuthKey,
                name,
                args = args ?? Array.Empty <string>()
            };
            string json = await client.PostAsJsonAsync($"{options.BaseUrl}/command/send", payload, token).GetStringAsync(token).ConfigureAwait(false);

            try
            {
                using JsonDocument j = JsonDocument.Parse(json);
                JsonElement root = j.RootElement;
                root.EnsureApiRespCode();
            }
            catch (JsonException) // 返回值非json就是执行失败, 把响应正文重新抛出
            {
                throw new InvalidOperationException(json);
            }
            catch (TargetNotFoundException e) // 指令不存在
            {
                e.ActualMessage = "给定的指令不存在。";
                throw;
            }
        }
Ejemplo n.º 15
0
        /// <param name="client">要进行请求的 <see cref="HttpClient"/></param>
        /// <param name="options">连接信息</param>
        /// <inheritdoc cref="RegisterCommandAsync(string, string[], string, string, CancellationToken)"/>
        public static async Task RegisterCommandAsync(HttpClient client, MiraiHttpSessionOptions options, string name, string[]?alias = null, string?description = null, string?usage = null, CancellationToken token = default)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentException("指令名必须非空。", nameof(name));
            }
            var payload = new
            {
                authKey = options.AuthKey,
                name,
                alias = alias ?? Array.Empty <string>(),
                description,
                usage
            };
            string json = await client.PostAsJsonAsync($"{options.BaseUrl}/command/register", payload, token).GetStringAsync(token).ConfigureAwait(false);

            try
            {
                using JsonDocument j = JsonDocument.Parse(json);
                JsonElement root = j.RootElement;
                root.EnsureApiRespCode();
            }
            catch (JsonException) // 返回值非json就是执行失败, 把响应正文重新抛出
            {
                throw new InvalidOperationException(json);
            }
        }
Ejemplo n.º 16
0
        async void HandShakeClientStart(object sender, RoutedEventArgs e)
        {
            var port    = int.Parse(PortTextBox.Text);
            var options = new MiraiHttpSessionOptions("localhost", port, "PinkPill");
            var selfQQ  = long.Parse(SelfIDTextBox.Text);   // 自己
            var otherQQ = long.Parse(TargetIDTextBox.Text); // 对方

            TargetQQ = otherQQ;
            session  = new MiraiHttpSession();

            await session.ConnectAsync(options, selfQQ);

            var superStream  = new DelayedBufferStream((_, e) => { SendMessage(new ImageObfuscator().Obfuscate(e)); });
            var serverStream = new SslStream(superStream, false,
                                             (sender, certificate, chain, errors) =>
            {
                var subject = certificate.Subject;
                AddMessage($"握手完成: 证书名 {subject}");
                return(true);
            }, null);

            stream = serverStream;
            var cert = X509Certificate2.CreateFromPemFile(@"cert.pem");

            cert = new X509Certificate2(cert.Export(X509ContentType.Pkcs12));


            session.FriendMessageEvt += (_, args) =>
            {
                if (args.Sender.Id == otherQQ)
                {
                    var obfs = new ImageObfuscator();
                    var msg  = args.Chain;
                    if (msg.FirstOrDefault(c => c is ImageMessage) is not ImageMessage imageMessage)
                    {
                        return(Task.FromResult(true));
                    }
                    var imageBytes = new HttpClient().GetByteArrayAsync(imageMessage.Url).Result;

                    superStream.SendMessage(obfs.Deobfuscate(new MagickImage(imageBytes, MagickFormat.Png)));
                }

                return(Task.FromResult(true));
            };
            await serverStream.AuthenticateAsClientAsync("", new X509Certificate2Collection(new[] { cert }), SslProtocols.Tls12, false);

            _ = Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    var buffer = new Span <byte>(new byte[1024]);
                    var i      = serverStream.Read(buffer);
                    if (i > 0)
                    {
                        AddMessage($"接收到了: {Encoding.UTF8.GetString(buffer.Slice(0, i))}");
                    }
                }
            }, TaskCreationOptions.LongRunning);
        }
Ejemplo n.º 17
0
        public static async Task Main()
        {
            AppDomain.CurrentDomain.UnhandledException += (_, e) => ErrorHelper.WriteErrorLog(e.ExceptionObject);

            Console.WriteLine("葱葱机器人");

            if (!File.Exists(Cache.JsonConfigFileName))
            {
                Console.WriteLine("初次使用本机器人,请先设置config.json相关参数。");
            }

            Console.WriteLine("请输入机器人QQ号:");
            long qqId = Convert.ToInt64(Console.ReadLine());

            Console.WriteLine("请输入mirai-api-http host IP:");
            string ip = Console.ReadLine();

            Console.WriteLine("请输入mirai-api-http端口:");
            int port = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("请输入mirai-api-http autoKey:");
            string autoKey = Console.ReadLine();

            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(ip, port, autoKey);

            await using MiraiHttpSession session = new MiraiHttpSession();
            session.AddPlugin(new TempMessage());
            session.AddPlugin(new FriendMessage());
            session.AddPlugin(new GroupMessage());
            bool stop = false;
            await session.ConnectAsync(options, qqId).ContinueWith(callback =>
            {
                if (callback.IsFaulted)
                {
                    stop = true;
                    Console.WriteLine("连接失败,请检查Mirai是否已经正常启动并已配置mirai-api-http相关参数。");
                }
            });

            if (stop)
            {
                return;
            }

            Cache.SetTaskAtFixedTime();

            string nickname = (await session.GetFriendListAsync()).Where(m => m.Id == qqId).FirstOrDefault().Name;

            Console.WriteLine($"已连接到mirai-api-http, 登录昵称:{nickname}, 输入exit或按下Ctrl+C断开连接。");

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 18
0
        static async Task Main(string[] args)
        {
            var lines = File.ReadAllLines("students.csv", Encoding.UTF8);

            foreach (var line in lines.Where(l => l.NotNullNorWhiteSpace()))
            {
                var sp    = line.Split(',');
                var id    = sp[0];
                var stdid = sp[1];
                var name  = sp[2];
                PreRegisteredStudents.Add(new Student(null, id.ToInt(), stdid, name));
            }

            var options = new MiraiHttpSessionOptions("127.0.0.1", 8080, Config.Instance.AuthCode);
            var qq      = Config.Instance.QQ;

            mirai = new MiraiHttpSession();

            await mirai.ConnectAsync(options, qq);

            mirai.FriendMessageEvt  += OnFriendMessage;
            mirai.NewFriendApplyEvt += (sender, eventArgs) =>
            {
                mirai.HandleNewFriendApplyAsync(eventArgs, FriendApplyAction.Allow, "略略略");
                Thread.Sleep(5000);
                SendPrivate(eventArgs.FromQQ.ToString(), $"使用[注册 名字]来注册 如输入 '注册 小明' \n" +
                            $"使用[上传图片]来开始上传图片, 在输入上传图片后 发送的下一张图片将会被保存.\n" +
                            $"以上内容均不包含括号'[]'\n" +
                            $"Written by Cyl18 2020 https://github.com/Cyl18/");
                return(Task.FromResult(true));
            };
            mirai.DisconnectedEvt += async(sender, exception) =>
            {
                while (true)
                {
                    try
                    {
                        await mirai.ConnectAsync(options, qq); // 连到成功为止, QQ号自填, 你也可以另行处理重连的 behaviour

                        return(true);
                    }
                    catch (Exception)
                    {
                        await Task.Delay(1000);
                    }
                }
            };

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    return;
                }
            }
        }
Ejemplo n.º 19
0
        public static async Task <long[]> GetManagersAsync(HttpClient client, MiraiHttpSessionOptions options, long qqNumber, CancellationToken token = default)
        {
            string json = await client.GetAsync($"{options.BaseUrl}/managers?qq={qqNumber}", token).GetStringAsync(token);

            if (!string.IsNullOrEmpty(json))
            {
                return(JsonSerializer.Deserialize <long[]>(json) !);
            }
            return(Array.Empty <long>());
        }
Ejemplo n.º 20
0
        public override void Init()
        {
            var config  = MiraiConfig.Instance;
            var qq      = config.BotQQ;
            var host    = config.Host;
            var port    = config.Port;
            var authKey = config.AuthKey;

            if (Directory.Exists("WFBotImageCaches"))
            {
                Directory.Delete("WFBotImageCaches", true);
            }

            if (qq == default || host == default || port == default || authKey == default)
            {
                // todo 直接控制台写
                throw new InvalidOperationException("请在 MiraiConfig.json 内补全信息, 详情请查看文档.");
            }

            var options = new MiraiHttpSessionOptions(host, port, authKey); // 至少八位数

            session = new MiraiHttpSession();
            session.GroupMessageEvt += (sender, args) =>
            {
                var msg = args.Chain.GetPlain();
                ReportGroupMessage(args.Sender.Group.Id, args.Sender.Id, msg);
                return(Task.FromResult(true));
            };

            session.FriendMessageEvt += (sender, args) =>
            {
                var msg = args.Chain.GetPlain();
                ReportFriendMessage(args.Sender.Id, msg);
                return(Task.FromResult(true));
            };

            session.DisconnectedEvt += async(sender, exception) =>
            {
                while (true)
                {
                    try
                    {
                        Console.WriteLine("Mirai 连接断开, 正在重连...");
                        await session.ConnectAsync(options, qq);

                        return(true);
                    }
                    catch (Exception)
                    {
                        await Task.Delay(1000);
                    }
                }
            };
            session.ConnectAsync(options, qq).Wait();
        }
Ejemplo n.º 21
0
        static void Main(string[] args)
        {
            Console.WriteLine("[QQ]配置初始化...");
            session = new MiraiHttpSession();
            if (!File.Exists("mirai.conf"))
            {
                JObject jb = new JObject();
                jb.Add("host", "127.0.0.1");
                jb.Add("port", 1234);
                jb.Add("auth", "passw0rd");
                File.WriteAllText("mirai.conf", jb.ToString());
            }
            string  config = File.ReadAllText("mirai.conf");
            JObject conf   = JObject.Parse(config);

            options = new MiraiHttpSessionOptions(conf.Value <string>("host"), conf.Value <int>("port"), conf.Value <string>("auth"));
            Console.WriteLine("[QQ]等待Mirai...");
            session.ConnectAsync(options, qq).Wait();
            session.DisconnectedEvt   += Session_DisconnectedEvt;
            session.FriendMessageEvt  += Session_FriendMessageEvt;
            session.NewFriendApplyEvt += Session_NewFriendApplyEvt;
            Console.WriteLine("[QQ]已连接");
            SignQueueHandler.session = session;
            if (File.Exists("./database.bin"))
            {
                Console.WriteLine("[Queue]加载保存的队列...");
                try
                {
                    SignQueueHandler.Load();
                    Console.WriteLine("[Queue]已加载" + SignQueueHandler.queue.Count + "个用户数据");
                }
                catch (Exception err)
                {
                    Console.WriteLine("[Queue]加载失败:" + err.Message + "\n" + err.StackTrace);
                }
            }
            while (true)
            {
                try
                {
                    DateTime start = DateTime.Now;
                    Console.WriteLine("[Timer] 计时器开始:" + start);
                    SignQueueHandler.__ProceedQueue();
                    SignQueueHandler.Save();
                    Console.WriteLine("[Timer] 计时器结束:" + DateTime.Now + ", 用时" + (DateTime.Now - start).Seconds + "秒");
                    Thread.Sleep(10 * 60 * 1000);
                }
                catch (Exception err)
                {
                    Console.WriteLine("[EXCEPTION] 消息循环内出现意外错误");
                    DumpError(err);
                }
            }
        }
Ejemplo n.º 22
0
        private static Task VerifyAsync(HttpClient client, MiraiHttpSessionOptions options, Version apiVersion, InternalSessionInfo session, CancellationToken token = default)
        {
            var payload = new
            {
                sessionKey = session.SessionKey,
                qq         = session.QQNumber
            };
            string url = apiVersion.Major >= 2 ? $"{options.BaseUrl}/bind" : $"{options.BaseUrl}/verify";

            return(client.PostAsJsonAsync(url, payload, token).AsApiRespAsync(token));
        }
Ejemplo n.º 23
0
        /// <summary>
        /// 异步获取给定QQ的Managers
        /// </summary>
        /// <exception cref="BotNotFoundException"/>
        /// <exception cref="InvalidAuthKeyException"/>
        /// <param name="options">连接信息</param>
        /// <param name="qqNumber">机器人QQ号</param>
        /// <param name="token">用于取消操作的Token</param>
        /// <returns>能够管理此机器人的QQ号数组</returns>
        public static async Task <long[]> GetManagersAsync(MiraiHttpSessionOptions options, long qqNumber, CancellationToken token = default)
        {
            using JsonDocument j = await HttpHelper.HttpGetAsync($"{options.BaseUrl}/managers?qq={qqNumber}").GetJsonAsync(token: token);

            JsonElement root = j.RootElement;

            if (root.ValueKind == JsonValueKind.Object && root.TryGetProperty("code", out JsonElement code)) // 正常返回是没有code的
            {
                return(ThrowCommonException <long[]>(code.GetInt32(), in root));
            }
            return(Utils.Deserialize <long[]>(in root));
        }
Ejemplo n.º 24
0
        public QClient(string addr, int port, string passwd, long account)
        {
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(addr, port, passwd);

            session       = new MiraiHttpSession();
            handler       = new EventHandler(this);
            conversations = new List <Conversation>();
            session.ConnectAsync(options, account).Wait();
            friends = session.GetFriendListAsync().Result.ToList();
            groups  = session.GetGroupListAsync().Result.ToList();
            session.AddPlugin(handler);
        }
        private static async Task <string> AuthorizeAsync(HttpClient client, MiraiHttpSessionOptions options)
        {
            using JsonDocument j = await client.PostAsJsonAsync($"{options.BaseUrl}/auth", new { authKey = options.AuthKey }).GetJsonAsync();

            JsonElement root = j.RootElement;
            int         code = root.GetProperty("code").GetInt32();

            return(code switch
            {
                0 => root.GetProperty("session").GetString() !,
                _ => throw GetCommonException(code, in root)
            });
Ejemplo n.º 26
0
        private static async Task <string> AuthorizeAsync(MiraiHttpSessionOptions options)
        {
            byte[] payload = JsonSerializer.SerializeToUtf8Bytes(new { authKey = options.AuthKey });
            using JsonDocument j = await HttpHelper.HttpPostAsync($"{options.BaseUrl}/auth", payload).GetJsonAsync();

            JsonElement root = j.RootElement;
            int         code = root.GetProperty("code").GetInt32();

            return(code switch
            {
                0 => root.GetProperty("session").GetString(),
                _ => ThrowCommonException <string>(code, in root)
            });
Ejemplo n.º 27
0
        public async Task Main(long qqId, string ip, int port, string autoKey)
        {
            MiraiHttpSessionOptions options = new MiraiHttpSessionOptions(ip, port, autoKey);

            await using MiraiHttpSession session = new MiraiHttpSession();
            session.AddPlugin(new TempMessage());
            session.AddPlugin(new FriendMessage());
            session.AddPlugin(new GroupMessage());
            bool stop = false;
            await session.ConnectAsync(options, qqId).ContinueWith(callback =>
            {
                if (callback.IsFaulted)
                {
                    stop = true;
                    MessageBox.Show("连接失败,请检查Mirai是否已经正常启动并已配置mirai-api-http相关参数。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            });

            if (stop)
            {
                return;
            }

            Cache.SetTaskAtFixedTime();

            string nickname = (await session.GetFriendListAsync()).Where(m => m.Id == qqId).FirstOrDefault().Name;

            Invoke(new Action(() =>
            {
                lblState.Text      = $"连接状态: 已连接到mirai-api-http, 登录昵称:{nickname}";
                lblState.ForeColor = Color.Black;
                btnConnect.Text    = "断开连接";
                btnConnect.Click  -= btnConnect_Click;
                btnConnect.Click  += btnDeconnect_Click;
            }));

            while (true)
            {
                if (await Console.In.ReadLineAsync() == "exit")
                {
                    Invoke(new Action(() =>
                    {
                        btnConnect.Text    = "连接到mirai-api-http";
                        lblState.Text      = "连接状态: 未连接到mirai-api-http";
                        lblState.ForeColor = Color.Red;
                    }));
                    return;
                }
            }
        }
Ejemplo n.º 28
0
        /// <param name="client">要进行请求的 <see cref="HttpClient"/></param>
        /// <param name="options">连接信息</param>
        /// <inheritdoc cref="GetVersionAsync(CancellationToken)"/>
        public static async Task <Version> GetVersionAsync(HttpClient client, MiraiHttpSessionOptions options, CancellationToken token = default)
        {
            using JsonDocument j = await client.GetAsync($"{options.BaseUrl}/about", token).GetJsonAsync(token).ConfigureAwait(false);

            JsonElement root = j.RootElement;

            root.EnsureApiRespCode();
            string version = root.GetProperty("data").GetProperty("version").GetString() !;
            int    vIndex  = version.IndexOf('v');

#if NETSTANDARD2_0
            return(Version.Parse(vIndex != -1 ? version.Substring(vIndex) : version));        // v1.0.0 ~ v1.7.4, skip 'v'
#else
            return(Version.Parse(vIndex != -1 ? version.AsSpan()[(vIndex + 1)..] : version)); // v1.0.0 ~ v1.7.4, skip 'v'
Ejemplo n.º 29
0
        private async Task StartReceiveCommandLoopAsync(MiraiHttpSessionOptions options, InternalSessionInfo session, CancellationToken connectToken, CancellationToken token)
        {
            ClientWebSocket ws = new ClientWebSocket();

            try
            {
                await ws.ConnectAsync(new Uri($"ws://{_options.Host}:{_options.Port}/command?verifyKey={options.AuthKey}&sessionKey={session.SessionKey}"), connectToken).ConfigureAwait(false);

                ReceiveMessageLoop(ws, session, token);
            }
            catch
            {
                ws.Dispose();
                throw;
            }
        }
Ejemplo n.º 30
0
        static async Task Main(string[] args)
        {
            var options = new MiraiHttpSessionOptions(Host, Port, AuthKey);

            await using var session = new MiraiHttpSession();
            await session.ConnectAsync(options, QQNum);

            session.GroupMessageEvt += MessageQueueListener.Listener;
            session.AddPlugin(new Commands.GroupCommandForwarder());
            session.AddPlugin(new Commands.TempCommandForwarder());
            Tests.TestRuner.Run();
            while (true)
            {
                if (await Console.In.ReadLineAsync() == "quit")
                {
                    return;
                }
            }
        }