奇怪小说
https://www.aahhss.com
rga (8486)02/15 14:01
/*
version: 2025.0205
完善发现,添加搜索接口by河鹅和
优化搜索发现
目录乱序修复by折木
目录乱序修复可通过设置书籍变量来开启,默认关闭
发现添加最新入库,需要先登录构造本地数据
添加本地搜索,可通过构造的本地数据进行搜索,在搜索关键词前加上name:,id:,author:,tags:即可指定搜索类型,默认为搜索书名,例子:author:佚名
当前支持类型有author,category,id,intro,name,pornrate,score,status,tags,update,word,all,分别是搜索作者,分类,书ID,简介,书名,肉量,评分,状态,标签,更新,字数,全部
发现自动添加书籍到本地数据
本地搜索支持正则,例:id:^95[5-9]\d$、all:(白天|黑夜)
添加更多排序选择
添加设置每次并发数
2025.01.31 修改本地数据保存方法,不再保存到源变量
02.01 优化目录乱序修复
02.04 优化本地数据保存,将数据切分每50万个字符保存,数据网络导出最大为10M,超过10M请使用本地导出
02.05 优化生成发现方法
*/
{ "bookSourceComment": "\/*\nversion: 2025.0205\n完善发现,添加搜索接口by河鹅和\n优化搜索发现\n目录乱序修复by折木\n目录乱序修复可通过设置书籍变量来开启,默认关闭\n发现添加最新入库,需要先登录构造本地数据\n添加本地搜索,可通过构造的本地数据进行搜索,在搜索关键词前加上name:,id:,author:,tags:即可指定搜索类型,默认为搜索书名,例子:author:佚名\n当前支持类型有author,category,id,intro,name,pornrate,score,status,tags,update,word,all,分别是搜索作者,分类,书ID,简介,书名,肉量,评分,状态,标签,更新,字数,全部\n发现自动添加书籍到本地数据\n本地搜索支持正则,例:id:^95[5-9]\\d$、all:(白天|黑夜)\n添加更多排序选择\n添加设置每次并发数\n2025.01.31 修改本地数据保存方法,不再保存到源变量\n02.01 优化目录乱序修复\n02.04 优化本地数据保存,将数据切分每50万个字符保存,数据网络导出最大为10M,超过10M请使用本地导出\n02.05 优化生成发现方法\n*\/\napi = [\n`https:\/\/www.aaccnn.com\/e\/search\/,{\n \"body\": \"keyboard=${key}\",\n \"method\": \"POST\"\n}`,\n`https:\/\/www.aahhss.com\/e\/search\/,{\n \"body\": \"keyboard=${key}\",\n \"method\": \"POST\"\n}`,\n`https:\/\/www.aakkrr.com\/book\/${key}<,\/${page}>`,\ntoDataUrl(key,page-1)]\nv = String(checkData()['api'])\nresult = api[v.match(\/^\\d+$\/)?v:2]", "bookSourceGroup": "写源by河鹅和", "bookSourceName": "奇怪小说", "bookSourceType": 0, "bookSourceUrl": "https:\/\/www.aahhss.com", "bookUrlPattern": "", "concurrentRate": "", "customOrder": -98608, "enabled": true, "enabledCookieJar": false, "enabledExplore": true, "exploreUrl": "@js:\nexpl = []\npush = (title, url, type) => expl.push({\n\ttitle: title,\n\turl: url,\n\tstyle: {\n\t\tlayout_flexGrow: 1,\n\t\tlayout_flexBasisPercent: type\n\t}\n})\n\/\/ 默认一行3个发现项\nflex = 0.25\n\/\/ 获取数据\n$ = checkData()\nif ($.isLocal) {\n\t\/\/ 本地发现\n\tcategorys = new Set()\n\ttags = new Set()\n\tstatus = new Set()\n\tpornrate = new Set()\n\tscore = new Set()\n\t\n\t\/\/ 提取分类、标签、状态、肉量和评分\n\tfor (let bookId in $.books) {\n\t\tlet book = $.books[bookId]\n\t\tif (book.category) {\n\t\t\tbook.category.forEach(cat => categorys.add(cat))\n\t\t}\n\t\tif (book.tags) {\n\t\t\tbook.tags.forEach(tag => tags.add(tag))\n\t\t}\n\t\tif (book.status) {\n\t\t\tstatus.add(book.status)\n\t\t}\n\t\tif (book.pornrate) {\n\t\t\tpornrate.add(book.pornrate.replace(\/[\\d.\\(\\)%]\/g, \"\"))\n\t\t}\n\t\tif (typeof book.score === 'number') {\n\t\t\tscore.add(String(book.score).replace(\/\\.\\d+\/, \"\"))\n\t\t}\n\t}\n\tdata = [\n\t\t{\n\t\t\t\"title\": `📊排行(当前按${$.sortType==\"pornrate\"?\"肉量\":($.sortType==\"score\"?\"评分\":($.sortType==\"word\"?\"字数\":($.sortType==\"update\"?\"更新\":\"ID\")))}${$.order?\"⬆️正\":\"⬇️倒\"}序排列)`,\n\t\t\t\"titleUrl\": \"\",\n\t\t\t\"urlPattern\": \"{{toDataUrl('id:',page-1,'<key>')}}\",\n\t\t\t\"titles\": [[\"🕒ID\", \"id\"], [\"💗肉量\", \"pornrate\"], [\"💯评分\", \"score\"], [\"🎖️更新\", \"update\"], [\"📃字数\", \"word\"]]\n\t\t},\n\t\t{\n\t\t\t\"title\": `📚分类`,\n\t\t\t\"titleUrl\": \"\",\n\t\t\t\"urlPattern\": \"{{toDataUrl('category:<key>',page-1)}}\",\n\t\t\t\"titles\": Array.from(categorys)\n\t\t},\n\t\t{\n\t\t\t\"title\": `🔖标签`,\n\t\t\t\"titleUrl\": \"\",\n\t\t\t\"urlPattern\": \"{{toDataUrl('tags:<key>',page-1)}}\",\n\t\t\t\"titles\": Array.from(tags)\n\t\t},\n\t\t{\n\t\t\t\"title\": `🎐状态`,\n\t\t\t\"titleUrl\": \"\",\n\t\t\t\"urlPattern\": \"{{toDataUrl('status:<key>',page-1)}}\",\n\t\t\t\"titles\":Array.from(status)\n\t\t},\n\t\t{\n\t\t\t\"title\": `💗肉量`,\n\t\t\t\"titleUrl\": \"\",\n\t\t\t\"urlPattern\": \"{{toDataUrl('pornrate:^[\\\\\\\\d.%]+\\\\\\\\(<key>\\\\\\\\)',page-1)}}\",\n\t\t\t\"titles\": Array.from(pornrate)\n\t\t},\n\t\t{\n\t\t\t\"title\": `💯评分`,\n\t\t\t\"titleUrl\": \"\",\n\t\t\t\"urlPattern\": \"{{toDataUrl('score:^<key>(\\\\\\\\.\\\\\\\\d+)?$',page-1)}}\",\n\t\t\t\"titles\": Array.from(score).sort((a, b) => a - b)\n\t\t}\n\t]\n\t\/\/ 过滤没有标签的项\n\tdata = data.filter(d => d.titles.length>0)\n}else{\n\t\/\/ 使用在线发现\n\tdata=JSON.parse(java.base64Decode(\"W3sidGl0bGUiOiLwn4+g6aaW6aG1IiwidGl0bGVVcmwiOiIvIiwidGl0bGVzIjpbXX0seyJ0aXRsZSI6IvCfk5rliIbnsbsiLCJ0aXRsZVVybCI6IiIsInVybFBhdHRlcm4iOiIvY2F0ZWdvcnkvPGluZGV4Pi97e3BhZ2UtMX19IiwidGl0bGVzIjpbIuagoeWbreaYpeiJsiIsIuWutuW6reS5seS8piIsIumDveW4gua\/gOaDhSIsIuWQjOS6uuaUuee8liIsIuezu+e7n+W8guiDvSIsIuepv+i2iumHjeeUnyIsIuS4nOaWueeOhOW5uyIsIuilv+aWuemtlOW5uyIsIuS5oeadkeeIseaDhSIsIuenkeWtpuW5u+aDsyIsIuWoseS5kOaYjuaYnyIsIue7j+WFuOatpuS+oCIsIuWOhuWPsuaetuepuiIsIui0pOiAheWwj+ivtCIsIuW8uuWluOi9ruWluCIsIueOhOW5uyIsIuepv+i2iiIsIumDveW4giIsIuWlh+W5uyIsIuS5seS8piIsIuagoeWbrSIsIuWOhuWPsiIsIuWQjOS6uiIsIuezu+e7nyIsIuenkeW5uyIsIuatpuS+oCIsIuaYjuaYnyIsIuS5oeadkSJdfSx7InRpdGxlIjoi8J+Uluagh+etviIsInRpdGxlVXJsIjoiIiwidXJsUGF0dGVybiI6Ii90YWcvPGluZGV4Pi97e3BhZ2UtMX19IiwidGl0bGVzIjpbIumqqOenkSIsIuWJp+aDhSIsIue6r+eIsSIsIuaXoOe7vyIsIuWPjeW3riIsIueGn+WlsyIsIuiwg+aVmSIsIua3q+WglSIsIuS6uuWmuyIsIueUnOaWhyIsIumAguWQiOWls+eUnyIsIjF2MSIsIua1qua8qyIsIuWQjuWuqyIsIueIveaWhyIsIue+pOS6pCIsIueMjuiJsyIsIuebruWJjeeKryIsIuiCieS+v+WZqCIsIlNNIiwi5o2G57uRIiwi5byC5LiW55WMIiwi56eN6amsIiwi5q+N5a2QIiwi56eN55SwIiwi5Y+X5a2VIiwiTlRMIiwi5q+N5aWz6IqxIiwi5oCn5aW0Iiwi6YGT5YW3Iiwi54G15byCIiwi6Zyy5Ye6Iiwi55e05aWzIiwi5qCh6IqxIiwi55m+5ZCIIiwi5aWz5oCn6KeG6KeSIiwiU0MiLCLlpb3mlofnrJQiLCLkuJ3oopwiLCLnpZ7osaoiLCLlrpjlnLoiLCLniLblpbMiLCLpgIbmjqgiLCLlsI\/pqazmi4nlpKfovaYiLCLlvq7ph43lj6MiLCLmiYvmnqrmlociLCLmgYvotrMiLCLlhajlrrbmobYiLCLlj5joo4UiLCLlp5DlprnoirEiLCJOUCIsIuiQneiOiSIsIuWItuacjSIsIuW\/q+epvyIsIumHjeWPoyIsIk5UUiIsIuWCrOecoCIsIuWHjOi+sSIsIuW8guWbvSIsIuWqmum7kSIsIuiZkOS4uyIsIuWHuui9qCIsIui2s+S6pCIsIuW8uuWluCIsIueLl+ihgCIsIue7j+WFuCIsIuamqOeyviIsIue7v+avjSIsIkZ1dGEiLCLmmpfpu5EiLCLmnKvkuJYiLCLmlLnpgKAiLCLkuqflpbYiLCLmt6vlprsiLCLomZDlv4MiLCLlpI3ku4ciLCLlvq7ogokiLCLnoLTlpIQiLCLmmrTomZAiLCLnm5HnpoEiLCLmgKfovawiLCJCRSIsIumakOWluCIsIuiNr+eJqSIsIuaJqeW8oCIsIuW8guenjeaXjyIsIuS6uuWFvSIsIuS8quWomCIsIuS6pOaNouS8tOS+oyIsIuiAvee+jiIsIueXheWohyIsIuWFrOWqsyIsIueyl+WPoyIsIkhFIiwi5pCe56yRIiwi5Lq65aaWIiwi6Kem5omLIiwi6ICB5biIIiwi5pq06ZyyIiwi576kUCIsIuWQjOS6uiIsIumAhk5UUiIsIue7v+WltCIsIuS4i+WFi+S4iiIsIueZveiZjiIsIuacieeItiIsIue6ouW4vSJdfSx7InRpdGxlIjoi8J+TiuaOkuihjCIsInRpdGxlVXJsIjoiIiwidXJsUGF0dGVybiI6Ii90b3AvPGtleT4ve3twYWdlPT0xPycnOidpbmRleF8nK3BhZ2UrJy5odG1sJ319IiwidGl0bGVzIjpbWyLkurrmsJTmjpLooYwiLCJob3QiXSxbIuaUtuiXj+aOkuihjCIsImNvbGxlY3QiXSxbIueDremXqOWFqOacrCIsIndhbmJlbiJdLFsi6IKJ6YeP5o6S6KGMIiwicG9ybnJhdGUiXSxbIuivhOWIhuaOkuihjCIsInNjb3JlIl0sWyLmnIDmlrDlsI\/or7QiLCJuZXciXV19XQ==\"))\n}\n\/\/ 构造发现数组\ndata.forEach(o => {\n\tpush(o.title, o.titleUrl, 1)\n\tlet flexBasisPercent = flex\n\tlet flag = true\n\tif(o.titles.length == 2 || o.titles.length == 4) {\n\t\tflexBasisPercent=0.4\n\t\tflag=false\n\t}\n\to.titles.map((t, index) => {\n\t\tt = Array.isArray(t) ? t : [t]\n\t\tpush(String(t[0]).replace(\/^(超多肉)$\/,\"$1(>=60%)\").replace(\/^(多肉)$\/,\"$1(40%~60%)\").replace(\/^(中肉)$\/,\"$1(20%~40%)\").replace(\/^(少肉)$\/,\"$1(<20%)\"), o.urlPattern.replace(\/<index>\/,index+1).replace(\/<key>\/,t[t.length-1]), flexBasisPercent)\n\t})\n\tif (flag) {\n\t\tArray.from({ length: [0, 2, 1][o.titles.length % 3] }, () => push(\"\", \"\", flexBasisPercent))\n\t\t}\n})\njava.toast(`\\n✅发现刷新成功✅\\n共${expl.filter(e=>e.url!=\"\").length}个类别`)\nJSON.stringify(expl)", "header": "{\"User-Agent\": \"Mozilla\/5.0 (Linux; Android 8.0.0; MI 5s Plus Build\/OPR1.170623.032; wv) AppleWebKit\/537.36 (KHTML, like Gecko) Version\/4.0 Chrome\/71.0.3578.99 Mobile Safari\/537.36\"}", "jsLib": "\/\/ 读取并返回数据\nfunction checkData(_) {\n\tconst { java, source, cache }= _ || this\n\tjava.log(\"checkData()\")\n\tconst vName = `sourceVariable_${source.getKey()}`\n\tlet temp\n\ttry{\n\t\ttemp = []\n\t\t\/\/ 尝试从缓存中分段读取数据\n\t\tfor(let i = 0; i < cache.get(`${vName}_iLength`);){\n\t\t\ttemp.push(cache.get(`${vName}_${i}`))\n\t\t\ti += 500000\n\t\t}\n\t\ttemp = temp.join(\"\")\n\t\t\/\/ 如果没有数据,尝试从缓存文件或源变量中获取\n\t\tif (!temp||temp==\"\") {\n\t\t\ttemp=cache.getFile(vName)||cache.get(vName)\n\t\t}\n\t\t\/\/ 解析 JSON 数据\n\t\tconst $=JSON.parse(temp)\n\t\t\/\/ 验证数据结构\n\t\tif (typeof $.books!='object') {\n\t\t\tthrow new Error(\"错误数据\")\n\t\t}\n\t\treturn $\n\t} catch (e) {\n\t\tjava.log(`function checkData Error:${e}`)\n\t\treturn reset(false, false, this)\n\t}\n}\n\/\/ 保存数据\nfunction setv(json, _, isString) {\n\tconst { java, source, cache }= _ || this\n\tconst vName = `sourceVariable_${source.getKey()}`\n\tjava.log(\"setv()\")\n\t\/\/ 如果输入不是字符串,则将其转换为 JSON 字符串\n\tif (!isString) {\n\t\tjson = JSON.stringify(json)\n\t}\n\tjava.logType(json)\n\tjava.log(`json length: ${json.length}`)\n\t\/\/ 记录数据的长度\n\tcache.put(`${vName}_iLength`,json.length,0)\n\t\/\/ 分段存储数据\n\tfor (let i = 0; i < json.length;) {\n\t\tcache.put(`${vName}_${i}`,json.slice(i, i += 500000),0)\n\t}\n}\n\/\/ 重置数据\nfunction reset(check, showTip, _) {\n\tconst { java, source, cache }= _ || this\n\tlet vName = String(`sourceVariable_${source.getKey()}`)\n\tjava.log(\"reset()\"+check+showTip)\n\tif(check){\n\t\ttry{\n\t\t\tcheck = java.getVerificationCode(checkImg)\n\t\t}catch(e){}\n\t} else {\n\t\tcheck = \"y\"\n\t}\n\tif (check == \"y\") {\n\tlet $ = {\n\t\tapi:2,\n\t\ttime:20250204,\n\t\tlastestId:11759,\n\t\tsum:50,\n\t\tisLocal:false,\n\t\torder:false,\n\t\terrorIds:[],\n\t\tsortType:\"\",\n\t\tconcurrency:1,\n\t\tbooks:{}\n\t\t}\n\tfor (i = 0; i < cache.get(`${vName}_iLength`);) {\n\t\tcache.delete(`${vName}_${i}`)\n\t\ti += 500000\n\t}\n\tcache.delete(vName)\n\tcache.delete(`${vName}_iLength`)\n\tsetv($, _||this)\n\tif (showTip) {\n\tjava.toast('\\n✅重置成功,请重新构造本地数据')\n\t}\n\treturn $\n\t} else {\n\t\tjava.toast(\"\\n❎用户取消重置❎\")\n\t}\n}\nfunction getl(arr, page){\n\treturn arr.slice(page*500, (+page+1)*500)\n}\nfunction toDataUrl(key, page, sortType) {\n\tconst { java } = this\n\tlet data = [key, page, sortType]\n\treturn `data:;base64,${java.base64Encode(data.join(\"|==|\"))},{\"type\":\"\"}`\n}\nfunction sleep(t) {\n Packages.java.lang.Thread.sleep(t)\n}\nfunction createRegExp(input) {\n const flagsRegex = \/\\(\\?([igm]*)\\)(?!\\))\/g;\n let flags = '';\n let pattern = input;\n let match;\n while ((match = flagsRegex.exec(input)) !== null) {\n flags += match[1];\n pattern = pattern.substring(0, match.index) + pattern.substring(match.index + match[0].length);\n }\n return new RegExp(pattern, flags);\n}\nfunction getSortValue(book, type) {\n\tlet data = book[type]\n\tlet value\n\tswitch (type) {\n\t\tcase 'pornrate':\n\t\t\tvalue = data.split(\"%\")[0]\n\t\t\tbreak;\n\t\tcase 'update':\n\t\t\tvalue = parseInt(data.replace(\/-\/g,\"\"))\n\t\t\tbreak;\n\t\tcase 'word':\n\t\t\tm = data.match(\/[^\\d.]+\/)\n\t\t\tf = 1\n\t\t\tif (m&&\/k\/i.test(m)) {\n\t\t\t\tf = 1000\n\t\t\t}else if(m&&\/m\/i.test(m)) {\n\t\t\t\tf = 1000000\n\t\t\t}\n\t\t\tvalue = Number(data.match(\/[\\d.]+\/))*f\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tvalue = data\n\t}\n\treturn value\n}\nfunction spArr(arr, num) {\n\tlet newArr = []\n\tfor(let i = 0; i < arr.length;){\n\t\tnewArr.push(arr.slice(i, i += num))\n\t}\n\treturn newArr\n}\ncheckImg = \"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKIAAAAYCAYAAAB5oyYIAAAAAXNSR0IArs4c6QAADZJJREFUaEPtmguUVWUVx\/\/3MTN3gHgKzAxgvEWIbKlAChYoKIGoCUkkoaCYZD4ijUhraSVWRg8fPcwyiqIwtETNUAMEiRCLUElAhAScGQYQELgzl5l7Wz\/8PvvmcM655yIZyzV7rVlw7jnne+z933v\/9\/5OTE3SpIHjQAOx42ANTUto0oAKAuLixUr2aN3\/wUQycd7B2sykXgPW\/b5Jh00aOBYaKAiIG1f2ndixrHROi+bJ+I6auhV7dqdH9hmy\/s0CFsJ8uZDnh0pivOfzjHmCpDMkPS6pwefZCkndzTjpAtb3\/3j0g5KqzR\/zl0j6gKSXJR3Is6Bekjb+DxaNnb4gaYX5C5sCPf87wA68d6qkMZJuCxskMhDXLjuxTZtWbZ7vVJ7qFovFdDBdX7+j6uC4bgPW\/TGiIgZK+oakT0jaG\/DOzyRtkjQrz5gjJd0pqb\/Pc6WSFkkaIul2SbfkGetDkh41z+AkVZLulvTLiPuK8lhnSTMlzZC03\/MCgGO\/dr4ukl6TBEBfCBl8uHHEwZKek\/RJSfGQ51+S9E9zv6+kYp9nX5RUL+lcSX+WNEnSI85zOAb3rTSXtEbSw2ZvfkFmrCQyZyjWIgNx8+r+F1VUpOYXFyeKWEU2m9P2yvTWht37encbtqU2gjXaSvqrpKclfVZST0lLPO91MtfbPb8TKV+RBMhSkr4iqdyMw6PMT+RLSLpLEsb5nDHU1ZJ+E7I+5hxn7rO3i8z7gMe7jgjb9H0EcC2V9KQk1uMa7GiA+BHjPPdJusmM92oAuOyCcMofmYvVkk7zWWlrSRlJBwM2OszHZqzlKUlflvQdn\/dwMpzwnQMxt1jJyvanLO7QvmRIza6s9u6VunSOKZfLqbqqbkqPgS88ENFC55hFY\/jHTPp0XyWS\/cN4l\/s7SgZspAu\/zV4rCaPcIenTkpiHaHKB8cYrC4hwZ0l6RpKf0iNu0\/exM40RcRDWSrrCcYgmKyV9y7zVw+wRAxLp2PtaZ8RRkn4r6deS2LcboaKuD+rC3Oh6nqRvOwGAqM3cRFiiHXKrpJONXnf5TILOiehEv4c897HJl0y0DqRlkSLiyyv7TqwoK51zKJOLz7yjSJU7Eho3OqNLxyZUs6tuyf4t+0f2GvVKXUQt4DlwQEL\/NJMG7KtEI+QPzlgo62vmur0kDEVkxSAYCYFXkYJJ+4BuufP+pyR9UdI9hhoE0QL7ynhj6MslzYm4p6iPkQlwDta+TlILSd4sYK8Zk4j8PUmzzQSAGNrwfbOnQ1En9nmulaEhZJu\/mftnOxnLRk8AiePgSKTuILnZRGmb\/u1z0DHuNTNZy\/f9vECEG7Zt2WppRVmqf1VNRpdc3Vy5XExDz8jo1uk51dZm63fsrB3ZY+A6Um6hcpIkwGVlmYlkGMzKPk9EGGGiB1EP4T6KxNsWSrrKs4jdBvA\/N9EH7wwTDI3Bf2zeK3RPYc8ThQCf6wyFpGbSOu9\/16S6r5t0u\/UoFvlxA+jekggi8EZ4JEK0zZooeLr57Vfm3\/kOp44y7VdNoQIVg\/\/7Sl4gblrZZ2xFWWpeKpUo2lGT0YRrS3QgndCYczKacU1M8Zi0dVu6KlH\/ZvcuZ24LqlC\/KWmiWQG8kP9PldTVsyqiJeItVtgAQELgOqSjpLnG2z5slBhUwcMrTzTcZ1uI9iDfzEW1SHFFRQhn8hMiM7yVaEvh5Eo7ScyDQ5Gy2jg3KVZcTl0IEN2uA86CkQdIAkysPZ+QhayNSO9U3PBtpMxU6kRKAI6wfvZCVMPRyVg\/NE6Kftw0zFqsjdx13GvGobgKDFahQMytVtHriZOXlbUvGhSPxbRrT70mTS9Rze6EJozJ6LrJOSXiVNANqqzOXNVz8IafBmgCoJBySEstJeGNHzObz6c87ldKesKAD8NNkXSeA0SiqvVYOx6GgguRttknfApeFiZwHFISxsVIpFCIeJBQBPFsPw9gqTahAt1MSqIKtsLeXerBfjD0XPNAlKrZplC49gJDVdBxPgFstIrc6Ac\/RQgM6IpCxuKCrAOQ+phncCqclGyBY7MXhGIEHsnvXiHL0cFA\/+jEV0KBuGFJ18kV5an7mzUDbjnt3degK2aW6NWtCU2bUKcp43UYiLhK9c5Dy\/dXZofn4YoUGyzKboAqGGOFyWbHi2lpwEEYx\/ImeCaeRnr+qBkIUEKguYabQLrzAZEIC7ekYMK7SU\/oB44ZJNAEnscp+NcK4IVP3WAqffgVQsS43kRS9oIwDzzYFmGkMHpuVP+Wu7lV\/ylOERFmP3qtNUbXLvCZ00Yp5qYgIgNR\/SIA0drnYqNHe01hhb69gMOZ4K3e3y0PpXDcaRy7MCBuerJNq1TLVs+WdyjpFzPbPXAwq2m3Fmvt+qRmTK3V+NFSnNxM5\/VAtr666uCFPc7eRpM5SLxAtJ5JxIOTuEJPjBYN0QZij5CCbF8QoCGAjtQPv7Gei2IwdCFAvFTS\/ZLgrUQwHAZvJtJYQHj3BXgBEc5hqYfd0yBJqzwvsC44Kq0sCjC7Rx6zrSJvscI9WkkIY9NtgNKwxveH6DoIiKzLRsHLDHUAJDbDAER7oGBbPO51IUAko7BeQE4nAnvSpz1CAj1q8+LykeUdSxeWlMQsF1NtXU7XzyrSijVFuv2GtM4f9hZHRGjlvLa9bneuYVunbsMacSB30iAgQogBoysdjJFdILr34YoIHJEUjCGtggFPIUDE0BjgB6YFZOch7XWUROQL4r8YBt5EqqJogOdCAYiC3naFBaKNUPAvQEDLyFb6QakZ8AJ4OgY4BqnUOp6fbYOAyKkN3QX0Q4Qj3Vog4hjPOv3IsNTszhkUEXFs9AclwymJ7HQBogHxxfkqbl3e6ZnyDslBFmi8Wd8g3TS7SItWFOmem9MaOkCy0ZL76dqsXq\/OXN5zeFVQ2yMIiLzubR7byBAGRIoQOB3HfKQYlI9gLKrnKBERko9BMDStDPfkgyM0jP4TAzC\/Phj8dIu5z1qI3nC+X\/jo2wtEm9otd+OVMI4IyDEkkYy0fzRAZA7CB4WGF4ictsABKSwQAHSdcw3lCIuIv5NE24s1AnhS8mhzsABvJnPRjzyiheYbEdf\/qd1lFR2KH2jenBLlv5LLSbfcndCCp1OaO2u\/TusXa9QuP8wVa+qXlJ9VTTPYTywQSWMYmYqUlOoawr5nPdoFImmFIzkMgCGs2NBPMxahORwlIkLOARkK5zTmXz6Lpo9G0xeD0NrxEyIpoJouifYGqZO2kVcogEjNRFoyDUeLRFrLwfIB0Y5HG+edAJFxAKEXiOicotBLE9zrICByjIcdgAFAJvqhB74JoMtB2wlb8zvFTSM5AohrH23Vpl3z5KLy9snTG6HQvDb38bgWLi3W7Olpde54JI73H8jWV9ZkRvUevZfjLK8ARJROm4XN0Q+zvasoEZE2CemCFIxCOIoCqEREOBO\/IUQmgEiKJuIRpbzFCkUMjVoqZYDot167flo0gBugswZvZIRaEJFp5wCuz\/vsnQgN6BebKMFaiRA4FzzTSpSq+VgBkbUCDCgFHBE6AYguNIuJmpopKAEd9QFBhqiIbclIcEMrVPkPmkOMRvo+Akmbn2g5smPbxCOlqfjhM2WvLFsjrXopqcljMmrb8sgzdqLmlsr6XbGSvZ19uCKpBW73F0kTTCoFiFE5ImuypwlejsgxmDc1248GOMR3gQin5FiSyE1laD968Nsyv6EnQMhxFR9mcL77hvMw90nhtHLorwFKV+xHBLxHUcS6qPopNtyPCniHShND0uej1eInUYAItaGXCai8czAm0dCeZHGNDW40hwfsE\/ECkcIQDulWx3x4gu7JBFdI4oMUwEbnwfYj7R7QE3qniOG5v7s33t7oxrtU0uykZivKTig6Ne7zHUddJqdr7izVU8+ldO+N+zRqcIP4Escr6bqcqnZkrux+QS1Gc4U2C0Ai3e1x+lluaqaygsSjSNIEjWN7lOeO5QdEqmrGonGL8dkF0QuwESEvMQPA4YhQXHs\/vAgCI7+zbvb0GafvZ59nzveZFO9GTMszMQCGpl1FGmOdtE9wRNI4erF\/KBXawB8tLqKHm+qDgEhkJzLBweC7ABqA+X1WR8rkIwcrnCHbFpiNYhaIdCjo\/9JSIjO4XybBK9EHhQlz8S490ckB5+A4GidgBANscvgDi0YoWv9QampF+\/h9LUobMcNGhlm2Jq5V64o1+fy02rb0o5hvNf+rdueWl5+bphp0hYn5ds2SVdvqcIFIVMG7ACNcirNjv28O\/YBIoxdvJFVAAYiC8DZaQwDPRj4MTDTaEIa6gHuAHa7ngg3nIcqRkr2NdWtAwGNPVOBLOAecCr6LUXiOP5uJACXOSkXLN33uaUwQEKmGoT+MwydbFA9E3rBvQO02qcIpKACw1bcFItQE8KEvnJfizE\/QK1yaPmXQFzy8x37R49tBoBGSNi1IPta1U3yUWyl7Z8tmpWxOSnJqGiJv7MvVtR1xiKo2nzCSH9DyvXc83OeEh6hL05vqGU7q9zGrezSXb922XXY0X9XkGzvffSIk4H\/XpREQN8zXiKKixMPJeKRzy9DFZho0r8fFDWGnEu\/6Zo\/xhKQkIjdRjZRGJLKN92M81Xt\/uLwfPbz3VdC0w+NBA01APB6s0LQG\/Qc\/LMFGH5FawAAAAABJRU5ErkJggg==\"", "lastUpdateTime": "1739599313955", "loginUi": "[\n\t{\n\t\t\"name\": \"获取数目\",\n\t\t\"type\": \"text\"\n\t},\n\t{\n\t\t\"name\": \"并发数\",\n\t\t\"type\": \"text\"\n\t},\n\t{\n\t\t\"name\": \"⚙️设置获取数目⚙️\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"sum=(Number(result.获取数目)||50);setInfo('获取数目',sum);saveProgress('\\\\n✅成功设置获取数目为'+setData('sum',sum))\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" ⚙️设置并发数⚙️ \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"concurrency=(Number(result.并发数)||1);setInfo('并发数',concurrency);saveProgress('\\\\n✅成功设置并发数为'+setData('concurrency',concurrency))\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" 💡显示当前设置💡 \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"v=checkData();java.toast('\\\\n当前搜索接口:'+sN(String(v['api']).match(\/^[0-9]+$\/)?v['api']:2)+'\\\\n当前设置获取数目:'+v['sum']+'\\\\n当前并发数:'+(v['concurrency']||1)+'\\\\n当前最新bookid:'+v['lastestId']+'\\\\n当前发现模式:'+(v.isLocal?'本地':'在线')+'\\\\n当前本地数据顺序:按'+(v.sortType?((v.sortType=='pornrate')?'肉量':((v.sortType=='score')?'评分':((v.sortType=='word')?'字数':((v.sortType=='update')?'更新':'ID')))):'ID')+(v.order?'正':'倒')+'序排列\\\\n本地数据更新时间:'+v['time']+'\\\\n本地数据数目:'+Object.keys(v.books).length)\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 1\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"⏳构造本地数据⌛\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"setLocal()\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"⚠️重置本地数据⚠️\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"reset(true,true)\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"❎结束构造数据❎\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"source.put('isEnd',1)\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"◀️查看当前进度▶️\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"p=source.get('progress');String(p)?java.toast(p):java.toast('\\\\n❎当前无进度')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"🧭切换发现模式🧭\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"v=checkData();setData('isLocal',!v.isLocal,v);saveProgress('\\\\n✅成功将发现切换为'+(v.isLocal?'本地':'在线')+'模式,请刷新')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 0,\n\t\t\t\"layout_flexBasisPercent\": 0.46\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" ⚙️切换数据顺序(默认按ID排序)⚙️ \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"v=checkData();java.toast('\\\\n✅当前本地数据顺序为:\\\\n按'+(v.sortType?((v.sortType=='pornrate')?'肉量':((v.sortType=='score')?'评分':((v.sortType=='word')?'字数':((v.sortType=='update')?'更新':'ID')))):'ID')+(v.order?'正':'倒')+'序排列')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 1\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" ⬆️🆔⬇️ \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"saveProgress('\\\\n✅成功将本地数据顺序切换为\\\\n按ID'+(setData('sortType','id').order?'正':'倒')+'序排列')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.25\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"💗肉量💗\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"saveProgress('\\\\n✅成功将本地数据顺序切换为\\\\n按肉量'+(setData('sortType','pornrate').order?'正':'倒')+'序排列')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.25\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"💯评分💯\",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"saveProgress('\\\\n✅成功将本地数据顺序切换为\\\\n按评分'+(setData('sortType','score').order?'正':'倒')+'序排列')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.25\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" 🎖️更新🎖️ \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"saveProgress('\\\\n✅成功将本地数据顺序切换为\\\\n按更新'+(setData('sortType','update').order?'正':'倒')+'序排列')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" 📃字数📃 \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"saveProgress('\\\\n✅成功将本地数据顺序切换为\\\\n按字数'+(setData('sortType','word').order?'正':'倒')+'序排列')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" ⚙️设置搜索接口⚙️ \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"java.toast('\\\\n点击下面按钮即可设置')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 1\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"0⃣️:aaccnn(失效) \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"setData('api',0);saveProgress('\\\\n成功设置接口0⃣️')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"1⃣️:aahhss(失效) \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"setData('api',1);saveProgress('\\\\n成功设置接口1⃣️')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"2⃣️:aakkrr(默认) \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"setData('api',2);saveProgress('\\\\n成功设置接口2⃣️')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"3⃣️:本地搜索 \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"setData('api',3);saveProgress('\\\\n成功设置接口3⃣️')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" ⚙️数据导入导出⚙️ \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"isEncode=Number(source.get('isEncode'));source.put('isEncode',Number(!isEncode));java.toast('\\\\n📝输入数据地址可进行📝\\\\n导入支持http\/https链接和本地链接\\\\n导出地址也会显示在数据地址\\\\n本地导出地址为相对路径,在阅读缓存路径里\\\\n\/android\/data\/{package}\/cache\/\\\\n当前为'+((!isEncode)?'编码后':'原文本')+'导出')\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 1\n\t\t}\n\t},\n\t{\n\t\t\"name\": \"数据地址\",\n\t\t\"type\": \"text\"\n\t},\n\t{\n\t\t\"name\": \" 📥导入数据📥 \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"importData(result.数据地址)\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 1\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" 📤本地导出📤 \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"exportData()\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t},\n\t{\n\t\t\"name\": \" 📤网络导出📤 \",\n\t\t\"type\": \"button\",\n\t\t\"action\": \"exportData(true)\",\n\t\t\"style\": {\n\t\t\t\"layout_flexGrow\": 1,\n\t\t\t\"layout_flexBasisPercent\": 0.4\n\t\t}\n\t}\n]", "loginUrl": "function login() {\n\tinfo = JSON.parse(source.getLoginInfo())\n\tsum=(Number(info[\"获取数目\"])||50)\n\tconcurrency=(Number(info[\"并发数\"])||1)\n\tdata=checkData()\n\tdata['sum']=sum\n\tdata['concurrency']=concurrency\n\tsetv(data,this)\n\tsetInfo('获取数目',sum)\n\tsetInfo('并发数',concurrency)\n}\nfunction setData(key,value,_){\n\tdata=_||checkData(this)\n\tdata[key]=value\n\tif (key=='sortType'){\n\t\tdata['order']=!data.order\n\t\tsetv(data,this)\n\t\treturn data\n\t\t}\n\tsetv(data,this)\n\treturn data[key]\n}\nfunction setInfo(key,value){\n\tlet data=JSON.parse(source.getLoginInfo()||\"{}\")\n\tdata[key]=String(value)\n\tputLoginInfo(JSON.stringify(data))\n\t}\nfunction putLoginInfo(info){\n\ttry {\n\t\tlet key=java.androidId()\n\t\tlet encodeStr=Packages.android.util.Base64.encodeToString(java.createSymmetricCrypto(\"AES\", key).encrypt(info),2)\n\t\tcache.put(`userInfo_${source.getKey()}`, encodeStr)\n\t\treturn true\n\t\t}catch(e){\n\t\t\tjava.log(e)\n\t\t\treturn source.putLoginInfo(info)\n\t\t}\n\t}\nfunction saveProgress(progress,notshow){\n\tsource.put(\"progress\",progress)\n\tif(!notshow){java.toast(progress)}\n\t}\nfunction setLocal(times){\n\tsource.put('isEnd',0)\n\tsaveProgress(`\\n⌛开始${times?(\"第\"+times+\"次\"):\"\"}构造本地数据⏳`,times)\n\terror=false\ntime = +java.timeFormatUTC(new Date(), 'yyyyMMdd', 8);\n$=checkData()\nif ((+$.time||0)<time){\n\ttry{\n\tsleep(1000)\n\tsaveProgress(\"\\n🚀正在获取最新书籍🆔\")\n\tresult=org.jsoup.Jsoup.parse(java.ajax(source.key))\n\threfs=result.select(\".chapter-new li a.name\")\n\threfs.sort((a,b)=>b.attr(\"href\").match(\/\\d+\/)-a.attr(\"href\").match(\/\\d+\/))\n\tlastestId=Number(hrefs.attr(\"href\").match(\/\\d+\/)[0])\n\t$.time=time\n\t$.lastestId=lastestId\n\t}catch(e){\n\t\tjava.log(e)\n\t\terror=true\n\t\tsaveProgress(\"\\n⚠️获取最新书籍🆔失败,请尝试切换网络\")\n\t\tsleep(800)\n\t\t}\n\t}\n\turls=[]\n\tfor (let i=$.lastestId;i>$.lastestId-$.sum;i--){\n\t\tif (((i in $.books)&&$.books[i].tags)||i<1||(($.errorIds?$.errorIds:$.errorIds=[])&&$.errorIds.includes(i)))continue\n\t\turls.push(`${source.key}\/book\/${i}\/`)\n\t\t}\n\tsleep(1000)\n\tsaveProgress(`\\n当前最新书籍🆔为${$.lastestId}\\n🚀正在并发获取${urls.length}本书籍🚀`)\n\tsleep(800)\n\tcount=0\n\turlslist=spArr(urls,$.concurrency||1)\n\tfor (let i in urlslist){\n\t\tif (Number(source.get('isEnd'))){\n\t\t\tsleep(800)\n\t\t\tsaveProgress(`\\n❎用户终止在${count}\/${urls.length}❎`)\n\t\t\terror=false\n\t\t\tsleep(800)\n\t\t\tbreak\n\t\t\t}\n\t\ttry{\n\t\t htmlList=java.ajaxAll(urlslist[i])\n\t\t htmlList.forEach(h=>{\n\t\t \thtml=h.body()\n\t\t\tlet e=org.jsoup.Jsoup.parse(html)\n\t\t\tif(html==\"\"||html.match(\/<h1>404 Not Found\/)){$.errorIds.push(Number(urls[i].match(\/\\d+\/)))}\n\t\t\tid=String(e.select('[property=\"og:novel:read_url\"]').attr(\"content\")).match(\/book\\\/(\\d+)\/)[1]\n\t\t\t$.books[id]={author:e.select('[property=\"og:novel:author\"]').attr(\"content\"),category:Object.values(e.select(\".categories a\").textNodes()),cover:String(e.select('[property=\"og:image\"]').attr(\"content\")).replace(\/.*file\\\/cover\\\/\/,\"\"),intro:e.select('.book-desc').textNodes().toArray().join(\"\"),name:e.select('[property=\"og:novel:book_name\"]').attr(\"content\"),pornrate:e.select('.pornrate dd').text(),score:Number(e.select('.score dd').text()),status:e.select('[property=\"og:novel:status\"]').attr(\"content\"),tags:Object.values(e.select('.tag a').textNodes()),update:String(e.select('.new dd').textNodes()[0]).trim(),word:e.select(\".wordcount dd\").text()}\n\t\t\tcount++\n\t\t\tprogress=`\\n${count%2?\"⏳\":\"⌛\"}当前进度(${count}\/${urls.length})\\n${'﹦'.repeat(Math.floor((count\/urls.length)*39))}${'﹣'.repeat(Math.ceil((urls.length-count)*39\/urls.length))}`\n\t\t\tsaveProgress(progress,true)\n\t\t\ttime=new Date()\n\t\t\tif(count==1||count==(urls.length)||time-pretime>15000){\n\t\t\tpretime=new Date()\n\t\t\tjava.toast(progress)\n\t\t\t}\n\t\t\t})\n\t\t\tsleep(parseInt((Math.random()+0.65)*1000))\n\t\t\t\n\t\t\t}catch(e){\n\t\t\t\tjava.log(e)\n\t\t\t\terror=true\n\t\t\t\tsaveProgress(`\\n❎终止在${count}\/${urls.length}`)\n\t\t\t\tsleep(1000)\n\t\t\t\tbreak\n\t\t\t\t}\n\t\t}\n\tsource.put(\"progress\",\"\")\n\tjava.longToast(`\\n✅构造本地数据完成,新增${count}本`)\n\tif(count>0){setv($)}\n\tif(error&&!Number(source.get('isEnd'))&&((times||0)<3)){\n\t\tsleep(2000)\n\t\tprogress=`\\n🔄开始第${(times||0)+1}次重试`\n\t\tsaveProgress(progress)\n\t\tsleep(1000)\n\t\tsetLocal((times||0)+1)\n\t\t}\n}\nfunction sN(str){\n\treturn String(str).replace(\/(\\d)\/g,`$1⃣️`)\n\t}\nfunction exportData(t) {\n\ttry{\n\t\tsaveProgress(\"\\n✅开始导出数据\")\n\t\tsleep(800)\n\t\tv=JSON.stringify(checkData())\n\t\tbody=v\n\t\tif (Number(source.get('isEncode'))){\n\t\t\tbody=String(v).replace(\/[\\u4e00-\\u9fa5]+\/g, (match)=>match.replace(\/[\\u4e00-\\u9fa5]\/g,(char)=>'\\\\u' + ('0000' + char.charCodeAt(0).toString(16)).slice(-4)))\n\t\t}\n\t\tif (t) {\n\t\t\tjava.toast(\"\\n⚠️网络导出最大为10M,超过10M将导出失败\")\n\t\t\tresp=java.post('https:\/\/jsonblob.com\/api\/jsonBlob',body, {\"Content-Type\":\"application\/json\",\"Accept\": \"application\/json\"})\n\t\t\tpath=String(resp.header(\"Location\")).replace(\/http:\/,\"https:\")\n\t\t} else {\n\t\t\tm=String(JSON.parse(source.getLoginInfo()||'{}').数据地址).match(\/(data\\\/[^\\\/]+\\\/cache)?\\\/?([^\\\/]+\\.json)\/)\n\t\t\tif(m){\n\t\t\t\tjava.deleteFile(\"\/\"+m[m.length-1])\n\t\t\t}\n\t\t\turl=`data:;${java.md5Encode16(v)},{\"type\": \"json\"}`\n\t\t\tcontent=java.hexEncodeToString(body)\n\t\t\tpath=java.downloadFile(content,url)\n\t\t}\n\t\tsetInfo(\"数据地址\",path)\n\t\tsaveProgress(`\\n✅导出成功✅\\n${t?'地址为':'保存在阅读缓存路径\\n\/android\/data\/{package}\/cache'}${path}`)\n\t} catch (e) {\n\t\tjava.log(e)\n\t\tsaveProgress(\"\\n❎导出失败❎\\n错误信息已打印在日志\")\n\t}\n}\nfunction importData(url) {\n\ttry{\n\t\tif(!(String(url||\"\").trim())) {\n\t\t\turl=\"https:\/\/jsonblob.com\/api\/jsonBlob\/1334825983680897024\"\n\t\t}\n\t\tsetInfo(\"数据地址\",url)\n\t\tsaveProgress(\"\\n✅开始导入数据\")\n\t\tsleep(800)\n\t\turl = String(url)\n\t\tisDelete = false\n\t\tif (url.startsWith(\"http\")) {\n\t\t\tpath = java.downloadFile(url)\n\t\t\tisDelete = true\n\t\t}else {\n\t\t\tm = url.match(\/(data\\\/[^\\\/]+\\\/cache)?\\\/?([^\\\/]+\\.json)\/)\n\t\t\tpath = \"\/\"+m[m.length-1]\n\t\t}\n\t\tdata = java.readTxtFile(path)\n\t\tdata = \/base64Data\/.test(data)?JSON.parse(data).base64Data:data\n\t\tdata = \/^[A-Za-z0-9+\/]+={0,2}$\/.test(data)?java.base64Decode(data):data\n\t\tdata = JSON.parse(data)\n\t\tsaveProgress('\\n✅数据数目:'+Object.keys(data.books).length)\n\t\tsetv(data)\n\t\tsetInfo('获取数目',data.sum)\n\t\tsetInfo('并发数',data.concurrency||1)\n\t\tsleep(2000)\n\t\tif (isDelete) {\n\t\t\tjava.deleteFile(path)\n\t\t}\n\t\tsaveProgress(\"\\n✅导入成功✅\")\n\t}catch (e) {\n\t\tjava.log(e)\n\t\tsaveProgress(\"\\n❎导入失败❎\\n错误信息已打印在日志\")\n\t}\n}", "respondTime": 180000, "ruleBookInfo": { "author": "[property=\"og:novel:author\"]@content", "coverUrl": "[property=\"og:image\"]@content", "init": "", "intro": " \n🆔:{{baseUrl.match(\/\\d+\/)[0]}} 📈评分:{{@.score dd@text}} 💗肉量:{{@.pornrate dd@text}} \n👁️观看:{{@.onclick dd@text}} 💌收藏:{{@.collect dd@text}}\n📝 简介:{{@.book-desc@textNodes}}\n🔖 标签:{{String(java.getString('.tag a@text')).replace(\/\\s\/g,\",\")}}\n🕰 更新:{{@[property~=update_time]@content}}", "kind": ".categories a@text&&[property~=status|update_time]@content", "lastChapter": "[property~=las?test_chapter_name]@content", "name": "[property=\"og:novel:book_name\"]@content", "tocUrl": "", "wordCount": ".wordcount dd@text" }, "ruleContent": { "content": ".content@p@textNodes", "replaceRegex": "##标题:{{chapter.title}}", "title": ".content@p@textNodes##标题[::](.*)\\n##{{chapter.title}} $1###", "webJs": "" }, "ruleExplore": { "author": "$.author", "bookList": "<js>\nbooklist=[]\n$=checkData()\nif(baseUrl==\"http:\/\/localhost\/\"){\n\t[key,page,sortType]=String(java.hexDecodeToString(result)).split(\"|==|\")\nif (\/^(author|category|id|intro|name|pornrate|score|status|tags|update|word):\/.test(key)){\n\t\t[type,key]=key.split(\/:([\\w\\W]+)?\/,2)\n\t\t}else{\n\t\t\t[key,page]=String(java.hexDecodeToString(result)).split(\"|==|\")\n\t\t\ttype=\"name\"\n\t\t\t}\n\t\t\tbooks=$.books\n\tfor (let i in books){\n books[i][\"id\"]=i\n booklist.push(books[i])\n }\n Regkey=createRegExp(key)\n booklist=booklist.filter(b=>String(b[type]).match(Regkey))\n \n if(\/(pornrate|score|update|word)\/.test($.sortType)||sortType){\n st=sortType||$.sortType\n booklist.sort((a,b)=>getSortValue(a,st)-getSortValue(b,st))\n \t}\n if(!$.order){\n \tbooklist.reverse()\n \t}\n if (booklist.length>0&&page==0)java.toast(`\\n✅成功获取${booklist.length}本书籍`)\n else if((!booklist.length>0)&&page==0)java.toast(\"\\n⚠️请先登录构造本地数据\")\n booklist=getl(booklist,page);\n\t}else {\n\t\tresult=java.getElements(\".book-like a\")\n\t\tcount=0\n\t\tresult.forEach(r=>{\n\t\t\tid=java.getString(\"href\",r).match(\/book\\\/(\\d+)\/)[1]\n\t\t\ttemp={name:java.getString('h4@text',r),author:java.getString(\"span@text\",r),cover:String(java.getString(\"img@src\",r)).replace(\/.*file\\\/cover\\\/\/,\"\")}\n\t\t\tif (!(id in $.books)){\n\t\t\t\t$.books[id]=Object.assign({},temp)\n\t\t\t\tcount++\n\t\t\t\t}\n\t\t\ttemp.id=id\n\t\t\tbooklist.push(temp)\n\t\t\t})\n\t\tif (count>0){\n\t\t\tjava.toast(`\\n✅本地数据新增${count}本`)\n\t\t\tsetv($)\n\t\t\t}\n\t\t}\nJSON.stringify(booklist)\n<\/js>\n$[*]", "bookUrl": "{{source.key}}\/book\/{{$.id}}\/", "coverUrl": "{{String(source.key).replace(\/www\/,\"static\")}}\/file\/cover\/{{$.cover##.*file\\\/cover\\\/}}", "intro": " 🆔:{{$.id}} {{$.score##^(\\S)##📈评分:$1}} {{String(result.pornrate||\"\").replace(\/^(\\S)\/,'💗肉量:$1').replace(\/\\(.*\\)\/,\"\")}}\n{{$.intro##^\\n##📝 简介:}}\n🔖 标签:{{$.tags##\\s##,}}\n{{$.update##^(\\s*\\S)##🕰 更新:$1}}", "kind": "$.tags&&$.category&&$.status&&$.update", "lastChapter": "", "name": "$.name", "wordCount": "$.word" }, "ruleReview": {}, "ruleSearch": { "author": "{{baseUrl.match(\/\\\/e\\\/\/)?java.getString('span@text'):\"\"}}{{$.author||\"\"}}", "bookList": "<js>\njava.log(baseUrl)\nif(baseUrl==\"http:\/\/localhost\/\"){\n\t[key, page, sortType] = String(java.hexDecodeToString(result)).split(\"|==|\")\n\tif (\/^(author|category|id|intro|name|pornrate|score|status|tags|update|word|all)[:]\/.test(key)) {\n\t\t[type,key]=key.split(\/:([\\w\\W]+)?\/,2)\n\t} else {\n\t\t[key, page] = String(java.hexDecodeToString(result)).split(\"|==|\")\n\t\ttype=\"name\"\n\t}\n\t$=checkData()\n\tbooks=$.books\n\tbooklist=[]\n\tfor (let i in books) {\n\t\tbooks[i][\"id\"]=i\n\t\ttype == \"all\" ? Object.defineProperty(books[i], 'all', {\n\t\t\tget: function(){\n\t\t\t\treturn JSON.stringify(this)\n\t\t\t}\n\t\t}) : \"\"\n\t\tbooklist.push(books[i])\n\t}\n\tRegkey=createRegExp(key)\n\tbooklist = booklist.filter(b => String(b[type]).match(Regkey))\n\tif(\/(pornrate|score|update|word)\/.test($.sortType)||sortType) {\n\t\tst = sortType || $.sortType\n\t\tbooklist.sort((a, b) => getSortValue(a, st)-getSortValue(b, st))\n\t}\n if (!$.order) {\n \tbooklist.reverse()\n \t}\n \tif (booklist.length>0&&page==0) java.toast(`\\n✅成功获取${booklist.length}本书籍\\n当前为按${$.sortType==\"pornrate\"?\"肉量\":($.sortType==\"score\"?\"评分\":($.sortType==\"word\"?\"字数\":($.sortType==\"update\"?\"更新\":\"ID\")))}${$.order?\"⬆️正\":\"⬇️倒\"}序排列`)\n \telse if ((!booklist.length>0)&&page==0) java.toast(\"\\n❎本地数据未找到,请切换搜索接口\")\n \tbooklist=getl(booklist,page);\n \tjava.setContent(JSON.stringify(booklist))\n \tresult=java.getElements(\"$[*]\")\n}else result=java.getElements(\".book-like a||.grid-item\")\n<\/js>", "bookUrl": "{{@href||a.0@href||\"\"}}{{baseUrl==\"http:\/\/localhost\/\"?`${source.key}\/book\/${result.id}\/`:\"\"}}##aaqqcc##aahhss", "checkKeyWord": "name:我的", "coverUrl": "{{String(source.key).replace(\/www\/,\"static\")}}\/file\/cover\/{{$.cover##.*file\\\/cover\\\/}}{{@img@src||\"\"##.*file\\\/cover\\\/}}", "intro": " 🆔:{{$.id||\"\"}}{{@href||a.0@href||\"\"##\\D}} {{$.score##^(\\S)##📈评分:$1}} {{String(result.pornrate||\"\").replace(\/^(\\S)\/,'💗肉量:$1').replace(\/\\(.*\\)\/,\"\")}}\n{{$.intro##^\\n##📝 简介:}}\n🔖 标签:{{$.tags##\\s##,}}\n{{$.update##^(\\s*\\S)##🕰 更新:$1}}", "kind": "$.tags&&$.category&&$.status&&$.update", "name": "{{@h4@text||h3@text||\"\"}}{{$.name||\"\"}}", "wordCount": "$.word" }, "ruleToc": { "chapterList": "<js>\nlet e = org.jsoup.Jsoup.parse(result);\ntry{\n\tv = checkData()\n\tid=String(e.select('[property=\"og:novel:read_url\"]').attr(\"content\")).match(\/book\\\/(\\d+)\/)[1]\n\tv.books[id]={author:e.select('[property=\"og:novel:author\"]').attr(\"content\"),category:Object.values(e.select(\".categories a\").textNodes()),cover:String(e.select('[property=\"og:image\"]').attr(\"content\")).replace(\/.*file\\\/cover\\\/\/,\"\"),intro:e.select('.book-desc').textNodes().toArray().join(\"\"),name:e.select('[property=\"og:novel:book_name\"]').attr(\"content\"),pornrate:e.select('.pornrate dd').text(),score:Number(e.select('.score dd').text()),status:e.select('[property=\"og:novel:status\"]').attr(\"content\"),tags:Object.values(e.select('.tag a').textNodes()),update:String(e.select('.new dd').textNodes()[0]).trim(),word:e.select(\".wordcount dd\").text()}\n\tsetv(v)\n} catch(error) {\n\tjava.log(error)\n}\nlet chapters = e.select(\".book-chapter a\");\nlet chapterData = [];\nlet chapterNumber = 0;\nif (book.getVariable(\"custom\") != \"\") {\n\t java.toast(\"\\n✅目录乱序修复已开启\")\n\t chapters.forEach((item) => {\n let title = item.text()\n let chapterNumberMatch = title.match(\/第(\\d+)(-\\d+)?章\/);\n if (chapterNumberMatch) {\n chapterNumber = parseInt(chapterNumberMatch[1], 10);\n }\n chapterData.push({\n number: chapterNumber,\n text: title,\n href: item.attr(\"href\")\n });\n });\n chapterData.sort((a, b) => a.number - b.number);\n} else {\n chapterData = chapters\n}\nchapterData\n<\/js>", "chapterName": "text", "chapterUrl": "href" }, "searchUrl": "{{cookie.removeCookie(source.getKey());eval(String(source.bookSourceComment))}}", "variableComment": "", "weight": 0 }