From f2097cd976e98483000e5d23c254bbbf738bd517 Mon Sep 17 00:00:00 2001 From: MrGus Date: Thu, 25 Dec 2025 23:23:56 +0100 Subject: [PATCH] Update anime/hianime/source.js --- anime/hianime/source.js | 97 ++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 30 deletions(-) diff --git a/anime/hianime/source.js b/anime/hianime/source.js index fbb77b9..96f48a6 100644 --- a/anime/hianime/source.js +++ b/anime/hianime/source.js @@ -1,17 +1,31 @@ class HiAnime { constructor() { - this.type = "anime-board"; - this.version = "1.0"; + this.type = "anime-streaming"; + this.version = "1.0.0"; this.baseUrl = "https://hianime.to"; } getSettings() { - return { episodeServers: ["HD-1", "HD-2", "HD-3", "HD-4"], supportsDub: true }; + return { + episodeServers: ["HD-1", "HD-2", "HD-3", "HD-4"], + supportsSub: true, + supportsDub: true, + supportsHls: true + }; } _nativeFetch(url, method, headers, body) { - const raw = Native.fetch(String(url), method || "GET", JSON.stringify(headers || {}), body == null ? "" : String(body)); - try { return JSON.parse(raw || "{}"); } catch (e) { return { ok: false, status: 0, headers: {}, body: "" }; } + const raw = Native.fetch( + String(url), + method || "GET", + JSON.stringify(headers || {}), + body == null ? "" : String(body) + ); + try { + return JSON.parse(raw || "{}"); + } catch (e) { + return { ok: false, status: 0, headers: {}, body: "" }; + } } _getText(url, headers) { @@ -21,11 +35,16 @@ class HiAnime { _getJson(url, headers) { const res = this._nativeFetch(url, "GET", headers, ""); - try { return JSON.parse(String(res.body || "{}")); } catch (e) { return {}; } + try { + return JSON.parse(String(res.body || "{}")); + } catch (e) { + return {}; + } } search(query) { - if (typeof query === "string") query = { query, media: { startDate: { year: 0, month: 0, day: 0 } } }; + if (typeof query === "string") + query = { query, media: { startDate: { year: 0, month: 0, day: 0 } } }; const start = (query.media && query.media.startDate) || { year: 0, month: 0, day: 0 }; const sy = start.year || 0; @@ -46,13 +65,6 @@ class HiAnime { const pageUrl = m[1]; const title = m[2]; - const jnameRegex = new RegExp( - `

[\\s\\S]*?]+href="\\/${pageUrl}[^"]*"[^>]+data-jname="([^"]+)"`, - "i" - ); - const jnameMatch = html.match(jnameRegex); - const jname = jnameMatch ? jnameMatch[1] : null; - const imageRegex = new RegExp( `]+data-src="([^"]+)"`, "i" @@ -70,8 +82,8 @@ class HiAnime { id: `${m.id}/${subOrDub}`, title: m.title, image: m.image, - url: `${this.baseUrl}/${m.pageUrl}`, - subOrDub, + url: `${this.baseUrl}/watch/${m.pageUrl}`, + subOrDub })); } @@ -80,7 +92,10 @@ class HiAnime { const id = parts[0]; const subOrDub = parts[1] || "sub"; - const json = this._getJson(`${this.baseUrl}/ajax/v2/episode/list/${id}`, { "X-Requested-With": "XMLHttpRequest" }); + const json = this._getJson( + `${this.baseUrl}/ajax/v2/episode/list/${id}`, + { "X-Requested-With": "XMLHttpRequest" } + ); const html = String(json.html || ""); const episodes = []; @@ -93,7 +108,7 @@ class HiAnime { id: `${match[2]}/${subOrDub}`, number: parseInt(match[1], 10), url: this.baseUrl + match[3], - title: match[4], + title: match[4] }); } @@ -101,15 +116,21 @@ class HiAnime { } findEpisodeServer(episode, _server) { - if (typeof episode === "string") { try { episode = JSON.parse(episode); } catch (e) {} } + if (typeof episode === "string") { + try { episode = JSON.parse(episode); } catch (e) {} + } const parts = String((episode && episode.id) || "").split("/"); const id = parts[0]; const subOrDub = parts[1] || "sub"; + const serverName = _server !== "default" ? _server : "HD-1"; if (_server === "HD-4") return null; - const serverJson = this._getJson(`${this.baseUrl}/ajax/v2/episode/servers?episodeId=${id}`, { "X-Requested-With": "XMLHttpRequest" }); + const serverJson = this._getJson( + `${this.baseUrl}/ajax/v2/episode/servers?episodeId=${id}`, + { "X-Requested-With": "XMLHttpRequest" } + ); const serverHtml = String(serverJson.html || ""); const regex = new RegExp( @@ -121,7 +142,10 @@ class HiAnime { if (!match) throw new Error(`Server "${serverName}" (${subOrDub}) not found`); const serverId = match[1]; - const sourcesJson = this._getJson(`${this.baseUrl}/ajax/v2/episode/sources?id=${serverId}`, { "X-Requested-With": "XMLHttpRequest" }); + const sourcesJson = this._getJson( + `${this.baseUrl}/ajax/v2/episode/sources?id=${serverId}`, + { "X-Requested-With": "XMLHttpRequest" } + ); let decryptData = null; let requiredHeaders = {}; @@ -139,13 +163,15 @@ class HiAnime { requiredHeaders = { Referer: "https://megacloud.club/", Origin: "https://megacloud.club", - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36", - "X-Requested-With": "XMLHttpRequest", + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36", + "X-Requested-With": "XMLHttpRequest" }; } const sources = decryptData.sources || []; - const streamSource = sources.find((s) => s.type === "hls") || sources.find((s) => s.type === "mp4"); + const streamSource = + sources.find((s) => s.type === "hls") || sources.find((s) => s.type === "mp4"); if (!streamSource || !streamSource.file) throw new Error("No valid stream file found"); const subtitles = (decryptData.tracks || []) @@ -154,13 +180,20 @@ class HiAnime { id: `sub-${index}`, language: track.label || "Unknown", url: track.file, - isDefault: !!track.default, + isDefault: !!track.default })); return { server: serverName, headers: requiredHeaders, - videoSources: [{ url: streamSource.file, type: streamSource.type === "hls" ? "m3u8" : "mp4", quality: "auto", subtitles }], + videoSources: [ + { + url: streamSource.file, + type: streamSource.type === "hls" ? "m3u8" : "mp4", + quality: "auto", + subtitles + } + ] }; } @@ -178,7 +211,8 @@ class HiAnime { "X-Requested-With": "XMLHttpRequest", Referer: baseDomain, Origin: `${protocol}://${host}`, - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36", + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36" }; const html = this._getText(embedUrl, headers); @@ -196,7 +230,10 @@ class HiAnime { } if (!nonce) throw new Error("nonce not found"); - const sourcesJson = this._getJson(`${baseDomain}embed-2/v3/e-1/getSources?id=${fileId}&_k=${nonce}`, headers); + const sourcesJson = this._getJson( + `${baseDomain}embed-2/v3/e-1/getSources?id=${fileId}&_k=${nonce}`, + headers + ); return { sources: sourcesJson.sources || [], @@ -204,9 +241,9 @@ class HiAnime { intro: sourcesJson.intro || null, outro: sourcesJson.outro || null, server: sourcesJson.server || null, - headersProvided: headers, + headersProvided: headers }; } } -module.exports = HiAnime; +module.exports = new HiAnime();