From b49fde5adb781f59baef8054d24888f052c95be1 Mon Sep 17 00:00:00 2001 From: cy Date: Sun, 17 May 2026 06:15:11 +0200 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E6=96=87=E4=BB=B6=E8=87=B3?= =?UTF-8?q?=E3=80=8C/=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- drpy2.dbk.js | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 drpy2.dbk.js diff --git a/drpy2.dbk.js b/drpy2.dbk.js new file mode 100644 index 0000000..4571c26 --- /dev/null +++ b/drpy2.dbk.js @@ -0,0 +1,204 @@ +const host = 'https://api.dbokutv.com'; +const headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "Referer": "https://www.duboku.tv/" +}; + +function base64Encode(text) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + let b64 = ''; + for (let i = 0; i < text.length; i += 3) { + let n = (text.charCodeAt(i) << 16) | (text.charCodeAt(i + 1) << 8) | text.charCodeAt(i + 2); + b64 += chars.charAt((n >> 18) & 63) + + chars.charAt((n >> 12) & 63) + + chars.charAt((n >> 6) & 63) + + chars.charAt(n & 63); + } + let mod = text.length % 3; + return (mod ? b64.slice(0, mod - 3) + "===".substring(mod) : b64); +} + +function base64Decode(str) { + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + str = str.replace(/=/g, ''); + let bin = ''; + for (let i = 0; i < str.length; i += 4) { + let n = (chars.indexOf(str.charAt(i)) << 18) + | (chars.indexOf(str.charAt(i + 1)) << 12) + | (chars.indexOf(str.charAt(i + 2)) << 6) + | chars.indexOf(str.charAt(i + 3)); + bin += String.fromCharCode((n >> 16) & 255, (n >> 8) & 255, n & 255); + } + return bin.replace(/\0/g, ''); +} + +function decodeData(data) { + if (!data || typeof data !== 'string') return ''; + let strippedStr = data.replace(/['"]/g, '').trim(); + if (!strippedStr) return ''; + let segmentLength = 10; + let processedBase64 = ''; + for (let i = 0; i < strippedStr.length; i += segmentLength) { + let segment = strippedStr.substring(i, i + segmentLength); + processedBase64 += segment.split('').reverse().join(''); + } + processedBase64 = processedBase64.replace(/\./g, '='); + try { + return base64Decode(processedBase64); + } catch (e) { + return ''; + } +} + +function getSignedUrl(path) { + const timestamp = Math.floor(Date.now() / 1000).toString(); + const randomNumber = Math.floor(Math.random() * 800000001); + const valueA = (randomNumber + 100000000).toString(); + const valueB = (900000000 - randomNumber).toString(); + const combined = valueA + valueB; + + let interleaved = ''; + let minLen = Math.min(combined.length, timestamp.length); + for (let i = 0; i < minLen; i++) { + interleaved += combined[i] + timestamp[i]; + } + interleaved += combined.substring(minLen) + timestamp.substring(minLen); + + const ssid = base64Encode(interleaved).replace(/=/g, '.'); + + function randomStr(len) { + const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + let res = ''; + for (let i = 0; i < len; i++) res += chars.charAt(Math.floor(Math.random() * chars.length)); + return res; + } + + const sign = randomStr(60); + const token = randomStr(38); + const connector = path.includes('?') ? '&' : '?'; + return `${host}${path}${connector}sign=${sign}&token=${token}&ssid=${ssid}`; +} + +async function init(cfg) {} + +async function home(filter) { + const classes = [ + { type_id: '2', type_name: '连续剧' }, + { type_id: '1', type_name: '电影' }, + { type_id: '3', type_name: '综艺' }, + { type_id: '4', type_name: '动漫' } + ]; + return JSON.stringify({ class: classes }); +} + +async function homeVod() { + const url = getSignedUrl('/home'); + const r = await req(url, { headers }); + const json = JSON.parse(r.content); + let videos = []; + json.forEach(group => { + (group.VodList || []).forEach(j => { + videos.push({ + vod_id: decodeData(j.DId || j.DuId), + vod_name: j.Name, + vod_pic: decodeData(j.TnId), + vod_remarks: j.Tag + }); + }); + }); + return JSON.stringify({ list: videos }); +} + +async function category(tid, pg, filter, extend = {}) { + let page = pg || 1; + let pageStr = page.toString() === '1' ? '' : page.toString(); + let urlPath = `/vodshow/${tid}--------${pageStr}---`; + const url = getSignedUrl(urlPath); + const r = await req(url, { headers }); + const json = JSON.parse(r.content); + + let videos = (json.VodList || []).map(i => ({ + vod_id: decodeData(i.DId || i.DuId), + vod_name: i.Name, + vod_pic: decodeData(i.TnId), + vod_remarks: i.Tag + })); + + let pageCount = page; + try { + (json.PaginationList || []).forEach(j => { + if (j.Type === 'StartEnd') { + let parts = decodeData(j.PId || j.PuId).split('-'); + if (parts.length > 8) pageCount = parseInt(parts[8]); + } else if (j.Type === 'ShortPage') { + pageCount = parseInt(j.Name.split('/')[1]); + } + }); + } catch (e) {} + + return JSON.stringify({ + page: parseInt(page), + pagecount: pageCount || parseInt(page), + list: videos + }); +} + +async function detail(id) { + const url = getSignedUrl(id); + const r = await req(url, { headers }); + const data = JSON.parse(r.content); + + const playUrls = (data.Playlist || []).map(i => { + return `${i.EpisodeName}$${decodeData(i.VId)}`; + }).join('#'); + + return JSON.stringify({ + list: [{ + vod_id: id, + vod_name: data.Name, + vod_pic: decodeData(data.TnId), + vod_remarks: `评分:${data.Rating}`, + vod_year: data.ReleaseYear, + vod_area: data.Region, + vod_actor: Array.isArray(data.Actor) ? data.Actor.join(',') : data.Actor, + vod_director: data.Director, + vod_content: data.Description, + vod_play_from: '初忆测试', + vod_play_url: playUrls, + type_name: `${data.Genre || ''},${data.Scenario || ''}` + }] + }); +} + +async function search(wd, quick, pg = 1) { + const url = getSignedUrl('/vodsearch') + `&wd=${encodeURIComponent(wd)}`; + const r = await req(url, { headers }); + const json = JSON.parse(r.content); + + const list = (json || []).map(i => ({ + vod_id: decodeData(i.DId || i.DuId), + vod_name: i.Name, + vod_pic: decodeData(i.TnId), + vod_remarks: i.Tag + })); + + return JSON.stringify({ page: pg, list: list }); +} + +async function play(flag, id, flags) { + const url = getSignedUrl(id); + const r = await req(url, { headers }); + const res = JSON.parse(r.content); + + return JSON.stringify({ + parse: 0, + url: decodeData(res.HId), + header: { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', + 'Origin': 'https://w.duboku.io', + 'Referer': 'https://w.duboku.io/' + } + }); +} + +export default { init, home, homeVod, category, detail, search, play }; \ No newline at end of file