using System; using System.Collections.Generic; using System.Threading.Tasks; using Shared; using Shared.Models.Online.Settings; using Shared.Models; using System.Text.Json; using System.Linq; using AnimeON.Models; using Shared.Engine; namespace AnimeON { public class AnimeONInvoke { private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; private ProxyManager _proxyManager; public AnimeONInvoke(OnlinesSettings init, HybridCache hybridCache, Action onLog, ProxyManager proxyManager) { _init = init; _hybridCache = hybridCache; _onLog = onLog; _proxyManager = proxyManager; } public async Task> Search(string imdb_id, long kinopoisk_id, string title, string original_title, int year) { string memKey = $"AnimeON:search:{kinopoisk_id}:{imdb_id}"; if (_hybridCache.TryGetValue(memKey, out List res)) return res; try { var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; async Task> FindAnime(string query) { if (string.IsNullOrEmpty(query)) return null; string searchUrl = $"{_init.host}/api/anime/search?text={System.Web.HttpUtility.UrlEncode(query)}"; string searchJson = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(searchJson)) return null; var searchResponse = JsonSerializer.Deserialize(searchJson); return searchResponse?.Result; } var searchResults = await FindAnime(title) ?? await FindAnime(original_title); if (searchResults == null) return null; if (!string.IsNullOrEmpty(imdb_id)) { var seasons = searchResults.Where(a => a.ImdbId == imdb_id).ToList(); if (seasons.Count > 0) { _hybridCache.Set(memKey, seasons, cacheTime(5)); return seasons; } } // Fallback to first result if no imdb match var firstResult = searchResults.FirstOrDefault(); if (firstResult != null) { var list = new List { firstResult }; _hybridCache.Set(memKey, list, cacheTime(5)); return list; } return null; } catch (Exception ex) { _onLog($"AnimeON error: {ex.Message}"); } return null; } public async Task> GetFundubs(int animeId) { string fundubsUrl = $"{_init.host}/api/player/fundubs/{animeId}"; string fundubsJson = await Http.Get(fundubsUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(fundubsJson)) return null; var fundubsResponse = JsonSerializer.Deserialize(fundubsJson); return fundubsResponse?.FunDubs; } public async Task GetEpisodes(int animeId, int playerId, int fundubId) { string episodesUrl = $"{_init.host}/api/player/episodes/{animeId}?take=100&skip=-1&playerId={playerId}&fundubId={fundubId}"; string episodesJson = await Http.Get(episodesUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(episodesJson)) return null; return JsonSerializer.Deserialize(episodesJson); } public async Task ParseMoonAnimePage(string url) { try { string requestUrl = $"{url}?player=animeon.club"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://animeon.club/") }; string html = await Http.Get(requestUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) return null; var match = System.Text.RegularExpressions.Regex.Match(html, @"file:\s*""([^""]+\.m3u8)"""); if (match.Success) { return match.Groups[1].Value; } } catch (Exception ex) { _onLog($"AnimeON ParseMoonAnimePage error: {ex.Message}"); } return null; } public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) return TimeSpan.FromMinutes(rhub); int ctime = AppInit.conf.mikrotik ? mikrotik : AppInit.conf.multiaccess ? init != null && init.cache_time > 0 ? init.cache_time : multiaccess : home; if (ctime > multiaccess) ctime = multiaccess; return TimeSpan.FromMinutes(ctime); } } }