public string KouCalConstant([KouPluginArgument(Name = "定数/歌曲名[+难度类型]")] string nameOrConstant, [KouPluginArgument(Name = "分数")] int score, [KouPluginArgument(Name = "歌曲ptt反推定数")] double?ptt = null) { if (score < 0 || score > 11000000) { return("这个分数怎么有点奇怪呢"); } string songName = nameOrConstant; if (ptt != null) { return($"{score}分的谱面ptt={ptt}时,谱面定数约为{ArcaeaData.CalSongChartConstant(ptt.Value, score):F3}"); } Song.RatingClass ratingClass = Song.RatingClass.Future; if (songName.MatchOnceThenReplace(@"[,,]?(ftr|pst|prs|byd|byn|future|past|present|beyond)", out songName, out var matched, RegexOptions.IgnoreCase | RegexOptions.RightToLeft)) { KouStringTool.TryToEnum(matched[1].Value, out ratingClass); } if (songName.IsNullOrWhiteSpace()) { return("你在说哪首歌呢"); } var satisfiedSongs = Song.Find(s => s.SongTitle.Contains(songName, StringComparison.OrdinalIgnoreCase) || s.Aliases?.Any(alias => alias.Alias == songName) == true); if (satisfiedSongs.Count > 1) { return($"具体是以下哪一首歌呢(暂时不支持选择id):\n{satisfiedSongs.ToSetString()}"); } if (satisfiedSongs.Count == 0) { if (KouStringTool.TryToDouble(nameOrConstant, out double constant)) { return($"定数{constant}时,{score}分的ptt为{ArcaeaData.CalSongScorePtt(constant, score):F3}"); } return($"找不到哪个歌叫{songName}哦..."); } var song = satisfiedSongs[0]; var songConstant = song.MoreInfo.FirstOrDefault(p => p.ChartRatingClass == ratingClass)?.ChartConstant; if (songConstant == null) { return($"{song.SongTitle}还没有{ratingClass}的定数信息呢..."); } return($"{song.SongTitle}[{ratingClass}{songConstant.Value:0.#}]{score}分的ptt为{ArcaeaData.CalSongScorePtt(songConstant.Value, score):F3}"); }
public string KouCalConstant([KouPluginArgument(Name = "定数/歌曲名[+难度类型]")] string nameOrConstant, [KouPluginArgument(Name = "分数")] int score, [KouPluginArgument(Name = "歌曲ptt反推定数")] double?ptt = null) { if (score < 0 || score > 11000000) { return("这个分数怎么有点奇怪呢"); } if (ptt != null) { return($"{score}分的谱面ptt={ptt}时,谱面定数约为{ArcaeaData.CalSongChartConstant(ptt.Value, score):F3}"); } if (KouStringTool.TryToDouble(nameOrConstant, out double constant)) { return($"定数{constant}时,{score}分的ptt为{ArcaeaData.CalSongScorePtt(constant, score):F3}"); } KouArcaeaInfo kouArcaeaInfo = new KouArcaeaInfo { SongName = nameOrConstant }; var songs = kouArcaeaInfo.GetSatisfiedSong(ratingClass: PluginArcaeaSong.RatingClass.Future); string result = ""; if (songs.Count == 0) { return($"找不到是哪个歌"); } else if (songs.Count > 4) { result = $"具体是指下面哪个歌呢?\n{songs.ToSetString()}"; } else { foreach (var song in songs) { if (song.ChartConstant == null) { continue; } double con = song.ChartConstant.Value; result += $"{song.ToString(FormatType.Brief)} {score}分的ptt为{ArcaeaData.CalSongScorePtt(con, score):F3}\n"; } } return(result.Trim()); }
//Func<T, object, bool> func = (modelInstance, comparePair) => 的lamada表达式被简化为了本地函数 static bool func(T modelInstance, object comparePair) { bool result = true; Dictionary <string, KeyValuePair <object, FilterType> > list = (Dictionary <string, KeyValuePair <object, FilterType> >)comparePair;//[Key属性名 Value[Key属性值,Value过滤类型]] Dictionary <string, KeyValuePair <Type, object> > propertyInfoDict = ReflectionTool.GetAllPropertyInfo <T>(modelInstance); if (propertyInfoDict.IsNullOrEmptySet() || comparePair == null) { return(true); //没东西就不用过滤了 } foreach (var contrastPair in list) { var pair = contrastPair.Value; if (propertyInfoDict.TryGetValue(contrastPair.Key, out KeyValuePair <Type, object> originPair)) { Type propertyType = originPair.Key; object propertyValue = originPair.Value; object contrast = pair.Key; FilterType filterType = pair.Value; var origin = propertyValue;//原始字段值 //当Str类型支持Empty值时符合则匹配 if (filterType.HasFlag(FilterType.SupportStrEmpty) && contrast is string && origin is string && ((string)contrast).IsNullOrEmpty() && ((string)origin).IsNullOrEmpty()) { continue; } //原始值是空的不匹配,除非支持null值匹配 if (!filterType.HasFlag(FilterType.SupportNull) && origin == null) { return(false); } //原始值是值类型且是默认值的不匹配,除非支持默认值 if (origin is ValueType && !filterType.HasFlag(FilterType.SupportValueDefault) && origin.Equals(Activator.CreateInstance(propertyType))) { return(false); } //比较值为空的匹配,因为没有做限制,除非支持null认为null也是限制 if (!filterType.HasFlag(FilterType.SupportNull) && contrast == null) { continue; } //当仅过滤空值、默认值时直接匹配(因为前面已经过滤掉了) if (filterType.HasFlag(FilterType.OnlyFilterNull)) { continue; } if (origin is string) //类型是string的 { string ori = (string)origin; if (ori == string.Empty && !filterType.HasFlag(FilterType.SupportStrEmpty)) { return(false); } string con = (string)contrast; switch (filterType) { case var _ when filterType.HasFlag(FilterType.Exact): //C#7.0特性 case的when约束,要true才会成功case case FilterType.Exact: result &= ori.Equals(con); break; case FilterType.IgnoreCase: result &= ori.Equals(con, StringComparison.OrdinalIgnoreCase); break; case FilterType.Fuzzy: result &= ori.Trim().Contains(con.Trim()); break; case FilterType.FuzzyIgnoreCase: result &= ori.ToLower().Trim().Contains(con.ToLower().Trim()); break; case FilterType.Interval: //转为闭区间类型 result &= ori.TryGetInterval(out double left, out double right, true) && con.TryGetInterval(out double conleft, out double conright, true) && (conleft <= left && right <= conright); break; default: goto case FilterType.FuzzyIgnoreCase; } } else if (origin is double || origin is int && contrast is string)//数值型支持区间表示 { double ori = System.Convert.ToDouble(origin); string con = (string)contrast; if (ZhNumber.IsContainZhNumber(con)) { con = ZhNumber.ToArabicNumber(con); } if (double.TryParse(con, out double num))//直接精确等于 { result &= num == ori; } else if (con.TryGetInterval(out IntervalDouble left, out IntervalDouble right))//区间表示 { if (!(ori >= left && ori <= right)) { return(false); } } else { return(false);//无法转换则不匹配 } } else if (origin is Enum)//支持枚举类过滤 { if (contrast is string con) { result &= Enum.Parse(propertyType, con).Equals(origin); } else { result &= contrast.Equals(origin); } } else if (origin is TimeSpan span && contrast is string con)//支持TimeSpan区间型过滤 { if (con.TryGetTimeSpan(out TimeSpan timeSpan)) { if (timeSpan != span) { return(false); } } else if (con.TryGetTimeSpanInterval(out TimeSpan left, out TimeSpan right)) { if (!(span >= left && span <= right)) { return(false); //不在区间内 } } else//尝试古代时间、现代时间以及中文计数法 { var interval = Regex.Split(con, "(到|[-~,])+"); string rightCon = "";//尝试是否存在第二个以构成区间 bool isRightExist = false; if (interval.Length >= 3) { con = interval[0]; rightCon = interval[2]; isRightExist = true; } TimeSpan zhTimeSpan = new TimeSpan(); bool success = KouStringTool.TryToTimeSpan(con, out zhTimeSpan); if (success && isRightExist)//如果左边成功了尝试是否有第二个构成区间 { TimeSpan zhTimeSpanRight = new TimeSpan(); bool successRight = KouStringTool.TryToTimeSpan(rightCon, out zhTimeSpanRight); if (!successRight || zhTimeSpan > zhTimeSpanRight || span < zhTimeSpan || span > zhTimeSpanRight) { return(false); //原时间间隔不在区间内的不匹配 } } else if (!success || zhTimeSpan != span) { return(false); //时间与原时间间隔的不一致的不匹配 } } } else//其他类型直接比较是否相等 { contrast = System.Convert.ChangeType(contrast, propertyType); result &= contrast.Equals(origin); } if (result == false) { return(false); } } }