Ejemplo n.º 1
0
        /// <summary>
        /// 获取群名片提示。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        public static string GetHintMessage(string name, string card)
        {
            string hint;

            if (OsuHelper.DiscoverUsernames(card).Any(u => u.Equals(name, StringComparison.OrdinalIgnoreCase)))
            {
                hint = null;
            }
            // 用户名不行。
            else if (card.Contains(name, StringComparison.OrdinalIgnoreCase))
            {
                // 临时忽略。
                hint  = "建议修改群名片,不要在用户名前后添加可以被用做用户名的字符,以免混淆。";
                hint += "\r\n" + "建议群名片:" + RecommendCard(card, name);
            }
            else
            {
                hint = "为了方便其他人认出您,请修改群名片,必须包括正确的 osu! 用户名。";
            }

            return(hint);
        }
        private async Task ParseInfoAsync(
            HttpApiClient api,
            Endpoint sendBackEndpoint,
            GroupRequest r,
            int?osuId = null,
            TrustedUserInfo userInfo = default)
        {
            long   userId  = r.UserId;
            string comment = r.Comment;
            var    hints   = new List <Message>();

            if (!string.IsNullOrEmpty(comment))
            {
                var userNames = OsuHelper.DiscoverUsernames(comment).Where(n => !string.Equals(n, "osu", StringComparison.OrdinalIgnoreCase));
                if (osuId != null)
                {
                    bool success = userInfo != null; // 由于当前未从调用方法处获得上级 API 是否调用成功,在信息不为 null 时默认成功。
                    if (userInfo == null)
                    {                                // 可能的重试。
                        (success, userInfo) = await OsuApi.GetUserInfoAsync(osuId.Value, Mode.Standard).ConfigureAwait(false);
                    }
                    _ = await ProcessApplicantReportAsync(hints, null, (success, userInfo)).ConfigureAwait(false);

                    if (userInfo != null && !userNames.Any(n => string.Equals(userInfo.Name, n, StringComparison.OrdinalIgnoreCase)))
                    {// 绑定不一致
                        hints.Add(new Message("警告:其绑定的账号与申请不符。"));
                    }
                }
                else
                {// 忽略已绑定的情况,因为可能绑定不一致或者查询失败。
                    foreach (var name in userNames)
                    {
                        var userTuple = await OsuApi.GetUserInfoAsync(name, Bleatingsheep.Osu.Mode.Standard);

                        //// 我想用 8.0 新语法
                        //hints.Add(new Message($"{info?.Name ?? name}: " +
                        //    $"{(success ? info == null ? "不存在此用户。" : $"PP: {info.Performance}, PC: {info.PlayCount}, TTH: {info.TotalHits}" : "查询失败。")}"));

                        var info = await ProcessApplicantReportAsync(hints, name, userTuple).ConfigureAwait(false);

                        if (info == null)
                        {// 属于没有查到的情况(因为网络问题或者用户不存在),并且之前已经给出错误信息。
                            continue;
                        }

                        // 自动绑定,在请求消息完全匹配 osu! 用户名的前提下。
                        if (userNames.Count() == 1 &&
                            comment.TrimEnd().EndsWith($"答案:{name}", StringComparison.Ordinal) &&
                            info != null)
                        {
                            var bindingResult = await Database.AddNewBindAsync(
                                qq : r.UserId,
                                osuId : info.Id,
                                osuName : info.Name,
                                source : "Auto (Request)",
                                operatorId : r.UserId,
                                operatorName : info.Name).ConfigureAwait(false);

                            if (bindingResult.Success)
                            {
                                hints.Add(new Message($"自动绑定为 {info.Name}"));
                                goto binding_end;
                            }
                            else
                            {
                                hints.Add(new Message($"自动绑定失败。"));
                            }
                        }
                        // 提供绑定并放行的捷径。
                        if (info?.Performance < 2500)
                        {
                            var ms = new MemoryStream();
                            using (var bw = new BinaryWriter(ms, Encoding.UTF8, true))
                            {
                                bw.Write(userId);
                                bw.Write(info.Id);
                                bw.Write(r.Flag);
                            }
#pragma warning disable CA5351 // 不要使用损坏的加密算法
                            using var md5 = MD5.Create();
#pragma warning restore CA5351 // 不要使用损坏的加密算法
                            ms.Write(md5.ComputeHash(ms.ToArray()));
                            var bytes  = ms.ToArray();
                            var base64 = Convert.ToBase64String(bytes);
                            await api.SendMessageAsync(sendBackEndpoint, $"(占位)绑定为 {info.Name} 并放行:#{base64}#");
                        }
                        binding_end :;
                    }
                }
            }
            if (hints.Count > 0)
            {
                var newLine = new Message("\r\n");
                await api.SendMessageAsync(sendBackEndpoint, hints.Aggregate((m1, m2) =>
                {
                    return((m1.Sections.LastOrDefault()?.Type, m2.Sections.FirstOrDefault()?.Type) switch
                    {
                        ("text", "text") => m1 + newLine + m2,
                        _ => m1 + m2,
                    });
                })).ConfigureAwait(false);