大灰狼融合
https://api.doubi.tk 提示:点击登录切换服务器按钮可进行切换(当前书源为融合版)
shuaige668 (3463)01/09 21:58
番茄、七猫、哔哩哔哩轻小说、得间、QQ、熊猫、起点(69来源、追书帮等)、喜马拉雅,分别为:融合版(小说、漫画、听书融合在一起,点击登录切换
{ "bookSourceGroup": "番茄小说", "ruleExplore": { "author": "author", "bookList": "$.data.data", "lastChapter": "{{$.last_chapter_title}} • {{$.last_update_time}}", "wordCount": "word_number", "intro": "{{$.media}}小说 \n{{$.abstract}}", "kind": "{{$.category}}\n{{$.score}}\n{{$.status}}\n{{$.source}}\n{{$.tags}}", "coverUrl": "thumb_url", "bookUrl": "{{$..book_id || ''}}|==|{{$..book_name || ''}}|==|{{$..author || ''}}|==|{{$..thumb_url || ''}}|==|{{$..media || ''}}\n<js>\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet ms = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\n\nlet [book_id, raw_book_name, raw_author, raw_thumb_url,media] = result.split(\"|==|\");\n\n\nlet book_name = java.base64Encode(raw_book_name);\nlet author = java.base64Encode(raw_author);\nlet thumb_url = java.base64Encode(raw_thumb_url);\n\nlet catalogue_url = `${base_url}\/multi_detail?bookId=${book_id}&book_name=${book_name}&author=${author}&thumb_url=${thumb_url}`;\n\ncatalogue_url\n<\/js>", "name": "book_name" }, "weight": 0, "ruleContent": { "content": "content" }, "loginUrl": "function login() {\n let zdyserver;\n try {\n zdyserver = String(source.getLoginInfoMap()['服务器地址(可不填)']);\n if (zdyserver.includes('http')) {\n setArgument('server', zdyserver);\n java.toast(`\\n\\n当前服务器为自定义服务器\\n${zdyserver}\\n\\n切换服务器请先清空服务器地址中的数据`);\n }\n } catch (error) {\n }\n ;\n let zdytone_id;\n try {\n zdytone_id = String(source.getLoginInfoMap()['其他音色填写后点击右上角✔']);\n if (zdytone_id) {\n setArgument('tone_id', zdytone_id);\n }} catch (error) {\n }\n ;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n\n for (let server of serverList) {\n let key = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (key) {\n let keyParts = key.split('secretKey=');\n if (keyParts.length > 1) {\n key = keyParts[keyParts.length - 1];\n setArgument('key', key);\n return key;\n }\n }\n }\n\n return '';\n}\n\n\/\/ 填写密钥\nfunction loginqt() {\n let key = gets_key()\n if (key && key != \"\") {\n java.toast(\"您已填写秘钥:\" + key);\n return false\n }\n java.startBrowserAwait(getArgument('server') + '\/check_key', '登录大灰狼小说书源');\n key = gets_key()\n if (key) {\n java.longToast('登录成功,秘钥:' + key);\n return true\n } else {\n java.toast('登录失败!!!!!');\n return false\n }\n}\n\n\/\/登录番茄\nfunction fq_login() {\n var cookies = cookie.getCookie('fanqienovel.com') || java.getCookie('fanqienovel.com')\n java.log(cookies)\n if (cookies && cookies != \"\") {\n java.toast(\"请不要重复登录,请先退出登录!\")\n return false\n }\n try {\n java.startBrowserAwait(\"https:\/\/fanqienovel.com\/\", \"登录\")\n } catch (e) {\n java.toast(e)\n }\n try {\n cookie.removeCookie(\"snssdk.com\")\n } catch (e) {\n }\n var cookies = cookie.getCookie(\"fanqienovel.com\")\n if (!cookies || cookies == \"\") {\n java.toast(\"登录失败!\")\n return false\n }\n java.toast(\"登录成功!\")\n return true\n}\n\n\/\/退出番茄\nfunction logout() {\n cookie.removeCookie(\"fanqienovel.com\");\n cookie.removeCookie(\"snssdk.com\");\n \/\/cookie.removeCookie(getArgument('server'));\n java.toast(\"退出登录成功\");\n}\n\n\/\/获取参数\nfunction getArgument(key) {\n let open_argument = source.getVariable();\n return getArguments(open_argument, key);\n}\n\n\/\/设置参数\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument, '');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\n\/\/首页\nfunction api() {\n java.startBrowserAwait(getArgument('server') + '\/', \"接口文档\");\n}\n\n\/\/打赏\nfunction vip() {\n java.startBrowserAwait(getArgument('server') + '\/coffee', \"喝咖啡\");\n}\n\n\/\/获取密钥\nfunction hqmy() {\n java.startBrowserAwait(getArgument('server') + '\/key', \"获取密钥\");\n}\n\nvar server = getArgument('server');\n\n\/\/获取搜索\nfunction get_search() {\n var search = getArgument('search');\n var datadist = {\n \"-1\": \"阅读模式\",\n \"-2\": \"漫画模式\",\n \"0\": \"音频模式\",\n };\n var tishi = '\\n\\n当前搜索模式:' + datadist[search]\n java.toast(tishi);\n return search\n}\n\n\/\/设置搜索\nfunction set_search(mode, name) {\n setArgument('search', mode);\n setArgument('tone_id', mode);\n java.toast('\\n\\n已切换至' + name);\n}\n\n\/\/获取服务器\nfunction get_server() {\n var server = getArgument('server');\n var tishi = '\\n\\n当前服务器:' + server\n java.toast(tishi);\n return server\n}\n\n\n\/\/设置服务器\nfunction set_server() {\n let zdyserver;\n try {\n zdyserver = String(source.getLoginInfoMap()['服务器地址(可不填)']);\n if (zdyserver.includes('http')) {\n setArgument('server', zdyserver);\n java.toast(`\\n\\n当前服务器为自定义服务器\\n${zdyserver}\\n\\n切换服务器请先清空服务器地址中的数据`);\n } else {\n zdyserver = '';\n }\n } catch (error) {\n zdyserver = '';\n }\n ;\n if (!zdyserver) {\n const servers = String(source.bookSourceUrl).split('\\n').map(s => s.trim()).filter(s => s && !s.includes('提示'));\n const currentServer = getArgument('server') || '';\n const currentIndex = servers.indexOf(currentServer);\n\n const nextIndex = currentIndex >= 0 ? (currentIndex + 1) % servers.length : 0;\n const nextServer = servers[nextIndex];\n\n setArgument('server', nextServer);\n java.toast(`\\n\\n当前服务器${nextIndex+1}:${nextServer}\\n\\n注意:切换服务器后需要在详情页刷新目录才能生效`);\n }\n}\n\n\n\/\/获取音色\nvar tone_id = getArgument('tone_id');\n\nfunction get_tone_id(arg) {\n var datadist = {\n \"0\": \"默认音色\",\n \"-1\": \"阅读模式\",\n \"-2\": \"漫画模式\",\n \"51\": \"多人发音\",\n \"1\": \"甜美少女\",\n \"2\": \"清亮青叔\",\n \"5\": \"开朗青年\",\n \"6\": \"温柔淑女\",\n \"4\": \"成熟大叔\",\n \"74\": \"大叔升级\",\n \"30\": \"优雅御姐\"\n };\n var tone_id = datadist[arg] || arg;\n var tishi = '\\n\\n当前音色:' + tone_id;\n java.toast(tishi);\n}\n\n\/\/设置音色\nfunction set_tone_id(mode, name) {\n let zdytone_id;\n try {\n zdytone_id = String(source.getLoginInfoMap()['其他音色填写后点击右上角✔']);\n if (zdytone_id) {\n setArgument('tone_id', zdytone_id);\n java.toast(`\\n\\n当前音色为自定义音色\\n${zdytone_id}\\n\\n切换音色请先清空音色输入框中的数据`);\n } else {\n zdytone_id = '';\n }\n } catch (error) {\n zdytone_id = '';\n }\n if (!zdytone_id) {\n let toast = \"\\n\\n已切换至:\" + name + '\\n\\n切换后需要刷新详情页';\n setArgument('tone_id', mode);\n java.toast(toast);\n }\n}\n\nfunction zr() {\n let toast = '\\n\\n真人语音无法手动切换\\n\\n前往搜索找包含主播的书籍进入即可';\n java.toast(toast);\n}\n\nfunction mh() {\n let toast = '\\n\\n漫画无法手动切换\\n\\n前往搜索找包含主播的书籍进入即可';\n java.toast(toast);\n}", "searchUrl": "{{key}}\n@js:\nlet search_title = result;\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\n\nlet open_argument = source.getVariable();\n\t \t\t\t \t\n\t \t\t\t \t\nlet base_url = getArguments(open_argument,'server');\nlet ms = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\n\nlet media;\nif (ms == '0') {\n media = `${base_url}\/searchAudio?title=`+search_title+'&media=喜马拉雅,番茄';\n} else if (ms == '-2') {\n media = `${base_url}\/searchCaricature?title=`+search_title+'&media=番茄';\n} else {\n media = `${base_url}\/searchNovel?title=`+search_title\n}\nkey = '&key=' + key;\n\/\/java.toast(media + key);\nmedia + key", "ruleSearch": { "author": "author", "bookList": "$..book_data[*]", "lastChapter": "{{$.media}}-{{$..book_id}}\n<js>\n\nfunction lastChapterTitle(media,bookid) {\n \n let url;\n let last;\n if (media == \"番茄\") {\n \t last=fq_last(bookid);\n return last\n } else if (media == \"七猫\") {\n \t last=qm_last(bookid);\n return last\n \n } else {\n \treturn '无'\n \t}\n}\n\n\nfunction fq_last(bookid) {\n\tlet url = `https:\/\/api5-normal-sinfonlineb.fqnovel.com\/reading\/bookapi\/multi-detail\/v\/?aid=1967&iid=1&version_code=999&book_id=${bookid}`;\n let last =JSON.parse(java.ajax(url)).data[0]; \n return last[\"last_chapter_title\"]+\" · \"+java.timeFormat(last[\"last_chapter_update_time\"]*1000);\n\t\n\t}\n\nfunction qm_last(bookid) {\n\tlet headers={'app-version':'51110','platform':'android','reg':'0','AUTHORIZATION':'','application-id':'com.****.reader','net-env':'1','channel':'unknown','qm-params':''}\n\tsign_key='d3dGiJc651gSQ8w1'\n\nparams={'id':bookid, 'imei_ip':'2937357107','teeny_mode':0}\n\nvar urlEncode = function (param, key, encode) { \n if(param==null) return ''; \n var paramStr = ''; \n var t = typeof (param); \n if (t == 'string' || t == 'number' || t == 'boolean') { \n paramStr += '&' + key + '=' + ((encode==null||encode) ? encodeURIComponent(param) : param); \n } else { \n for (var i in param) { \n var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i); \n paramStr += urlEncode(param[i], k, encode); \n } \n } \n return paramStr; \n};\nparamSign=String(java.md5Encode(Object.keys(params).sort().reduce((pre,n)=>pre+n+'='+params[n],'')+sign_key));\nheaderSign=String(java.md5Encode(Object.keys(headers).sort().reduce((pre,n)=>pre+n+'='+headers[n],'')+sign_key))\nparams['sign']=paramSign;\nheaders['sign']=headerSign;\nlet url = \"https:\/\/api-bc.wtzw.com\/api\/v4\/book\/detail?\"+urlEncode(params);\noption = {'headers':headers};\nlet last =JSON.parse(java.ajax(url+','+JSON.stringify(option)))[\"data\"][\"book\"];\nlet last2 = `${last[\"latest_chapter_title\"]} · ${java.timeFormat(last['update_time']*1000)} `\n\treturn last2\n\t}\nlet media = result.split(\"-\")[0];\nlet bookid = result.split(\"-\")[1].split(\"_\")[0];\nlet lasts = lastChapterTitle(media,bookid);\n\n`${media}: ${lasts}`\n<\/js>", "coverUrl": "thumb_url", "wordCount": "word_number", "intro": "{{$.media}}小说 \n{{$.abstract}}", "kind": "category&&status&&score&&last_chapter_update_time", "checkKeyWord": "炙热沦陷", "name": "book_name", "bookUrl": "{{$..book_id || ''}}|==|{{$..book_name || ''}}|==|{{$..author || ''}}|==|{{$..thumb_url || ''}}|==|{{$..media || ''}}\n<js>\nlet [book_id, raw_book_name, raw_author, raw_thumb_url,media] = result.split(\"|==|\");\n\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet ms = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\nlet book_name = java.base64Encode(raw_book_name);\nlet author = java.base64Encode(raw_author);\nlet thumb_url = java.base64Encode(raw_thumb_url);\n\nlet catalogue_url = `${base_url}\/multi_detail?bookId=${book_id}&book_name=${book_name}&author=${author}&thumb_url=${thumb_url}`;\n\ncatalogue_url\n<\/js>" }, "enabledExplore": true, "ruleBookInfo": { "author": "author", "tocUrl": "{{$..book_id || ''}}|==|{{$..book_name || ''}}|==|{{$..author || ''}}|==|{{$..thumb_url || ''}}\n<js>\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet tone_id = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\n\nlet [book_id, raw_book_name, raw_author, raw_thumb_url] = result.split(\"|==|\");\n\njava.put(\"id\", book_id);\n\nlet book_name = java.base64Encode(raw_book_name);\nlet author = java.base64Encode(raw_author);\nlet thumb_url = java.base64Encode(raw_thumb_url);\n\nlet catalogue_url = `${base_url}\/detail?bookId=${book_id}&book_name=${book_name}&author=${author}&thumb_url=${thumb_url}`;\n\ncatalogue_url\n<\/js>", "lastChapter": "last_chapter_title", "wordCount": "word_number", "intro": "$..book_id\n<js>\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet tone_id = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\nvar datadist = {\n \"-1\": \"纯净阅读\",\n \"-2\": \"纯净漫画\",\n \"51\": \"多人发音\",\n \"0\": \"默认发音\",\n \"1\": \"甜美少女\",\n \"2\": \"清亮青叔\",\n \"5\": \"开朗青年\",\n \"6\": \"温柔淑女\",\n \"4\": \"成熟大叔\",\n \"74\": \"大叔升级\",\n '999':'喜马拉雅听书'\n};\n\nlet ms;\nms = datadist[tone_id];\nif (!ms) {\n\t\tms = tone_id\n\t\t}\n\nvar tishi = '\\n\\n当前模式:'+ ms +'\\n\\n如切换,请切换请下拉刷新详情页\\n由于缓存原因,已听的需要切换到下一章再切回来\\n'\n\n\nlet res = result.split(\"\\n\")[0]\nlet media = res.split(\"_\")[1] || 'fanqie'\nlet bookid = res.split(\"_\")[0];\nlet info;\nif (media == 'fanqie') {\ntry {\n info = JSON.parse(java.ajax(`${base_url}\/tts_detail?&bookid=${bookid}`));\n } catch (error) {\n info = {'abstract': \"\"}\n }\n} else {\n info = {'abstract': \"\"}\n }\n\n\nif (!key) {\n jj = '\\n\\n❌️当前用户未填写密钥,请先输入密钥\\n密钥获取途径,书籍详情页,点击右上角点击登陆,获取后,填写,再次刷新详情页'\n }\n else if (!info.abstract) {\n jj = \"\"\n } else {\n jj =tishi + info.abstract\n }\n\n<\/js>", "kind": "category&&status&&score&&last_chapter_update_time", "coverUrl": "thumb_url", "name": "book_name", "init": "" }, "ruleToc": { "chapterUrl": "{{$..itemId}}|==|{{$..book_id || ''}}|==|{{$..book_name || ''}}|==|{{$..author || ''}}|==|{{$..thumb_url || ''}}|==|{{$..media || ''}}\n@js:\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet tone_id = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\n\n\n\/\/ 设备类型检测\nlet device, devicetype;\ntry {\n devicetype = java.androidId();\n device = 'android';\n} catch (e) {\n devicetype = java.deviceID();\n device = 'ios';\n}\n\n\/\/ 数据\nlet [itemId, book_id, book_name, author, thumb_url, media] = result.split(\"|==|\");\n\n\nlet catalogue_url = `${base_url}\/reader?item_id=${itemId}&book_id=${book_id}&tone_id=${tone_id}&key=${key}&device=${devicetype}&book_name=${book_name}&author=${author}&thumb_url=${thumb_url}&media=${media}`;\n\ncatalogue_url", "chapterList": "data.chapterListWithVolume[*].*\n@js:\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet tone_id = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\nfunction deviceType() {\n try {\n return!!java.androidId();\n } catch (e) {\n return false;\n }\n}\nlet device = deviceType()? 'android' : 'ios';\nlet genreValue = JSON.parse(java.ajax(book.bookUrl)).genre;\nvar datadist = {\n \"-1\": \"纯净阅读\",\n \"-2\": \"纯净漫画\",\n \"51\": \"多人发音\",\n \"0\": \"真人发音\",\n \"1\": \"甜美少女\",\n \"2\": \"清亮青叔\",\n \"5\": \"开朗青年\",\n \"6\": \"温柔淑女\",\n \"4\": \"成熟大叔\",\n \"74\": \"大叔升级\"\n};\nvar ms = String(tone_id)\nif (genreValue === '0' && ms === '-1') {\n\tif (device === 'android') {\n book.type = 8;} else {\n \tbook.type = 0;\n \t}\n} else if (genreValue === '1') {\n\t if (device === 'android') {\n book.type = 64;} else {\n \tbook.type = 2;\n \t}\n}else if (genreValue === '4') {\n\t var ms = '0';\n\t if (device === 'android') {\n book.type = 32;} else {\n \tbook.type = 1;\n \t}\n} else if (genreValue === '9999'){\n \tvar ms = '-1';\n \tif (device === 'android') {\n book.type = 8;} else {\n \tbook.type = 0;\n \t}\n\t }else if (genreValue!='0' && genreValue!='1' && genreValue!='4' && ms === '-1'){\n \tvar ms = '-1';\n \tif (device === 'android') {\n book.type = 8;} else {\n \tbook.type = 0;\n \t}\n\t } else {\n\t \tif (device === 'android') {\n book.type = 32;} else {\n \tbook.type = 1;\n \t}\n\t \t};\nresult", "updateTime": "firstPassTime", "chapterName": "title" }, "loginUi": "\n[ {\n \"name\": \"☕请杯咖啡,解除下载限制\",\n \"type\": \"button\",\n \"action\": \"vip()\"\n }, {\n \"name\": \"更新书源\",\n \"type\": \"button\",\n \"action\": \"api()\"\n },\n\n {\n \"name\": \"♥♥♥♥♥♥ 填写密钥 ♥♥♥♥♥♥\",\n \"type\": \"button\",\n \"action\":\"loginqt()\"\n }, {\n \"name\": \"服务器地址(可不填)\",\n \"type\": \"text\"\n },{\n \"name\": \"番茄登录\",\n \"type\": \"button\",\n \"action\": \"fq_login()\"\n },\n\n {\n \"name\": \"退出登录\",\n \"type\": \"button\",\n \"action\": \"logout()\"\n },{\n \"name\": \"切换服务器\",\n \"type\": \"button\",\n \"action\": \"set_server(server)\"\n },{\n \"name\": \"当前模式\",\n \"type\": \"button\",\n \"action\": \"get_search()\"\n },\n {\n \"name\": \"当前音色\",\n \"type\": \"button\",\n \"action\": \"get_tone_id(tone_id)\"\n }, {\n \"name\": \"当前服务器\",\n \"type\": \"button\",\n \"action\": \"get_server()\"\n },\n {\n \"name\": \"🔎搜小说\",\n \"type\": \"button\",\n \"action\": \"set_search('-1','小说搜索')\"\n },\n {\n \"name\": \"🔎搜音频\",\n \"type\": \"button\",\n \"action\": \"set_search('0','音频搜索')\"\n },{\n \"name\": \"🔎搜漫画\",\n \"type\": \"button\",\n \"action\": \"set_search('-2','漫画搜索')\"\n },\n {\n \"name\": \"阅读模式\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('-1','纯净阅读')\"\n },\n {\n \"name\": \"多人发音\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('51','多人发音')\"\n },\n {\n \"name\": \"甜美少女\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('1','甜美少女')\"\n },\n {\n \"name\": \"清亮青叔\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('2','清亮青叔')\"\n },\n {\n \"name\": \"开朗青年\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('5','开朗青年')\"\n },\n {\n \"name\": \"温柔淑女\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('6','温柔淑女')\"\n },\n {\n \"name\": \"成熟大叔\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('4','成熟大叔')\"\n },\n {\n \"name\": \"大叔升级\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('74','大叔升级')\"\n },\n {\n \"name\": \"优雅御姐\",\n \"type\": \"button\",\n \"action\": \"set_tone_id('30','优雅御姐')\"\n },\n {\n \"name\": \"其他音色填写后点击右上角✔\",\n \"type\": \"text\"\n }\n ]", "jsLib": "function get_key(cookie){\nlet key;\nkey = cookie.split('secretKey=');\nkey = key[key.length-1];\nreturn key\n}\n\nfunction getArguments(open_argument,key) {\n try {\n open_argument = JSON.parse(open_argument);\n } catch (e) {\n open_argument = {\n \"search\": \"-1\",\n \"tone_id\": \"-1\",\n \"server\": \"https:\/\/api.doubi.tk\"\n };\n }\n if (key) {return open_argument[key];} else {return open_argument}\n}\n", "bookSourceUrl": "https:\/\/api.doubi.tk\n提示:点击登录切换服务器按钮可进行切换(当前书源为融合版)", "lastUpdateTime": "1736431082998", "customOrder": -7, "bookSourceType": 0, "modificationDate": 1736341113648.8281, "enabled": true, "bookSourceName": "大灰狼融合", "variableComment": "", "bookSourceComment": "20241104新增指定来源搜索\n20241124新增详情页音色提示\n20241126修复bug\n20241129更新秘钥填写方式\n20241217更新服务器切换功能\n20250104新增服务器\n20250105登录新增手动填写服务器、音色", "cloudRecordID": "C99AE5FA-3C53-4482-AB0B-E5E7E40A7987", "respondTime": 180000, "exploreUrl": "<js>\nfunction setArgument(key, value) {\n let open_argument = source.getVariable();\n open_argument = getArguments(open_argument,'');\n open_argument[key] = value;\n open_argument = JSON.stringify(open_argument);\n source.setVariable(open_argument);\n return open_argument;\n}\n\nfunction gets_key() {\n var servers = String(source.bookSourceUrl);\n const serverList = servers.split('\\n');\n \n for (let server of serverList) {\n let keys = String(cookie.getCookie(server)) || String(java.getCookie(server));\n if (keys) {\n let keyParts = keys.split('secretKey=');\n if (keyParts.length > 1) {\n keys = keyParts[keyParts.length - 1];\n setArgument('key', keys);\n return keys;\n }\n }\n }\n return ''; \n }\n\nlet open_argument = source.getVariable();\nlet base_url = getArguments(open_argument,'server');\nlet ms = getArguments(open_argument,'tone_id');\nlet key = getArguments(open_argument,'key');\nif (!key) {\n\tkey = gets_key();\n\t}\n\nlet data = {\n \"男\": {\n \"玄幻\": 7,\n \"都市\": 1,\n \"洪荒\": 66,\n \"无敌\": 384,\n \"末世\": 68,\n \"诸天万界\": 71,\n \"科幻\": 8,\n \"星际\": 77,\n \"重生\": 36,\n \"系统\": 19,\n \"神豪\": 20,\n \"鉴宝\": 17,\n \"三国\": 67,\n \"二次元\": 39,\n \"历史\": 12,\n \"美食\": 78,\n \"奶爸\": 42,\n \"娱乐圈\": 43,\n \"大唐\": 73,\n \"外卖\": 75,\n \"宠物\": 74,\n \"学霸\": 82,\n \"游戏动漫\": 57,\n \"体育\": 15,\n \"直播\": 69,\n \"年代\": 79,\n \"文化历史\": 62,\n \"海岛\": 40,\n \"神医\": 26,\n \"明朝\": 126,\n \"武侠\": 16,\n \"灵异\": 100,\n \"穿越\": 37,\n \"剑道\": 80,\n \"都市修真\": 124,\n \"赘婿\": 25,\n \"盗墓\": 81,\n \"推理\": 61,\n \"无限流\": 70,\n \"种田\": 23,\n \"战争\": 97,\n \"天才\": 90,\n \"职场\": 127,\n \"悬疑\": 10,\n \"成功励志\": 56,\n \"空间\": 44,\n \"腹黑\": 92,\n \"诗歌散文\": 46,\n \"家庭\": 125,\n \"影视小说\": 45,\n \"生活\": 48,\n \"都市生活\": 2,\n \"扮猪吃虎\": 93,\n \"大秦\": 377,\n \"漫威\": 374,\n \"火影\": 368,\n \"西游\": 373,\n \"龙珠\": 376,\n \"聊天群\": 381,\n \"海贼\": 370,\n \"奥特同人\": 367,\n \"特种兵\": 375,\n \"反派\": 369,\n \"校花\": 385,\n \"女帝\": 378,\n \"单女主\": 389,\n \"神奇宝贝\": 371,\n \"九叔\": 383,\n \"求生\": 379,\n \"无女主\": 391,\n \"武魂\": 386,\n \"网游\": 372,\n \"战神\": 27,\n \"都市脑洞\": 262,\n \"都市种田\": 263,\n \"都市日常\": 261,\n \"历史脑洞\": 272,\n \"玄幻脑洞\": 257,\n \"奇幻仙侠\": 259,\n \"都市青春\": 396,\n \"传统玄幻\": 258,\n \"历史古代\": 273\n },\n \"女\": {\n \"幻想言情\": 32,\n \"现代言情\": 3,\n \"现言甜宠\": 395,\n \"现言脑洞\": 267,\n \"先婚后爱\": 265,\n \"都市日常\": 261,\n \"古言脑洞\": 253,\n \"古言萌宝\": 249,\n \"古言甜宠\": 394,\n \"现言日常\": 269,\n \"现言复仇\": 268,\n \"玄幻言情\": 248,\n \"医术\": 247,\n \"无敌\": 384,\n \"种田\": 23,\n \"萌宝\": 28,\n \"美食\": 78,\n \"游戏动漫\": 57,\n \"娱乐圈\": 43,\n \"直播\": 69,\n \"女扮男装\": 388,\n \"二次元\": 39,\n \"团宠\": 94,\n \"无cp\": 392,\n \"青梅竹马\": 387,\n \"病娇\": 380,\n \"科幻\": 8,\n \"武侠\": 16,\n \"年代\": 79,\n \"重生\": 36,\n \"灵异\": 100,\n \"公主\": 83,\n \"甜宠\": 96,\n \"盗墓\": 81,\n \"系统\": 19,\n \"女强\": 86,\n \"皇后\": 84,\n \"推理\": 61,\n \"文化历史\": 62,\n \"生活\": 48,\n \"反派\": 369,\n \"末世\": 68,\n \"悬疑\": 10,\n \"穿越\": 37,\n \"学霸\": 82,\n \"扮猪吃虎\": 93,\n \"清穿\": 76,\n \"穿书\": 382,\n \"快穿\": 24,\n \"皇叔\": 87,\n \"空间\": 44,\n \"宠妻\": 30,\n \"豪门总裁\": 29,\n \"影视小说\": 45,\n \"成功励志\": 56,\n \"职场\": 127,\n \"民国\": 390,\n \"都市生活\": 2,\n \"腹黑\": 92,\n \"星际\": 77,\n \"天才\": 90,\n \"古代言情\": 5,\n \"家庭\": 125,\n \"兽世\": 72,\n \"校园\": 4,\n \"诗歌散文\": 46,\n \"虐文\": 95,\n \"嫡女\": 88,\n \"王妃\": 85,\n \"精灵\": 89,\n \"马甲\": 266\n }\n};\n\nconst groupDatas = [];\nlet infoData = [];\nfunction deviceType() {\n try {\n return!!java.androidId();\n } catch (e) {\n return false;\n }\n}\nlet device = deviceType()? 'android' : 'ios';\nif (device == 'android' && (get_key(String(cookie.getCookie('fanqienovel.com') || java.getCookie('fanqienovel.com'))))) {\n function groupQuery() {\n const url = base_url + \"\/group_name?cookie={{get_key(String(cookie.getCookie('fanqienovel.com') || java.getCookie('fanqienovel.com')))}}\";\n const res = java.ajax(url);\n const data = JSON.parse(res).data;\n\n data.forEach(group => {\n let key;\n for (key in group) {\n groupDatas.push({\n \"title\": key,\n \"url\": base_url +\"\/bookshelf2?page={{page}}&book_ids=\" + group[key].join(\",\"),\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.45\n }\n });\n }\n });\n\n if (groupDatas.length % 2 !== 0) {\n groupDatas.push({\n \"title\": \"--\",\n \"url\": \"\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.45\n }\n });\n }\n }\n\n try {\n \tjava.longToast(\"请稍等,正在更新分组数据!\");\n \/\/ 用户信息\n const userUrl = base_url + '\/fquser?sessionid={{String(cookie.getKey(\"fanqienovel.com\", \"sessionid\"))}}';\n const userRes = java.ajax(userUrl);\n const userInfo = JSON.parse(userRes).data.name;\n\n infoData = [\n {\n \"title\": `${userInfo}个人中心`,\n \"url\": \"\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n }\n ];\n groupQuery();\n } catch (e) {\n java.longToast(\"网络错误或登录失效或阅读版本过低,请重新登录番茄重试!\");\n }\n\n}\n\n\/\/ 合并数据\nlet datas1 = [\n {\n \"title\": \"番茄官方书架\",\n \"url\": base_url + \"\/bookshelf?page={{page}}&cookie={{cookie.getCookie('fanqienovel.com') || java.getCookie('fanqienovel.com')}}\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.45\n }\n },\n {\n \"title\": \"大灰狼阅读记录\",\n \"url\": base_url + \"\/bookshelf?page={{page}}&key=\" + key,\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.45\n }\n }\n];\n\nconst datas2 = [{\n \"title\": \"书籍排行榜 ٩( ˃̶͈̀௰˂̶͈́ )و\",\n \"url\": \"\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"title\": \"推荐榜单\",\n \"url\": base_url + '\/discover?page={{page}}&side_type=10',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"完结榜单\",\n \"url\": base_url +'\/discover?page={{page}}&side_type=11',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"热搜榜单\",\n \"url\": base_url +'\/discover?page={{page}}&side_type=12',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"黑马榜单\",\n \"url\": base_url +'\/discover?page={{page}}&side_type=13',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"爆更榜单\",\n \"url\": base_url + '\/discover?page={{page}}&side_type=15',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"巅峰榜单\",\n \"url\": base_url +'\/discover?page={{page}}&type=0',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"男频精选\",\n \"url\": base_url + '\/discover?page={{page}}&type=2',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"女频精选\",\n \"url\":base_url + '\/discover?page={{page}}&type=3',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"title\": \"每周推荐\",\n \"url\": base_url +'\/discover?page={{page}}&type=1',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n }];\nconst datas = datas1.concat(infoData, groupDatas, datas2);\n\n\nfunction generateUrl(k, k1, sort, status) {\n return `${base_url}\/discover?offset={{(page - 1) * 10}}&limit=10&tags=${data[k][k1]}&status=${status}&sort=${sort}`;\n}\n\nfor (let k in data) {\n datas.push({\n \"title\": \"❦ \" + k + \"生频道 ❧\",\n \"url\": \"\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n });\n for (let k1 in data[k]) {\n datas.push({\n \"title\": '༺༴ '+k1+' ༴༻',\n \"url\": '',\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n });\n datas.push({\n \"title\": \"推荐排行\",\n \"url\": generateUrl(k, k1, 0, 'ALL'),\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n });\n \n datas.push({\n \"title\": \"评分排行\",\n \"url\": generateUrl(k, k1, 1, 'ALL'),\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n });\n \n datas.push({\n \"title\": \"热门排行\",\n \"url\": generateUrl(k, k1, 2, 'ALL'),\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n });\n }\n}\n\n\n\nJSON.stringify(datas);\n<\/js>", "enabledCookieJar": true, "bookUrlPattern": "" }