using System.Text; using dodohold.core; using System.Text.RegularExpressions; using System.Net; using System.Linq; using System.Security.Cryptography; using TencentCloud.Ecm.V20190719.Models; using System.Diagnostics; using static dodohold.core.ZTOExpress.CreateOrderArgs; namespace molilian.core { public partial class AlimamaPlus { private string _accountName; private int _accountId; private string _company; private string _tb_token; private string _floorId; private string _refpid; private string _user_agent; private string _cookies; private WebProxy? _proxy = null; private string _api; private int _api_id = 0; public TkConfigDTO _config; private static string _end_point; static Random _random = new Random(); public static string _url_pattern = @"https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]"; static AlimamaPlus() { _end_point = Environment.GetEnvironmentVariable("EndPoint"); } public AlimamaPlus(TkPoolDTO account) { // string accountName, string tb_token, string floorId, string refpid, // string cookies, string user_agent, string nodeName _config = TkConfigCore.Get(); _accountId = account.id; _accountName = account.name; _company = account.company; _tb_token = account.tb_token; _floorId = account.floorId; _refpid = account.refpid; _cookies = account.cookies; _user_agent = account.user_agent; if (!string.IsNullOrEmpty(account.nodeName)) { _proxy = ProxyNodesCore.GetOne(account.nodeName); } _api = account.api; _api_id = account.api_id; } public bool ShouldIgnoreOtherAff(string content) { TkDataDTO result = new(); //(_, _, var link_type, _) = InternalTextProcessing(content, ref result); InternalTextProcessing(content, ref result); return result.link_type == LinkTypeEnum.other_aff; } public TkDataDTO UnionParse(string content, ref TkDataDTO result) { InternalTextProcessing(content, ref result); //(result.success, result.content, result.link_type, result.shortLinkurl) = InternalTextProcessing(content,ref result); if (result.link_type == LinkTypeEnum.other_aff) { result.channel = TkChannelEnum.tb; result.channel_type = ChannelTypeEnum.tb; result.link_type = LinkTypeEnum.unknown; result.success = false; result.message = "放弃转链"; result.reason = "其他推广链接"; result.accountName = string.Empty; result.content = content; result.deeplink_url = GetDeeplink(null); result.itemName = GetTitle(content); } else { //处理过后的正文 用于转链 if (result.success) content = result.content; result = alimamaParse(content, result); } result.content = content; result.link_type = result.link_type; return result; } public async Task UnionParseAsync(string content, TkDataDTO result, CancellationToken cancellationToken = default, Dictionary swData = null) { result.itemName = "点击打开淘宝APP"; result = await InternalTextProcessingAsync(content, result, cancellationToken, swData); if (result.link_type == LinkTypeEnum.other_aff) { //============================== 其他推广链接 ============================== result.channel = TkChannelEnum.tb; result.channel_type = ChannelTypeEnum.tb; result.link_type = LinkTypeEnum.other_aff; result.success = false; result.message = "放弃转链"; result.reason = "其他推广链接"; result.accountName = string.Empty; result.content = content; result.deeplink_url = GetDeeplink(null); //result.itemName = GetTitle(content); return result; } //处理过后的正文 用于转链 if (!result.success) { return result; } //============================== 放弃转链-地区过滤 ============================== bool is_ignore2 = FlowControlIgnoreRequest(out string reason); if (is_ignore2) { result.success = false; result.message = "放弃转链"; result.reason = reason; return result; } result = await alimamaParseAsync(result.content, result, cancellationToken); if (!result.success) { result.itemName = "点击打开淘宝APP"; } if (string.IsNullOrEmpty(result.itemName) || result.link_type == LinkTypeEnum.profile) { result.itemName = "点击打开淘宝APP"; } return result; } public static string ReplaceUrls(string content, string shortLink) { if (string.IsNullOrEmpty(content) || string.IsNullOrEmpty(shortLink)) return content; string result = content; Regex regex = new(_url_pattern); MatchCollection matches = regex.Matches(content); foreach (Match m in matches.Cast()) { string url = m.Value; if (url.Contains("https://s.tb.cn/") || url.Contains("http://s.tb.cn/") || url.Contains("http://m.tb.cn/") || url.Contains("http://m.tb.cn/")) { result = result.Replace(url, shortLink); } } return result; } public static string RemoveUrls(string content) { if (string.IsNullOrEmpty(content)) return content; string result = content; Regex regex = new(_url_pattern); MatchCollection matches = regex.Matches(content); foreach (Match m in matches.Cast()) { string url = m.Value; result = result.Replace(url, string.Empty); } return result; } public static string GetLink(string content) { if (string.IsNullOrEmpty(content)) return content; //string pattern = @"https?:\/\/?([\da-z\.-]+)\.([a-z]{2,6})(:\d{1,5})?([\/\w\.-]*)*\/?(#[\S]+)?(\?[\S]+)?"; Regex regex = new(_url_pattern); MatchCollection matches = regex.Matches(content); string result = string.Empty; if (matches.Count > 0) { result = matches[^1].Value; // 返回第一个匹配到的 URL } result = result.Replace(" ", ""); return result; } public static string GetTaobaoLink(string content) { if (string.IsNullOrEmpty(content)) return content; string result = content; string pattern = @"(https?://(?:[\w-]+\.)*(?:tb\.cn|taobao\.com|juhuasuan\.com|tmall\.com|tmall\.hk)(?:/[a-zA-Z0-9\-\._~:/?#[\]@!$&'()*+,;=%]*)?)"; Regex regex = new(pattern, RegexOptions.IgnoreCase); MatchCollection matches = regex.Matches(content); if (matches.Count > 0) { return matches[^1].Value; // 返回第一个匹配到的 URL } return string.Empty; } public static string GetDeeplink(string url) { if (string.IsNullOrEmpty(url)) return "tbopen://m.taobao.com/tbopen/index.html"; string result = $"tbopen://m.taobao.com/tbopen/index.html?action=ali.open.nav&module=h5&h5Url={url.UrlEncode()}"; //string result = $"tbopen://m.taobao.com/tbopen/index.html?action=ali.open.nav&module=h5&bootImage=0&afcPromotionOpen=false&bc_fl_src=h5_huanduan&source=slk_dp&h5Url={url.UrlEncode()}"; return result; } public static string GetTitle(string content) { if (string.IsNullOrEmpty(content)) return string.Empty; string url = GetLink(content); if (!string.IsNullOrEmpty(url)) content = content.Replace(url, string.Empty); content = content.Replace("点击链接直接打开 或者 淘宝搜索直接打开", string.Empty).Trim(); string[] words = Regex.Split(content, @"\s+"); string word = words[^1]; word = word.TrimStart('「').TrimEnd('」'); return word; } public static bool IgnoreRegionIncluded(string _ignoreRegions, string? ipInfo, out string regionInfo) { regionInfo = string.Empty; if (string.IsNullOrEmpty(_ignoreRegions) || string.IsNullOrEmpty(ipInfo)) return false; string[] parts = ipInfo.Split('|'); string countryInfo = null; if (parts.Length >= 4) { countryInfo = parts[0]; regionInfo = parts[3]; } if (string.IsNullOrEmpty(regionInfo)) return false; if (string.IsNullOrEmpty(countryInfo)) return false; string[] ignoreRegions = _ignoreRegions.Split('|'); if (ignoreRegions.Contains(regionInfo)) return true; if (ignoreRegions.Contains(countryInfo)) { regionInfo = countryInfo; return true; } foreach (var region in ignoreRegions) { if ("海外".Equals(region) && !"中国".Equals(countryInfo) && !"0".Equals(countryInfo)) { regionInfo = "海外"; return true; } } return false; } public static async Task OtherPlatformAsync(string content) { try { //腾讯会议 string wemeetId = await ToolParsePlus.GetWemeetIdAsync(content); if (!string.IsNullOrEmpty(wemeetId)) return true; //百度网盘 string surl = string.Empty, pwd = string.Empty; _ = ToolParsePlus.GetPanLink(content, ref surl, ref pwd); if (!string.IsNullOrEmpty(surl)) return true; //JD string url = JdUnionPlus.GetLink(content); var urlType = JdUnionPlus.GetLinkType(url, out _, out _); if (urlType != LinkTypeEnum.unknown) return true; //DY url = DyUnionPlus.GetLink(content); urlType = DyUnionPlus.GetLinkType(content, url); if (urlType != LinkTypeEnum.unknown) return true; } catch { } return false; } public static bool MatchRegexes(string text, List extended) { text = RemoveUrls(text); string special_symbols = $"\\$\\(\\)\\/\\#\\&\\<\\>฿¢¥¥$🗝₰₵₲¤₪₴€₤£₳《¢💰🔑🎵✔💲🔐📲"; string[] base_patterns = [ $@"(.*?\d{{2}}\s[a-zA-Z]{{2}}\d{{4}}\s.*?[{special_symbols}]+[a-zA-Z0-9\s]+[{special_symbols}]).*", $@"[{special_symbols}]+\s*([a-zA-Z]{{1,2}}\d{{2,4}}\s[a-zA-Z0-9]{{11}}|[a-zA-Z0-9]{{11}}[a-zA-Z]{{1,2}}\d{{2,4}}\s|[a-zA-Z0-9]{{11}})\s*[{special_symbols}]+", @"🍑♭ɑ◑下单|Tao宝" ]; List mergedArray = extended.Union(base_patterns).ToList(); /* (.*?\\d{2}\\s[a-zA-Z]{2}\\d{4}\\s.*?[\\$\\(\\)\\/\\#\\&\\<\\>฿¢¥¥$🗝₰₵₲¤₪₴€₤£₳《¢💰🔑🎵✔💲🔐📲]+[a-zA-Z0-9\\s]+[\\$\\(\\)\\/\\#\\&\\<\\>฿¢¥¥$🗝₰₵₲¤₪₴€₤£₳《¢💰🔑🎵✔💲🔐📲])).*\n[\\$\\(\\)\\/\\#\\&\\<\\>฿¢¥¥$🗝₰₵₲¤₪₴€₤£₳《¢💰🔑🎵✔💲🔐📲]+\\s*([a-zA-Z]{1,2}\\d{2,4}\\s[a-zA-Z0-9]{11}|[a-zA-Z0-9]{11}[a-zA-Z]{1,2}\\d{2,4}\\s|[a-zA-Z0-9]{11})\\s*[\\$\\(\\)\\/\\#\\&\\<\\>฿¢¥¥$🗝₰₵₲¤₪₴€₤£₳《¢💰🔑🎵✔💲🔐📲]+\n🍑♭ɑ◑下单|Tao宝 【3瓶】恩威万蓝莓叶黄素酯软糖儿童成人上班族如酸涩肿胀可服用,:// HU7709,打開/ 置顶小助手,方便下次查询\r\n1★【劵】无\r\n2★【返.佣】 0.29圆 \r\n3★【付款.价】24.9 圆\r\n \r\n 1 ¢HZv5WAboi0D¢(/:/ HU8866\r\ n长按覆制本内容,打开TaoBao/\r\n-\r\n返佣是指商家的推广佣.金\r\n通过我回复的口令下単收货后,我 会微信红.苞返给你!!\r\n\r\n有疑问可回复“人工”咨询客服*/ //🍑🔗上 水和肌精华水& CZ0 VWdCWC2gj97&, //6฿04ZDWzrwxjN)/ CA97 //1😘 腹制这条(CZ00 iHvtWzrXa7O(:/ //¥EC8DG4Zj0dhd8DOw¥MF6563 oIo0WzOF1Cp##X-PyVpHiPlyj1OP## //6.6₵vU2jWzIW3Qx₲/ CZ5224 //$F56nWzIDSFZ$ //0復製这条口令( CZ00 D0M4WzI0jFJ¢,📱咑開[Tao宝]就可下单:/ //8fuzhi本条消息:¤ CZ3458 JSR1WzrPCBU¤,打开🍑♭ɑ◑下单/ //5€Lz6SWzrkLDw¥:// CZ13 //3₲Igq3Wzkc5np₳:// CZ15 //9.9🎈【康师傅易拉罐6罐】口伶:6₰TnxKWzr0wff₪:// CZ69 //4₲99Y0WzJdK6S₳:// CZ46 //4fuzhi本条消息:¤ CZ0002 WVCSWzrk6Ix¤,打开🍑♭ɑ◑下单/ bool anyMatch = false; foreach (string pattern in mergedArray) { if (Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase)) { anyMatch = true; } } return anyMatch; } public static bool MatchOtherInfo(string text, List extended) { string[] base_patterns = [ "[ďȌƯƔɪƝɖƟɏƖԂȎȗϓɫɧơȲǏđǫƲƳɨǹƊȮǚƴɬɲƿȖȳɳɗʮϔӢǙɦɒɎƥʘưΊƞǪȈʠΌǓϒίȠƠƱƗǸþŌŬÿĩŅÞÓũŸÎŎûįŇĎÖÙŷÏňÜÝÍñĎÒüŶľńĎ0ųŷÏŇdǒǔyí℡抖yí℡ÞŐûŷÌñ]{6}", @"(?:.+)极速版(?:口令|搜索)", @"##[a-zA-Z0-9]+##\[抖音(?:极速版)?(?:口令|搜索)\]", @"岽|亰|菄|京东|婛", "打开【剪映】", "weishi://|baiduhaokan://", "复制打开「UC浏览器」|UC瀏覽器", "番茄免费小说", @"\?chanTag=[^&\s]*口令", @"(https?://pan\.baidu\.com/s/[A-Za-z0-9?\-_=]+)", @"https?:\/\/meeting\.tencent\.com[^\s]*", @"#腾讯会议:(\d{3}-\d{3}-\d{3})" ]; List mergedArray = extended.Union(base_patterns).ToList(); bool anyMatch = false; foreach (string pattern in mergedArray) { if (Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase)) { anyMatch = true; } } return anyMatch; } public static bool MatchMultiToken(string text, List extended) { text = RemoveUrls(text); string special_symbols = $"\\$\\(\\)\\/\\#\\&\\<\\>฿¢¥¥$🗝₰₵₲¤₪₴€₤£₳《¢💰🔑🎵✔💲🔐📲"; string[] base_patterns = [ @"[!$¥%]+([a-zA-Z0-9]{16})[!$¥%]+", @"\^v(\d+#[a-zA-Z0-9]+)(?:\?.*)?\^", "##([a-zA-Z0-9\\-]+)##", $@"(.*?\d{{2}}\s[a-zA-Z]{{2}}\d{{4}}\s.*?[{special_symbols}]+[a-zA-Z0-9\s]+[{special_symbols}]).*", $@"[{special_symbols}]+\s*([a-zA-Z]{{1,2}}\d{{2,4}}\s[a-zA-Z0-9]{{11}}|[a-zA-Z0-9]{{11}}[a-zA-Z]{{1,2}}\d{{2,4}}\s|[a-zA-Z0-9]{{11}})\s*[{special_symbols}]+", ]; // PAGE6:/^v130091#P2J6EDxN8p8?chanTag=d9dc522bdea27437514052ea50f6a787^ List mergedArray = extended.Union(base_patterns).ToList(); int matchCount = 0; foreach (string pattern in mergedArray) { Match match = Regex.Match(text, pattern, RegexOptions.IgnoreCase); if (match.Success) { matchCount++; text = text.Replace(match.Groups[^1].Value, ""); // 移除匹配的部分文本 } } return matchCount >= 2; } public static bool FilterRiskLink(string ip, string oaid, string content, out string reason) { reason = string.Empty; string itemId = ExtractItemId(content); if (string.IsNullOrEmpty(itemId)) return false; string cacheKey = $":cache:parse:{ip}_{oaid}_{itemId}"; int flag = RedisHelper.Get(cacheKey); if (flag > 0) { reason = $"口令用户"; return true; } return false; } public static bool ShouldIgnoreRequest(string ip, string oaid, out string reason) { reason = string.Empty; try { // IP和流量控制 var config = TkConfigCore.Get(); string ignorePercentageCity = config.ignorePercentageCity; string? ipInfo = IP2RegionPlus.Search(ip); if (IgnoreRegionIncluded(ignorePercentageCity, ipInfo, out string regionInfo)) { reason = $"地区控制:{regionInfo}"; return true; } } catch (Exception ex) { reason = "配置异常"; } return false; } public static bool FlowControlIgnoreRequest(out string reason) { reason = string.Empty; try { // IP和流量控制 var config = TkConfigCore.Get(); int ignorePercentage = config.ignorePercentage; if (ignorePercentage == 0) return false; var randomValue = (decimal)_random.Next(0, 100); bool result = randomValue <= ignorePercentage; // 如果生成的随机数小于忽略百分比,则返回 true,表示需要忽略请求 if (result) { reason = "流量控制"; return true; } } catch (Exception ex) { reason = $"配置异常"; } return false; } public static TkDataDTO GetFormattedObject(string content, string ip, string oaid) { string shortLinkurl = GetTaobaoLink(content); string deeplink_url = GetDeeplink(shortLinkurl); return new TkDataDTO() { message = string.Empty, channel = TkChannelEnum.tb, accountName = string.Empty, success = false, content = content, link_type = LinkTypeEnum.unknown, ip = ip, oaid = oaid, couponAmount = 0, taoToken = string.Empty, elapsedTime = 0, itemName = "点击打开淘宝APP", shortLinkurl = shortLinkurl, deeplink_url = deeplink_url, create_time = DateTime.Now, end_point = _end_point, }; } public static string OppoDecode(string content) { try { string secretKey = "BwFeIvOEDZy9MFGi0JLZBO4yEhR44DGV"; byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey); if (!content.Contains("%IV%")) return content; string cipherText = content.GetContentPart("", "%IV%"); string ivText = content.GetContentPart("%IV%", ""); byte[] cipherBytes = Convert.FromBase64String(cipherText); byte[] ivBytes = Convert.FromBase64String(ivText); using RijndaelManaged aes = new(); aes.Key = keyBytes; aes.IV = ivBytes; aes.Mode = CipherMode.CFB; aes.Padding = PaddingMode.PKCS7; ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); var outBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length); content = outBytes.ConvertToString(); } catch (Exception e) { } return content; } } }