diff --git a/package.json b/package.json index 755317b..7b43022 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Miru", - "version": "4.1.15", + "version": "4.2.0", "author": "ThaUnknown_ ", "description": "Stream anime torrents, real-time with no waiting for downloads.", "main": "build/main.js", diff --git a/src/background/background.js b/src/background/background.js index b026264..db76c5a 100644 --- a/src/background/background.js +++ b/src/background/background.js @@ -2,6 +2,8 @@ import WebTorrent from 'webtorrent' import { SubtitleParser, SubtitleStream } from 'matroska-subtitles' import { ipcRenderer } from 'electron' import { pipeline } from 'streamx' +import HTTPTracker from 'bittorrent-tracker/lib/client/http-tracker.js' +import { hex2bin, bin2hex, arr2text, hex2arr } from 'uint8-util' class TorrentClient extends WebTorrent { constructor (settings) { @@ -31,6 +33,10 @@ class TorrentClient extends WebTorrent { this.server = this.createServer(undefined, 'node') this.server.listen(0) + + this.trackers = { + cat: new HTTPTracker({}, atob('aHR0cDovL255YWEudHJhY2tlci53Zjo3Nzc3L2Fubm91bmNl')) + } } handleTorrent (torrent) { @@ -49,6 +55,24 @@ class TorrentClient extends WebTorrent { this.dispatch('torrent', Array.from(torrent.torrentFile)) } + _scrape ({ id, infoHashes }) { + const hashes = infoHashes.map(infoHash => hex2bin(infoHash)) + const malformed = {} + for (const hash of infoHashes) { + malformed[bin2hex(arr2text(hex2arr(hash)))] = hash + } + this.trackers.cat._request(this.trackers.cat.scrapeUrl, { info_hash: hashes }, (err, data) => { + if (err) console.error(err) + const { files } = data + const result = [] + for (const [key, data] of Object.entries(files || {})) { + result.push({ hash: malformed[bin2hex(key)], ...data }) + } + this.dispatch('scrape', { id, result }) + console.log(result, data) + }) + } + async handleMessage ({ data }) { switch (data.type) { case 'current': { @@ -77,6 +101,10 @@ class TorrentClient extends WebTorrent { } break } + case 'scrape': { + this._scrape(data.data) + break + } case 'torrent': { const id = typeof data.data !== 'string' ? new Uint8Array(data.data) : data.data const existing = await this.get(id) diff --git a/src/renderer/modules/providers/tosho.js b/src/renderer/modules/providers/tosho.js index 6cacdd5..afa7290 100644 --- a/src/renderer/modules/providers/tosho.js +++ b/src/renderer/modules/providers/tosho.js @@ -3,6 +3,8 @@ import { fastPrettyBytes } from '../util.js' import { exclusions } from '../rss.js' import { set } from '@/views/Settings.svelte' import { alRequest } from '../anilist.js' +import { client } from '@/modules/torrent.js' + import anitomyscript from 'anitomyscript' export default async function tosho ({ media, episode }) { @@ -24,6 +26,25 @@ export default async function tosho ({ media, episode }) { for (const i in parseObjects) mapped[i].parseObject = parseObjects[i] + const id = crypto.randomUUID() + + const updated = await new Promise(resolve => { + function check ({ detail }) { + if (detail.id !== id) return + client.removeListener('scrape', check) + resolve(detail.result) + console.log(detail) + } + client.on('scrape', check) + client.send('scrape', { id, infoHashes: mapped.map(({ hash }) => hash) }) + }) + for (const { hash, complete, downloaded, incomplete } of updated) { + const found = mapped.find(mapped => mapped.hash === hash) + found.downloads = downloaded + found.leechers = incomplete + found.seeders = complete + } + return mapped } @@ -256,6 +277,7 @@ function mapTosho2dDeDupedEntry (entries) { seeders: entry.seeders >= 100000 ? 0 : entry.seeders, leechers: entry.leechers >= 100000 ? 0 : entry.leechers, downloads: entry.torrent_downloaded_count, + hash: entry.info_hash, size: entry.total_size && fastPrettyBytes(entry.total_size), verified: !!entry.anidb_fid, batch: entry.batch, diff --git a/webpack.config.cjs b/webpack.config.cjs index 0ec8282..3ad3728 100644 --- a/webpack.config.cjs +++ b/webpack.config.cjs @@ -23,7 +23,9 @@ module.exports = [ mainFields: ['module', 'main', 'node'], alias: { 'node-fetch': false, - ws: false + ws: false, + wrtc: false, + 'bittorrent-tracker/lib/client/http-tracker.js': resolve('node_modules/bittorrent-tracker/lib/client/http-tracker.js') } }, plugins: [new HtmlWebpackPlugin({ filename: 'background.html' })],