mirror of
https://github.com/lampame/lampac-ukraine.git
synced 2026-06-17 12:08:54 +00:00
Compare commits
No commits in common. "3ee62e24f6bd459f154ead65e0c9bab0d13e3e9b" and "6a398317a48551a94d4c416346aa10f8a7792663" have entirely different histories.
3ee62e24f6
...
6a398317a4
@ -169,82 +169,15 @@ namespace LME.AnimeON
|
|||||||
return JsonSerializer.Deserialize<EpisodeModel>(episodesJson);
|
return JsonSerializer.Deserialize<EpisodeModel>(episodesJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region MoonAnime Decryption
|
|
||||||
private static string CleanMoonUrl(string url)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(url))
|
|
||||||
return url;
|
|
||||||
|
|
||||||
string cleaned = Regex.Replace(url, @"([?&])player=[^&]*", "$1", RegexOptions.IgnoreCase);
|
|
||||||
cleaned = cleaned.Replace("?&", "?").Replace("&&", "&").TrimEnd('?', '&');
|
|
||||||
return cleaned;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string MoonDecode(string base64Input)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] raw = Convert.FromBase64String(base64Input);
|
|
||||||
const int KeySize = 32;
|
|
||||||
const int HeaderSize = 1 + KeySize;
|
|
||||||
|
|
||||||
if (raw.Length < HeaderSize)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
byte state = raw[0];
|
|
||||||
byte[] key = new byte[KeySize];
|
|
||||||
Array.Copy(raw, 1, key, 0, KeySize);
|
|
||||||
|
|
||||||
int payloadLen = raw.Length - HeaderSize;
|
|
||||||
byte[] payload = new byte[payloadLen];
|
|
||||||
Array.Copy(raw, HeaderSize, payload, 0, payloadLen);
|
|
||||||
|
|
||||||
for (int i = 0; i < payload.Length; i++)
|
|
||||||
{
|
|
||||||
byte encrypted = payload[i];
|
|
||||||
byte keyByte = key[i % KeySize];
|
|
||||||
|
|
||||||
payload[i] = (byte)(encrypted ^ keyByte ^ state);
|
|
||||||
state = (byte)((encrypted + keyByte) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(payload);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string MoonXorDecrypt(string file, string key)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
|
|
||||||
byte[] data = Convert.FromBase64String(file);
|
|
||||||
|
|
||||||
for (int i = 0; i < data.Length; i++)
|
|
||||||
{
|
|
||||||
data[i] = (byte)(data[i] ^ keyBytes[i % keyBytes.Length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(data);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public async Task<string> ParseMoonAnimePage(string url)
|
public async Task<string> ParseMoonAnimePage(string url)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string requestUrl = CleanMoonUrl(url);
|
string requestUrl = $"{url}?player=animeon.club";
|
||||||
var headers = new List<HeadersModel>()
|
var headers = new List<HeadersModel>()
|
||||||
{
|
{
|
||||||
new HeadersModel("User-Agent", "Mozilla/5.0")
|
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
||||||
|
new HeadersModel("Referer", "https://animeon.club/")
|
||||||
};
|
};
|
||||||
|
|
||||||
_onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {requestUrl}");
|
_onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {requestUrl}");
|
||||||
@ -252,57 +185,13 @@ namespace LME.AnimeON
|
|||||||
if (string.IsNullOrEmpty(html))
|
if (string.IsNullOrEmpty(html))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var atobMatch = Regex.Match(html, @"=atob\(""([^""]+)""\)");
|
|
||||||
if (!atobMatch.Success)
|
|
||||||
{
|
|
||||||
atobMatch = Regex.Match(html, @"=atob\('([^']+)'\)");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atobMatch.Success)
|
|
||||||
{
|
|
||||||
string blob = atobMatch.Groups[1].Value;
|
|
||||||
string decryptedJs = MoonDecode(blob);
|
|
||||||
if (!string.IsNullOrEmpty(decryptedJs))
|
|
||||||
{
|
|
||||||
var keyMatch = Regex.Match(decryptedJs, @"var k=""([^""]+)""");
|
|
||||||
if (!keyMatch.Success)
|
|
||||||
keyMatch = Regex.Match(decryptedJs, @"var k='([^']+)'");
|
|
||||||
|
|
||||||
var fileMatch = Regex.Match(decryptedJs, @"file\s*:\s*_0xd\(""([^""]+)""\)");
|
|
||||||
if (!fileMatch.Success)
|
|
||||||
fileMatch = Regex.Match(decryptedJs, @"file\s*:\s*_0xd\('([^']+)'\)");
|
|
||||||
|
|
||||||
if (keyMatch.Success && fileMatch.Success)
|
|
||||||
{
|
|
||||||
string key = keyMatch.Groups[1].Value;
|
|
||||||
string fileEncrypted = fileMatch.Groups[1].Value;
|
|
||||||
string streams = MoonXorDecrypt(fileEncrypted, key);
|
|
||||||
if (!string.IsNullOrEmpty(streams))
|
|
||||||
{
|
|
||||||
return streams;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var directFileMatch = Regex.Match(decryptedJs, @"file\s*:\s*""([^""]+)""");
|
|
||||||
if (!directFileMatch.Success)
|
|
||||||
directFileMatch = Regex.Match(decryptedJs, @"file\s*:\s*'([^']+)'");
|
|
||||||
|
|
||||||
if (directFileMatch.Success)
|
|
||||||
{
|
|
||||||
return directFileMatch.Groups[1].Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload = PlayerJsDecoder.ExtractPlayerPayload(html);
|
var payload = PlayerJsDecoder.ExtractPlayerPayload(html);
|
||||||
if (payload?.FilePayload != null)
|
if (payload?.FilePayload == null)
|
||||||
{
|
return null;
|
||||||
|
|
||||||
var streamUrls = ExtractStreamUrls(payload.FilePayload);
|
var streamUrls = ExtractStreamUrls(payload.FilePayload);
|
||||||
return streamUrls?.FirstOrDefault();
|
return streamUrls?.FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_onLog($"AnimeON ParseMoonAnimePage error: {ex.Message}");
|
_onLog($"AnimeON ParseMoonAnimePage error: {ex.Message}");
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Shared.Engine;
|
using Shared.Engine;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -439,59 +439,8 @@ namespace LME.AnimeON.Controllers
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
var streamQuality = new StreamQualityTpl();
|
string streamUrl = BuildStreamUrl(init, streamLink, streamHeaders, forceProxy);
|
||||||
string streamUrl = null;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(streamLink) && (streamLink.StartsWith("[") || streamLink.Contains("]http")))
|
|
||||||
{
|
|
||||||
var bracketMatches = Regex.Matches(streamLink, @"\[(?<quality>[^\]]+)\](?<url>https?://[^,\[]+)", RegexOptions.IgnoreCase);
|
|
||||||
foreach (Match match in bracketMatches)
|
|
||||||
{
|
|
||||||
string quality = match.Groups["quality"].Value;
|
|
||||||
string urlVal = match.Groups["url"].Value?.Trim()?.TrimEnd(',');
|
|
||||||
if (string.IsNullOrWhiteSpace(urlVal))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var headers = streamHeaders;
|
|
||||||
if (urlVal.Contains("moonanime.art") || urlVal.Contains("mooncdn.space"))
|
|
||||||
{
|
|
||||||
headers = new List<HeadersModel>()
|
|
||||||
{
|
|
||||||
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
||||||
new HeadersModel("Referer", "https://moonanime.art/")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
string qualityStreamUrl = BuildStreamUrl(init, urlVal, headers, forceProxy);
|
|
||||||
streamQuality.Append(qualityStreamUrl, quality);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (streamQuality.Any())
|
|
||||||
{
|
|
||||||
var first = streamQuality.Firts();
|
|
||||||
streamUrl = first.link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(streamUrl))
|
|
||||||
{
|
|
||||||
var headers = streamHeaders;
|
|
||||||
if (!string.IsNullOrEmpty(streamLink) && (streamLink.Contains("moonanime.art") || streamLink.Contains("mooncdn.space")))
|
|
||||||
{
|
|
||||||
headers = new List<HeadersModel>()
|
|
||||||
{
|
|
||||||
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
||||||
new HeadersModel("Referer", "https://moonanime.art/")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
streamUrl = BuildStreamUrl(init, streamLink, headers, forceProxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnLog("AnimeON Play: return call JSON");
|
OnLog("AnimeON Play: return call JSON");
|
||||||
if (streamQuality.Any())
|
|
||||||
{
|
|
||||||
return UpdateService.Validate(Content(VideoTpl.ToJson("play", streamUrl, title ?? string.Empty, subtitles: subtitleTpl, streamquality: streamQuality), "application/json; charset=utf-8"));
|
|
||||||
}
|
|
||||||
return UpdateService.Validate(Content(VideoTpl.ToJson("play", streamUrl, title ?? string.Empty, subtitles: subtitleTpl), "application/json; charset=utf-8"));
|
return UpdateService.Validate(Content(VideoTpl.ToJson("play", streamUrl, title ?? string.Empty, subtitles: subtitleTpl), "application/json; charset=utf-8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace LME.AnimeON
|
|||||||
{
|
{
|
||||||
public class ModInit : IModuleLoaded
|
public class ModInit : IModuleLoaded
|
||||||
{
|
{
|
||||||
public static double Version => 4.3;
|
public static double Version => 4.2;
|
||||||
|
|
||||||
public static OnlinesSettings AnimeON;
|
public static OnlinesSettings AnimeON;
|
||||||
public static bool ApnHostProvided;
|
public static bool ApnHostProvided;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace LME.AnimeON.Models
|
namespace LME.AnimeON.Models
|
||||||
@ -31,30 +30,7 @@ namespace LME.AnimeON.Models
|
|||||||
public string ImdbId { get; set; }
|
public string ImdbId { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("season")]
|
[JsonPropertyName("season")]
|
||||||
public System.Text.Json.JsonElement? RawSeason { get; set; }
|
public int Season { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
public int Season
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (RawSeason == null)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
var element = RawSeason.Value;
|
|
||||||
if (element.ValueKind == JsonValueKind.Number && element.TryGetInt32(out int val))
|
|
||||||
return val;
|
|
||||||
|
|
||||||
if (element.ValueKind == JsonValueKind.String)
|
|
||||||
{
|
|
||||||
string str = element.GetString();
|
|
||||||
if (int.TryParse(str, out int val2))
|
|
||||||
return val2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FundubsResponseModel
|
public class FundubsResponseModel
|
||||||
|
|||||||
@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -255,58 +254,7 @@ namespace LME.Mikai.Controllers
|
|||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
var streamQuality = new StreamQualityTpl();
|
string streamUrl = BuildStreamUrl(init, streamLink, streamHeaders, forceProxy);
|
||||||
string streamUrl = null;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(streamLink) && (streamLink.StartsWith("[") || streamLink.Contains("]http")))
|
|
||||||
{
|
|
||||||
var bracketMatches = Regex.Matches(streamLink, @"\[(?<quality>[^\]]+)\](?<url>https?://[^,\[]+)", RegexOptions.IgnoreCase);
|
|
||||||
foreach (Match match in bracketMatches)
|
|
||||||
{
|
|
||||||
string quality = match.Groups["quality"].Value;
|
|
||||||
string urlVal = match.Groups["url"].Value?.Trim()?.TrimEnd(',');
|
|
||||||
if (string.IsNullOrWhiteSpace(urlVal))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var headers = streamHeaders;
|
|
||||||
if (urlVal.Contains("moonanime.art") || urlVal.Contains("mooncdn.space"))
|
|
||||||
{
|
|
||||||
headers = new List<HeadersModel>()
|
|
||||||
{
|
|
||||||
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
||||||
new HeadersModel("Referer", "https://moonanime.art/")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
string qualityStreamUrl = BuildStreamUrl(init, urlVal, headers, forceProxy);
|
|
||||||
streamQuality.Append(qualityStreamUrl, quality);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (streamQuality.Any())
|
|
||||||
{
|
|
||||||
var first = streamQuality.Firts();
|
|
||||||
streamUrl = first.link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(streamUrl))
|
|
||||||
{
|
|
||||||
var headers = streamHeaders;
|
|
||||||
if (!string.IsNullOrEmpty(streamLink) && (streamLink.Contains("moonanime.art") || streamLink.Contains("mooncdn.space")))
|
|
||||||
{
|
|
||||||
headers = new List<HeadersModel>()
|
|
||||||
{
|
|
||||||
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
||||||
new HeadersModel("Referer", "https://moonanime.art/")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
streamUrl = BuildStreamUrl(init, streamLink, headers, forceProxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (streamQuality.Any())
|
|
||||||
{
|
|
||||||
return UpdateService.Validate(Content(VideoTpl.ToJson("play", streamUrl, title ?? string.Empty, subtitles: subtitleTpl, streamquality: streamQuality), "application/json; charset=utf-8"));
|
|
||||||
}
|
|
||||||
return UpdateService.Validate(Content(VideoTpl.ToJson("play", streamUrl, title ?? string.Empty, subtitles: subtitleTpl), "application/json; charset=utf-8"));
|
return UpdateService.Validate(Content(VideoTpl.ToJson("play", streamUrl, title ?? string.Empty, subtitles: subtitleTpl), "application/json; charset=utf-8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -138,82 +137,22 @@ namespace LME.Mikai
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region MoonAnime Decryption
|
|
||||||
private static string CleanMoonUrl(string url)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(url))
|
|
||||||
return url;
|
|
||||||
|
|
||||||
string cleaned = Regex.Replace(url, @"([?&])player=[^&]*", "$1", RegexOptions.IgnoreCase);
|
|
||||||
cleaned = cleaned.Replace("?&", "?").Replace("&&", "&").TrimEnd('?', '&');
|
|
||||||
return cleaned;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string MoonDecode(string base64Input)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] raw = Convert.FromBase64String(base64Input);
|
|
||||||
const int KeySize = 32;
|
|
||||||
const int HeaderSize = 1 + KeySize;
|
|
||||||
|
|
||||||
if (raw.Length < HeaderSize)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
byte state = raw[0];
|
|
||||||
byte[] key = new byte[KeySize];
|
|
||||||
Array.Copy(raw, 1, key, 0, KeySize);
|
|
||||||
|
|
||||||
int payloadLen = raw.Length - HeaderSize;
|
|
||||||
byte[] payload = new byte[payloadLen];
|
|
||||||
Array.Copy(raw, HeaderSize, payload, 0, payloadLen);
|
|
||||||
|
|
||||||
for (int i = 0; i < payload.Length; i++)
|
|
||||||
{
|
|
||||||
byte encrypted = payload[i];
|
|
||||||
byte keyByte = key[i % KeySize];
|
|
||||||
|
|
||||||
payload[i] = (byte)(encrypted ^ keyByte ^ state);
|
|
||||||
state = (byte)((encrypted + keyByte) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(payload);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string MoonXorDecrypt(string file, string key)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
|
|
||||||
byte[] data = Convert.FromBase64String(file);
|
|
||||||
|
|
||||||
for (int i = 0; i < data.Length; i++)
|
|
||||||
{
|
|
||||||
data[i] = (byte)(data[i] ^ keyBytes[i % keyBytes.Length]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Encoding.UTF8.GetString(data);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public async Task<string> ParseMoonAnimePage(string url)
|
public async Task<string> ParseMoonAnimePage(string url)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string requestUrl = CleanMoonUrl(url);
|
string requestUrl = url;
|
||||||
|
if (!requestUrl.Contains("player=", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
requestUrl = requestUrl.Contains("?")
|
||||||
|
? $"{requestUrl}&player=mikai.me"
|
||||||
|
: $"{requestUrl}?player=mikai.me";
|
||||||
|
}
|
||||||
|
|
||||||
var headers = new List<HeadersModel>()
|
var headers = new List<HeadersModel>()
|
||||||
{
|
{
|
||||||
new HeadersModel("User-Agent", "Mozilla/5.0")
|
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
||||||
|
new HeadersModel("Referer", _init.host)
|
||||||
};
|
};
|
||||||
|
|
||||||
_onLog($"Mikai: using proxy {_proxyManager.CurrentProxyIp} for {requestUrl}");
|
_onLog($"Mikai: using proxy {_proxyManager.CurrentProxyIp} for {requestUrl}");
|
||||||
@ -221,64 +160,19 @@ namespace LME.Mikai
|
|||||||
if (string.IsNullOrEmpty(html))
|
if (string.IsNullOrEmpty(html))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var atobMatch = Regex.Match(html, @"=atob\(""([^""]+)""\)");
|
|
||||||
if (!atobMatch.Success)
|
|
||||||
{
|
|
||||||
atobMatch = Regex.Match(html, @"=atob\('([^']+)'\)");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atobMatch.Success)
|
|
||||||
{
|
|
||||||
string blob = atobMatch.Groups[1].Value;
|
|
||||||
string decryptedJs = MoonDecode(blob);
|
|
||||||
if (!string.IsNullOrEmpty(decryptedJs))
|
|
||||||
{
|
|
||||||
var keyMatch = Regex.Match(decryptedJs, @"var k=""([^""]+)""");
|
|
||||||
if (!keyMatch.Success)
|
|
||||||
keyMatch = Regex.Match(decryptedJs, @"var k='([^']+)'");
|
|
||||||
|
|
||||||
var fileMatch = Regex.Match(decryptedJs, @"file\s*:\s*_0xd\(""([^""]+)""\)");
|
|
||||||
if (!fileMatch.Success)
|
|
||||||
fileMatch = Regex.Match(decryptedJs, @"file\s*:\s*_0xd\('([^']+)'\)");
|
|
||||||
|
|
||||||
if (keyMatch.Success && fileMatch.Success)
|
|
||||||
{
|
|
||||||
string key = keyMatch.Groups[1].Value;
|
|
||||||
string fileEncrypted = fileMatch.Groups[1].Value;
|
|
||||||
string streams = MoonXorDecrypt(fileEncrypted, key);
|
|
||||||
if (!string.IsNullOrEmpty(streams))
|
|
||||||
{
|
|
||||||
return streams;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var directFileMatch = Regex.Match(decryptedJs, @"file\s*:\s*""([^""]+)""");
|
|
||||||
if (!directFileMatch.Success)
|
|
||||||
directFileMatch = Regex.Match(decryptedJs, @"file\s*:\s*'([^']+)'");
|
|
||||||
|
|
||||||
if (directFileMatch.Success)
|
|
||||||
{
|
|
||||||
return directFileMatch.Groups[1].Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload = PlayerJsDecoder.ExtractPlayerPayload(html);
|
var payload = PlayerJsDecoder.ExtractPlayerPayload(html);
|
||||||
if (payload?.FilePayload != null)
|
if (payload?.FilePayload == null)
|
||||||
{
|
return null;
|
||||||
|
|
||||||
var streamUrls = ExtractStreamUrls(payload.FilePayload);
|
var streamUrls = ExtractStreamUrls(payload.FilePayload);
|
||||||
return streamUrls?.FirstOrDefault();
|
return streamUrls?.FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_onLog($"Mikai ParseMoonAnimePage error: {ex.Message}");
|
_onLog($"Mikai ParseMoonAnimePage error: {ex.Message}");
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<string> ExtractStreamUrls(object filePayload)
|
private List<string> ExtractStreamUrls(object filePayload)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -25,7 +25,7 @@ namespace LME.Mikai
|
|||||||
{
|
{
|
||||||
public class ModInit : IModuleLoaded
|
public class ModInit : IModuleLoaded
|
||||||
{
|
{
|
||||||
public static double Version => 4.3;
|
public static double Version => 4.2;
|
||||||
|
|
||||||
public static OnlinesSettings Mikai;
|
public static OnlinesSettings Mikai;
|
||||||
public static bool ApnHostProvided;
|
public static bool ApnHostProvided;
|
||||||
|
|||||||
@ -19,7 +19,7 @@ namespace LME.NMoonAnime
|
|||||||
{
|
{
|
||||||
public class ModInit : IModuleLoaded
|
public class ModInit : IModuleLoaded
|
||||||
{
|
{
|
||||||
public static double Version => 2.2;
|
public static double Version => 2.1;
|
||||||
|
|
||||||
public static OnlinesSettings NMoonAnime;
|
public static OnlinesSettings NMoonAnime;
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ namespace LME.Common.Playerjs
|
|||||||
{
|
{
|
||||||
public static class PlayerJsDecoder
|
public static class PlayerJsDecoder
|
||||||
{
|
{
|
||||||
private static readonly Regex _reAtobLiteral = new Regex(@"atob\(\s*(['""])(?<payload>[^'""]+)\1\s*\)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
private static readonly Regex _reAtobLiteral = new Regex(@"atob\(\s*(['""])(?<payload>[A-Za-z0-9+/=]+)\1\s*\)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||||
private static readonly Regex _reJsonParseHelper = new Regex(@"JSON\.parse\(\s*(?<fn>[A-Za-z_$][\w$]*)\(\s*(?<quote>['""])(?<payload>.*?)(\k<quote>)\s*\)\s*\)", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
|
private static readonly Regex _reJsonParseHelper = new Regex(@"JSON\.parse\(\s*(?<fn>[A-Za-z_$][\w$]*)\(\s*(?<quote>['""])(?<payload>.*?)(\k<quote>)\s*\)\s*\)", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
|
||||||
private static readonly Regex _reHelperCall = new Regex(@"^\s*(?<fn>[A-Za-z_$][\w$]*)\(\s*(?<quote>['""])(?<payload>.*?)(\k<quote>)\s*\)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
|
private static readonly Regex _reHelperCall = new Regex(@"^\s*(?<fn>[A-Za-z_$][\w$]*)\(\s*(?<quote>['""])(?<payload>.*?)(\k<quote>)\s*\)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
|
||||||
private static readonly Regex _reTrailingComma = new Regex(@",\s*([}\]])", RegexOptions.Compiled);
|
private static readonly Regex _reTrailingComma = new Regex(@",\s*([}\]])", RegexOptions.Compiled);
|
||||||
@ -150,10 +150,7 @@ namespace LME.Common.Playerjs
|
|||||||
if (!match.Success)
|
if (!match.Success)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
string rawBase64 = match.Groups["payload"].Value;
|
byte[] rawData = SafeBase64Decode(match.Groups["payload"].Value);
|
||||||
rawBase64 = Regex.Replace(rawBase64, @"\s+", "");
|
|
||||||
|
|
||||||
byte[] rawData = SafeBase64Decode(rawBase64);
|
|
||||||
if (rawData == null || rawData.Length <= 32)
|
if (rawData == null || rawData.Length <= 32)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -164,39 +161,7 @@ namespace LME.Common.Playerjs
|
|||||||
for (int index = 0; index < encryptedData.Length; index++)
|
for (int index = 0; index < encryptedData.Length; index++)
|
||||||
decoded[index] = (byte)(encryptedData[index] ^ key[index % key.Length]);
|
decoded[index] = (byte)(encryptedData[index] ^ key[index % key.Length]);
|
||||||
|
|
||||||
string decodedStr = DecodeBytes(decoded);
|
return DecodeBytes(decoded);
|
||||||
if (decodedStr != null && (decodedStr.Contains("Playerjs") || decodedStr.Contains("file:")))
|
|
||||||
return decodedStr;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (rawData.Length > 33)
|
|
||||||
{
|
|
||||||
byte state = rawData[0];
|
|
||||||
byte[] moonKey = new byte[32];
|
|
||||||
Array.Copy(rawData, 1, moonKey, 0, 32);
|
|
||||||
|
|
||||||
int payloadLen = rawData.Length - 33;
|
|
||||||
byte[] moonPayload = new byte[payloadLen];
|
|
||||||
Array.Copy(rawData, 33, moonPayload, 0, payloadLen);
|
|
||||||
|
|
||||||
for (int i = 0; i < moonPayload.Length; i++)
|
|
||||||
{
|
|
||||||
byte encrypted = moonPayload[i];
|
|
||||||
byte keyByte = moonKey[i % 32];
|
|
||||||
|
|
||||||
moonPayload[i] = (byte)(encrypted ^ keyByte ^ state);
|
|
||||||
state = (byte)((encrypted + keyByte) & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
string moonDecoded = DecodeBytes(moonPayload);
|
|
||||||
if (moonDecoded != null && (moonDecoded.Contains("Playerjs") || moonDecoded.Contains("file:")))
|
|
||||||
return moonDecoded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
|
|
||||||
return decodedStr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] SafeBase64Decode(string value)
|
private static byte[] SafeBase64Decode(string value)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user