|
@@ -0,0 +1,242 @@
|
|
|
|
|
+
|
|
|
|
|
+using dodohold.core;
|
|
|
|
|
+using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
+using Microsoft.Extensions.FileSystemGlobbing.Internal;
|
|
|
|
|
+using Spire.Pdf.Annotations;
|
|
|
|
|
+using System.Text.RegularExpressions;
|
|
|
|
|
+using System.Xml.Linq;
|
|
|
|
|
+namespace molilian.core
|
|
|
|
|
+{
|
|
|
|
|
+ public partial class DeeplinkParseCore
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ private static string _end_point;
|
|
|
|
|
+ private static readonly string[] separators = ["\r\n", "\n"];
|
|
|
|
|
+
|
|
|
|
|
+ static DeeplinkParseCore()
|
|
|
|
|
+ {
|
|
|
|
|
+ _end_point = Environment.GetEnvironmentVariable("EndPoint");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static DeeplinkParseDataDTO GetFormattedObject(string content, string channel, string ip = "", string oaid = "")
|
|
|
|
|
+ {
|
|
|
|
|
+ return new DeeplinkParseDataDTO()
|
|
|
|
|
+ {
|
|
|
|
|
+ message = string.Empty,
|
|
|
|
|
+ success = false,
|
|
|
|
|
+ content = content,
|
|
|
|
|
+ ip = ip,
|
|
|
|
|
+ oaid = oaid,
|
|
|
|
|
+ elapsedTime = 0,
|
|
|
|
|
+ create_time = DateTime.Now,
|
|
|
|
|
+ end_point = _end_point,
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static async Task<ActionResult> ParseAsync(string content, string channel, string ip, string oaid)
|
|
|
|
|
+ {
|
|
|
|
|
+ var result = GetFormattedObject(content, channel, ip, oaid);
|
|
|
|
|
+ content = content.Trim();
|
|
|
|
|
+
|
|
|
|
|
+ var rule = DeeplinkParseRuleCore.GetOne(channel);
|
|
|
|
|
+ if (rule == null)
|
|
|
|
|
+ {
|
|
|
|
|
+ result.success = false;
|
|
|
|
|
+ result.message = "转链失败";
|
|
|
|
|
+ result.reason = "无效平台";
|
|
|
|
|
+
|
|
|
|
|
+ _ = TkLogCore.ParseLogAsync(result);
|
|
|
|
|
+ return new APIResult(new
|
|
|
|
|
+ {
|
|
|
|
|
+ result.success,
|
|
|
|
|
+ result.message,
|
|
|
|
|
+ result.reason,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ result.channel_id = rule.channel_id;
|
|
|
|
|
+ result.channel_name = rule.channel_name;
|
|
|
|
|
+
|
|
|
|
|
+ result = await GenerateDeeplink(content, rule, result);
|
|
|
|
|
+
|
|
|
|
|
+ _ = TkLogCore.ParseLogAsync(result);
|
|
|
|
|
+ return new APIResult(new
|
|
|
|
|
+ {
|
|
|
|
|
+ result.success,
|
|
|
|
|
+ result.message,
|
|
|
|
|
+ channel = result.channel_name,
|
|
|
|
|
+ result.deeplink_url,
|
|
|
|
|
+ result.itemName,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static async Task<DeeplinkParseDataDTO> GenerateDeeplink(string text, DeeplinkParseRuleDTO config, DeeplinkParseDataDTO result)
|
|
|
|
|
+ {
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ var list = config.rules.Convert2Object<List<DeeplinkParseRule>>();
|
|
|
|
|
+
|
|
|
|
|
+ foreach (var rule in list)
|
|
|
|
|
+ {
|
|
|
|
|
+ var e = await WorkEachRule(text, config, result, rule);
|
|
|
|
|
+ if (e != null) return e;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ result.success = false;
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static async Task<DeeplinkParseDataDTO?> WorkEachRule(string text, DeeplinkParseRuleDTO config, DeeplinkParseDataDTO result, DeeplinkParseRule rule)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (!rule.enable) return null;
|
|
|
|
|
+
|
|
|
|
|
+ string content = text;
|
|
|
|
|
+
|
|
|
|
|
+ if (!string.IsNullOrEmpty(rule.url_pattern))
|
|
|
|
|
+ {
|
|
|
|
|
+ var regex = new Regex(rule.url_pattern);
|
|
|
|
|
+ var match = regex.Match(content);
|
|
|
|
|
+ if (!match.Success) return null;
|
|
|
|
|
+
|
|
|
|
|
+ content = match.Groups[1].Value;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ string url = ToolParsePlus.GetLink(text);
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ switch (rule.url_action)
|
|
|
|
|
+ {
|
|
|
|
|
+ case UrlAction.Redirect:
|
|
|
|
|
+ {
|
|
|
|
|
+ var response = await new WebClientUtility
|
|
|
|
|
+ {
|
|
|
|
|
+ Proxy = ProxyNodesCore.RandomOne(),
|
|
|
|
|
+ AllowAutoRedirect = false
|
|
|
|
|
+ }.RequestAsync(url);
|
|
|
|
|
+ if (response.ResponseMessage != null)
|
|
|
|
|
+ {
|
|
|
|
|
+ content = response.ResponseMessage.Headers.Location.ToString();
|
|
|
|
|
+ content = content.UrlDecode();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case UrlAction.Body:
|
|
|
|
|
+ {
|
|
|
|
|
+ var response = await new WebClientUtility
|
|
|
|
|
+ {
|
|
|
|
|
+ Proxy = ProxyNodesCore.RandomOne(),
|
|
|
|
|
+ AllowAutoRedirect = true
|
|
|
|
|
+ }.RequestAsync(url);
|
|
|
|
|
+ content = response.Body();
|
|
|
|
|
+ }
|
|
|
|
|
+ break;
|
|
|
|
|
+ case UrlAction.None:
|
|
|
|
|
+ //{
|
|
|
|
|
+ // content = url;
|
|
|
|
|
+ //}
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ //Console.WriteLine($"{url}\t{rule.url_action}\t{ex.Message}");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (rule.childs.Count > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ foreach (var sub_rule in rule.childs)
|
|
|
|
|
+ {
|
|
|
|
|
+ var e = await WorkEachRule(content, config, result, sub_rule);
|
|
|
|
|
+ if (e != null) return e;
|
|
|
|
|
+ }
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ var deeplink = rule.deeplink_template;
|
|
|
|
|
+ var prompt_text = rule.prompt_text;
|
|
|
|
|
+
|
|
|
|
|
+ try
|
|
|
|
|
+ {
|
|
|
|
|
+ var regex = new Regex(rule.pattern);
|
|
|
|
|
+ var match = regex.Match(content);
|
|
|
|
|
+ if (match.Success)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (match.Groups.Count > 1)
|
|
|
|
|
+ {
|
|
|
|
|
+ for (var i = 1; i < match.Groups.Count; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ string val = match.Groups[i].Value;
|
|
|
|
|
+ if (deeplink.Contains("{url:"))
|
|
|
|
|
+ {
|
|
|
|
|
+ deeplink = deeplink.Replace($"{{url:{i - 1}}}", val.UrlEncode());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (prompt_text.Contains("{url:"))
|
|
|
|
|
+ {
|
|
|
|
|
+ prompt_text = prompt_text.Replace($"{{url:{i - 1}}}", val.UrlEncode());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //atob
|
|
|
|
|
+ if (deeplink.Contains("{atob:"))
|
|
|
|
|
+ {
|
|
|
|
|
+ deeplink = deeplink.Replace($"{{atob:{i - 1}}}", val.FromBase64());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (prompt_text.Contains("{atob:"))
|
|
|
|
|
+ {
|
|
|
|
|
+ prompt_text = prompt_text.Replace($"{{atob:{i - 1}}}", val.FromBase64());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //btoa
|
|
|
|
|
+ if (deeplink.Contains("{btoa:"))
|
|
|
|
|
+ {
|
|
|
|
|
+ deeplink = deeplink.Replace($"{{btoa:{i - 1}}}", val.ToBase64());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (prompt_text.Contains("{btoa:"))
|
|
|
|
|
+ {
|
|
|
|
|
+ prompt_text = prompt_text.Replace($"{{btoa:{i - 1}}}", val.ToBase64());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ deeplink = deeplink.Replace($"{{{i - 1}}}", val);
|
|
|
|
|
+ prompt_text = prompt_text.Replace($"{{{i - 1}}}", val);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ deeplink = Regex.Replace(deeplink, @"\{\d+\}", string.Empty);
|
|
|
|
|
+ prompt_text = Regex.Replace(prompt_text, @"\{\d+\}", string.Empty);
|
|
|
|
|
+
|
|
|
|
|
+ if (!string.IsNullOrEmpty(deeplink))
|
|
|
|
|
+ {
|
|
|
|
|
+ result.deeplink_url = deeplink;
|
|
|
|
|
+ result.itemName = prompt_text;
|
|
|
|
|
+ result.success = true;
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ result.deeplink_url = deeplink;
|
|
|
|
|
+ result.itemName = prompt_text;
|
|
|
|
|
+ result.success = true;
|
|
|
|
|
+ return result;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (Exception ex)
|
|
|
|
|
+ {
|
|
|
|
|
+ Console.WriteLine($"Error processing pattern '{rule.pattern}': {ex.Message}");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return null;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|