▶ 花都动漫
https://hd.huadudm.com
laizhiyu (6509)4天前
修复适配sigma版
{
"bookSourceComment": "花都动漫(hd.huadudm.com)视频书源 v1.5\n· 站点:飞飞CMS(FeifeiCMS)影视站,UTF-8,无WAF,无需登录\n· 搜索:GET \/vodsearch\/{关键词}----------{页码}---.html(每页40条)\n· 分类:GET \/vodshow\/{分类}--------{页码}---.html(16个分类,每页40条)\n· 排序:\/vodshow\/{分类}--{time|hits|up}------{页码}---.html\n· 详情:\/voddetail\/{id}.html(div.detail-item 键值对)\n· 正文:\/vodplay\/{id}-{线路}-{集数}.html 内 var player_data\n encrypt=2 → base64 → url-decode 多层 → m3u8 直链\n· 每作品仅 1 个视频(标题含集数的实为整段长视频)\n· 视频CDN(cdn5.huabf.com \/ t1.121126.com)有短时频控:同一分片短时间内反复请求会返回 404 或超时,等 1~2 分钟自动恢复(实测正常播放不受影响,ExoPlayer 顺序拉流不会触发)\n· 兼容 LegadoTeam 与 legado-E(列表\/目录条目返回 JSON 字符串,字段走 $.键)\n· v1.7:修复 legado-E 发现列表为空 \/ 搜索有列表大小但无书名——E 版 getString 对 NativeObject 无 Mode.Json 分支,条目必须是 JSON 字符串",
"bookSourceGroup": "视频,AI,R18",
"bookSourceName": "▶ 花都动漫",
"bookSourceType": 4,
"bookSourceUrl": "https:\/\/hd.huadudm.com",
"bookUrlPattern": "https?:\/\/hd[.]huadudm[.]com\/voddetail\/[0-9]+[.]html",
"concurrentRate": "1\/800",
"customButton": false,
"customOrder": 1,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": true,
"eventListener": false,
"exploreUrl": "<js>\n(function(){\n var cats=[\n [1,'中文字幕'],[2,'无字幕'],[3,'国产'],[4,'欧美'],[5,'动漫'],\n [6,'中字有码'],[7,'骑兵有码'],[8,'中字无码'],[9,'步兵无码'],\n [10,'国产精品'],[11,'国产传媒'],[12,'欧美中字'],[13,'糖心Vlog'],\n [14,'中字里番'],[15,'3D动漫'],[16,'AI短剧']\n ];\n var out=[];\n function add(title,url,style){\n var o={title:title,url:url};\n if(style) o.style=style;\n out.push(o);\n }\n function head(t){\n out.push({title:t,url:'',style:{layout_flexBasisPercent:1,layout_wrapBefore:true,layout_justifySelf:'flex_start'}});\n }\n var cell={layout_flexGrow:1};\n function pgUrl(type,order){\n var o=order?('--'+order):'--';\n return '\/vodshow\/'+type+o+'------{{(function(){var p=Number(page);if(!(p>0)){p=1;}p=Math.floor(p);try{source.put(String.fromCharCode(104,103,112,103),String(p));}catch(e){}return p;})()}}---.html';\n }\n head('★ 全站榜单');\n add('人气榜', pgUrl(1,'hits'), cell);\n add('点赞榜', pgUrl(1,'up'), cell);\n add('最新更新', pgUrl(1,''), cell);\n head('◆ 分类(共16个)');\n for(var i=0;i<cats.length;i++){\n add(cats[i][1], pgUrl(cats[i][0],''), cell);\n }\n return JSON.stringify(out);\n})()\n<\/js>",
"header": "{\"User-Agent\": \"Mozilla\/5.0 (Linux; Android 14; Pixel 8) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/126.0.0.0 Mobile Safari\/537.36\"}",
"lastUpdateTime": "1792392489476",
"loginCheckJs": "\/\/ 站点无需登录;仅做限频\/异常提示(result 为 StrResponse,必须原样 return)\n(function(){\n var b='';\n try{ b=String(result.body()); }catch(e){ try{ b=String(result.body); }catch(e2){ b=''; } }\n if(!b) return result;\n if(b.length<1200 && (b.indexOf('频繁')>=0||b.indexOf('间隔')>=0||b.indexOf('稍后再试')>=0||b.indexOf('访问过快')>=0)){\n throw new Error('⏱ 站点限制访问频率,请等 10 秒后再试');\n }\n if(b.indexOf('Just a moment')>=0||b.indexOf('Attention Required')>=0){\n throw new Error('⚠ 站点触发人机验证,请稍后重试');\n }\n return result;\n})()",
"loginUi": "[{\"name\": \"▶ 花都动漫 · 无需登录\", \"type\": \"button\", \"action\": \"about()\"}, {\"name\": \"◎ 检查站点连通性\", \"type\": \"button\", \"action\": \"checkSite()\"}, {\"name\": \"◆ 使用说明\", \"type\": \"button\", \"action\": \"java.longToast('本网站无需登录。若播放无画面:多为视频CDN短时限流,等1~2分钟再点即可。若提示「暂无播放地址」:该资源已下架。')\"}, {\"name\": \"◆ 翻页自检\", \"type\": \"button\", \"action\": \"pageDiag()\"}]",
"loginUrl": "function login(){\n var ck='';\n try{ ck=String(java.getCookie('https:\/\/hd.huadudm.com\/')); }catch(e){}\n if(ck&&ck.length>3){ return '已带Cookie(本站无需登录)'; }\n return '本站无需登录';\n}\nfunction checkSite(){\n var t0=new Date().getTime();\n try{\n var r=java.connect('https:\/\/hd.huadudm.com\/',null,20000);\n var body='';\n try{ body=String(r.body()); }catch(eb){ try{ body=String(r.body); }catch(eb2){ body=''; } }\n var ms=new Date().getTime()-t0;\n if(body.indexOf('花都')>=0||body.indexOf('stui-vodlist')>=0){\n java.longToast('✅ 站点连通正常\\n耗时:'+ms+' ms\\n\\n本网站无需登录,搜索\/发现\/播放均可匿名使用。');\n return 'ok';\n }\n java.longToast('⚠️ 站点返回异常页面('+body.length+' 字节)\\n可能正在维护或被拦截,请稍后重试。');\n return 'bad';\n }catch(e){\n var ms2=new Date().getTime()-t0;\n java.longToast('❌ 无法连接站点('+ms2+' ms)\\n'+String(e).substring(0,160)+'\\n\\n请检查网络或稍后重试。');\n return 'err';\n }\n}\nfunction about(){\n java.longToast('▶ 花都动漫(hd.huadudm.com)\\n\\n· 本网站无需登录,所有功能匿名可用\\n· 每个作品对应 1 个视频(部分标题含集数,实为整段视频)\\n· 若播放失败:多为视频CDN短时限流,等 1~2 分钟再点\\n· 发现页共 16 个分类 + 3 个榜单');\n return 'ok';\n}\nfunction pageDiag(){\n var K=String.fromCharCode(104,103,112,103);\n var v='';\n try{ v=String(source.get(K)); }catch(e){ v='ERR'; }\n var blank=(v===''||v==='null'||v==='undefined');\n var msg='◆ 翻页自检\\n\\n最近一次请求页码:'+(blank?'(无记录)':v)+'\\n\\n';\n if(blank){\n msg+='若你刚刚在发现页下滑过,却读不到页码,说明 App 未走到 URL 模板替换。\\n';\n }else{\n msg+='若这里长期停在 1,说明 App 只请求过第 1 页(翻页未触发)。\\n';\n msg+='若出现过 2 及以上,说明翻页链路正常。\\n';\n }\n msg+='\\n站点分页实测:分类每页 40 条、第 2 页内容与第 1 页完全不重复。';\n java.longToast(msg);\n return String(v);\n}",
"respondTime": 180000,
"ruleBookInfo": {
"author": "$.a",
"coverUrl": "$.c",
"init": "@js:(function(){\n var html=String(result);\n var doc=Packages.org.jsoup.Jsoup.parse(html);\n function lab(key){\n var items=doc.select('div.detail-item');\n for(var i=0;i<items.size();i++){\n var it=items.get(i);\n var k=String(it.select('strong.label-width').text()).replace(\/[::\\s]\/g,'');\n if(k===key) return String(it.select('span.detail-content').text()).trim();\n }\n return '';\n }\n var name=lab('名称');\n if(!name){\n var t=String(doc.title());\n var m=t.match(\/《([^》]+)》\/);\n if(m) name=m[1];\n }\n var title=lab('标题');\n var cat=lab('分类');\n var tags=lab('类别');\n var date=lab('日期');\n var dur=lab('时长');\n var intro='';\n var md=doc.select('meta[name=description]').first();\n if(md!==null){\n intro=String(md.attr('content')).trim();\n intro=intro.replace(\/^[\\s\\S]*?详情介绍[::]\/,'').replace(\/[,,]?好看的[\\s\\S]*?推荐。?$\/,'').trim();\n }\n var seen={};\n function uniq(x){\n var t=String(x||'').trim();\n if(!t) return '';\n var k=t.replace(\/[\\s【】《》\\[\\]()()_]\/g,'');\n if(k.length<2||seen[k]) return '';\n seen[k]=1;\n return t;\n }\n var bits=[];\n var t1=uniq(title);\n if(t1) bits.push(t1);\n var t2=uniq(intro);\n if(t2) bits.push(t2);\n if(cat) bits.push('分类:'+cat);\n if(tags) bits.push('标签:'+tags.replace(\/\\s+\/g,' \/ '));\n if(dur) bits.push('时长:'+dur);\n if(date) bits.push('更新:'+date);\n var fullIntro=bits.join('\\n');\n var cover='';\n var im=doc.select('div.stui-vodlist__box img').first();\n if(im!==null){\n cover=String(im.attr('data-original')).trim();\n if(!cover) cover=String(im.attr('src')).trim();\n if(cover.indexOf('load.gif')>=0) cover='';\n }\n var kindParts=[];\n var kseen={};\n function kadd(x){\n var t=String(x||'').trim();\n if(!t||kseen[t]) return;\n kseen[t]=1;\n kindParts.push(t);\n }\n kadd(cat);\n if(tags){\n var arr=tags.split(\/\\s+\/);\n for(var k=0;k<arr.length;k++){ kadd(arr[k]); }\n }\n var out={\n n:name,\n a:'',\n k:kindParts.join(','),\n i:fullIntro,\n c:cover,\n l:'',\n w:dur||'',\n t:''\n };\n return JSON.stringify(out);\n})()",
"intro": "$.i",
"kind": "$.k",
"lastChapter": "$.l",
"name": "$.n",
"tocUrl": "$.t",
"wordCount": "$.w"
},
"ruleContent": {
"content": "@js:(function(){\n var html=String(result);\n var m=html.match(\/var\\s+player_data\\s*=\\s*([\\s\\S]*?)<\\\/script>\/);\n if(!m) throw new Error('未找到播放数据:页面结构可能已变更,请刷新目录后重试');\n var raw=m[1].replace(\/;\\s*$\/,'').trim();\n var d=null;\n try{ d=JSON.parse(raw); }catch(e){\n var m2=raw.match(\/\\{[\\s\\S]*\"nid\"\\s*:\\s*[0-9]+\\}\/);\n if(m2){ try{ d=JSON.parse(m2[0]); }catch(e2){} }\n }\n if(!d) throw new Error('播放数据解析失败');\n var enc=String(d.encrypt||'');\n var u=String(d.url||'');\n if(!u) throw new Error('该资源暂无播放地址(可能已下架或需要会员)');\n if(enc==='1'){\n try{ u=unescape(u); }catch(e3){}\n }else if(enc==='2'){\n try{ u=java.base64Decode(u); }catch(e4){}\n for(var i=0;i<5;i++){\n var nx=u;\n try{ nx=decodeURIComponent(u); }catch(e5){ nx=u; }\n if(nx===u) break;\n u=nx;\n }\n }\n if(u.indexOf('http')!==0) throw new Error('播放地址解密失败(加密方式可能已变更)');\n return u;\n})()"
},
"ruleExplore": {
"bookList": "@js:(function(){\n var doc=null;\n try{\n doc=(typeof result!=='undefined'&&result&&typeof result.select==='function')?result:Packages.org.jsoup.Jsoup.parse(String(result));\n }catch(e){ return []; }\n var uls=doc.select('ul.stui-vodlist');\n if(!uls||uls.size()===0) return [];\n var best=null,bestN=-1;\n for(var i=0;i<uls.size();i++){\n var n=uls.get(i).select('li').size();\n if(n>bestN){ bestN=n; best=uls.get(i); }\n }\n if(!best||bestN<=0){\n var st=doc.select('span.stats-text');\n var cur=0,tot=0;\n if(st.size()>0){\n var sm=String(st.get(0).text()).replace(\/\\s+\/g,'').match(\/第([0-9]+)[\/]([0-9]+)页\/);\n if(sm){ cur=Number(sm[1]); tot=Number(sm[2]); }\n }\n if(cur>0&&tot>0&&cur>=tot) return [];\n var pg='';\n try{\n var bm=String(baseUrl).match(\/[-]([0-9]+)[-]{3}[.]html\/);\n if(bm) pg=bm[1];\n }catch(e0){}\n throw new Error('第'+(pg||'?')+'页返回空页面(站点可能临时限流),请点「重试」');\n }\n var out=[],lis=best.select('li');\n for(var j=0;j<lis.size();j++){\n var li=lis.get(j);\n var a=li.select('h4.title a').first();\n if(a===null) continue;\n var href=String(a.attr('href'));\n if(href.indexOf('\/voddetail\/')<0) continue;\n var name=String(a.attr('title')).trim();\n if(!name) name=String(a.text()).trim();\n if(!name) continue;\n var cover='';\n var img=li.select('img').first();\n if(img!==null){\n cover=String(img.attr('data-original')).trim();\n if(!cover) cover=String(img.attr('src')).trim();\n if(cover.indexOf('load.gif')>=0) cover='';\n }\n var cat='',dur='';\n var st=li.select('span.pic-tag-t').first();\n if(st!==null) cat=String(st.text()).trim();\n var sb=li.select('span.pic-tag-b').first();\n if(sb!==null) dur=String(sb.text()).trim();\n var meta='';\n var sp=li.select('span.text').first();\n if(sp!==null) meta=String(sp.text()).trim();\n var bits=[];\n if(cat) bits.push(cat);\n if(dur) bits.push(dur);\n if(meta) bits.push(meta);\n out.push(String(JSON.stringify({n:name,u:href,c:cover,m:bits.join(' · '),k:cat})));\n }\n return out;\n})()",
"bookUrl": "$.u",
"coverUrl": "$.c",
"intro": "$.m",
"name": "$.n"
},
"ruleSearch": {
"bookList": "@js:(function(){\n var doc=null;\n try{\n doc=(typeof result!=='undefined'&&result&&typeof result.select==='function')?result:Packages.org.jsoup.Jsoup.parse(String(result));\n }catch(e){ return []; }\n var uls=doc.select('ul.stui-vodlist');\n if(!uls||uls.size()===0) return [];\n var best=null,bestN=-1;\n for(var i=0;i<uls.size();i++){\n var n=uls.get(i).select('li').size();\n if(n>bestN){ bestN=n; best=uls.get(i); }\n }\n if(!best||bestN<=0){\n var st=doc.select('span.stats-text');\n var cur=0,tot=0;\n if(st.size()>0){\n var sm=String(st.get(0).text()).replace(\/\\s+\/g,'').match(\/第([0-9]+)[\/]([0-9]+)页\/);\n if(sm){ cur=Number(sm[1]); tot=Number(sm[2]); }\n }\n if(cur>0&&tot>0&&cur>=tot) return [];\n var pg='';\n try{\n var bm=String(baseUrl).match(\/[-]([0-9]+)[-]{3}[.]html\/);\n if(bm) pg=bm[1];\n }catch(e0){}\n throw new Error('第'+(pg||'?')+'页返回空页面(站点可能临时限流),请点「重试」');\n }\n var out=[],lis=best.select('li');\n for(var j=0;j<lis.size();j++){\n var li=lis.get(j);\n var a=li.select('h4.title a').first();\n if(a===null) continue;\n var href=String(a.attr('href'));\n if(href.indexOf('\/voddetail\/')<0) continue;\n var name=String(a.attr('title')).trim();\n if(!name) name=String(a.text()).trim();\n if(!name) continue;\n var cover='';\n var img=li.select('img').first();\n if(img!==null){\n cover=String(img.attr('data-original')).trim();\n if(!cover) cover=String(img.attr('src')).trim();\n if(cover.indexOf('load.gif')>=0) cover='';\n }\n var cat='',dur='';\n var st=li.select('span.pic-tag-t').first();\n if(st!==null) cat=String(st.text()).trim();\n var sb=li.select('span.pic-tag-b').first();\n if(sb!==null) dur=String(sb.text()).trim();\n var meta='';\n var sp=li.select('span.text').first();\n if(sp!==null) meta=String(sp.text()).trim();\n var bits=[];\n if(cat) bits.push(cat);\n if(dur) bits.push(dur);\n if(meta) bits.push(meta);\n out.push(String(JSON.stringify({n:name,u:href,c:cover,m:bits.join(' · '),k:cat})));\n }\n return out;\n})()",
"bookUrl": "$.u",
"checkKeyWord": "中字",
"coverUrl": "$.c",
"intro": "$.m",
"name": "$.n"
},
"ruleToc": {
"chapterList": "@js:(function(){\n var html=String(result);\n var doc=Packages.org.jsoup.Jsoup.parse(html);\n var bid='';\n try{ bid=String(book.bookUrl); }catch(e){}\n var m=bid.match(\/[\/]voddetail[\/]([0-9]+)\/);\n if(!m){ try{ m=String(baseUrl).match(\/[\/]voddetail[\/]([0-9]+)\/); }catch(e2){} }\n if(!m) throw new Error('无法识别书籍ID,请刷新详情页后重试');\n var id=m[1];\n var out=[];\n var seen={};\n var as=doc.select('a[href*=vodplay]');\n for(var i=0;i<as.size();i++){\n var h=String(as.get(i).attr('href'));\n var mm=h.match(\/[\/]vodplay[\/]([0-9]+)-([0-9]+)-([0-9]+)[.]html\/);\n if(!mm) continue;\n if(mm[1]!==id) continue;\n var key=mm[2]+'-'+mm[3];\n if(seen[key]) continue;\n seen[key]=1;\n out.push(String(JSON.stringify({n:'第'+mm[3]+'集',u:'\/vodplay\/'+mm[1]+'-'+mm[2]+'-'+mm[3]+'.html'})));\n }\n if(out.length===0) out.push(String(JSON.stringify({n:'正片',u:'\/vodplay\/'+id+'-1-1.html'})));\n return out;\n})()",
"chapterName": "$.n",
"chapterUrl": "$.u"
},
"searchUrl": "https:\/\/hd.huadudm.com\/vodsearch\/{{java.encodeURI(key)}}----------{{(function(){var p=Number(page);if(!(p>0)){p=1;}p=Math.floor(p);try{source.put(String.fromCharCode(104,103,112,103),String(p));}catch(e){}return p;})()}}---.html",
"weight": 0
}