public void ProcessGroupMessage(GroupID groupId, UserID senderId, string message)
        {
            // 检查每分钟最大调用
            if (CheckCallPerMin(groupId))
            {
                return;
            }

            // 处理以 '/' 开头的消息
            if (Config.Instance.IsSlashRequired && !message.StartsWith("/"))
            {
                return;
            }
            message = message.TrimStart('/');

            var handler = new GroupMessageHandler(senderId, groupId, message);
            var commandProcessTask
                = Task.Factory.StartNew(() => handler.ProcessCommandInput(), TaskCreationOptions.LongRunning);

            Task.Run(async() =>
            {
                using var locker = WFBotResourceLock.Create(
                          $"命令处理 #{Interlocked.Increment(ref commandCount)} 群'{groupId}' 用户'{senderId}' 内容'{message}'");
                await Task.WhenAny(commandProcessTask, Task.Delay(TimeSpan.FromSeconds(60)));
                if (!commandProcessTask.IsCompleted)
                {
                    SendGroup(groupId, $"命令 {message} 处理超时.");
                }
            });
        }
        public void ProcessGroupMessage(GroupID groupId, UserID senderId, string message)
        {
            // 检查每分钟最大调用
            if (CheckCallPerMin(groupId))
            {
                return;
            }

            // 处理以 '/' 开头的消息
            RunAutoReply(groupId, message);
            if (Config.Instance.IsSlashRequired && !message.StartsWith('/'))
            {
                if (!showedSlashTip)
                {
                    Trace.WriteLine("提示: 设置中要求命令必须以 / 开头. ");
                    showedSlashTip = true;
                }
                return;
            }
            message = message.TrimStart('/', '、', '/');

            var handler = new GroupMessageHandler(senderId, groupId, message);

            // TODO 优化task数量
            // TODO cancellation token
            Task.Run(async() =>
            {
                var sw           = Stopwatch.StartNew();
                var cancelSource = new CancellationTokenSource();
                AsyncContext.SetCancellationToken(cancelSource.Token);
                var sender = new GroupMessageSender(groupId);
                AsyncContext.SetMessageSender(sender);
                var commandProcessTask = handler.ProcessCommandInput();

                using var locker = WFBotResourceLock.Create(
                          $"命令处理 #{Interlocked.Increment(ref commandCount)} 群[{groupId}] 用户[{senderId}] 内容[{message}]");
                await Task.WhenAny(commandProcessTask, Task.Delay(TimeSpan.FromSeconds(60)));

                if (!commandProcessTask.IsCompleted)
                {
                    cancelSource.Cancel();
                    await Task.Delay(10.Seconds());
                    if (!commandProcessTask.IsCompleted)
                    {
                        sender.SendMessage($"命令 [{message}] 处理超时.");
                    }
                    Trace.WriteLine($"命令 群[{groupId}] 用户[{senderId}] 内容[{message}] 处理超时.");
                    return;
                }
#if !DEBUG
                if (commandProcessTask.Result.matched)
                {
                    Trace.WriteLine($"命令 群 [{groupId}] 用户 [{senderId}] 内容 [{message}] 处理完成: {sw.Elapsed.Seconds:N1}s.");
                }
#endif
            });
        }
Exemple #3
0
        public async Task Reload(bool isFirstTime = false)
        {
            using var resourceLock = WFBotResourceLock.Create($"资源刷新 {FileName}");
            try
            {
                await _locker.WaitAsync();

                if (await LoadFromLocal())
                {
                    if (isFirstTime)
                    {
                        Trace.WriteLine($"WFResource: 资源 {FileName} 从本地载入.");
                    }
                    return;
                }

                if (isFirstTime && await LoadCache())
                {
                    Trace.WriteLine($"WFResource: 资源 {FileName} 从缓存载入.");
                    LoadFromTheWideWorldOfWebNonBlocking();
                    return;
                }

                await LoadFromTheWideWorldOfWeb();
            }
            catch (Exception) when(isFirstTime)
            {
                WFResources.ResourceLoadFailed = true;
                throw;
            }
            finally
            {
                _locker.Release();
                if (isFirstTime)
                {
                    initTask = null;
                }
                Interlocked.Increment(ref WFResourceStatic.FinishedResourceCount);
                Console.WriteLine($"资源加载进程: {WFResourceStatic.FinishedResourceCount} / {WFResourceStatic.ResourceCount}.");
            }
        }