速读谷
https://www.suduguu.com/
ycbsteamed-buns (14809)10/07 13:17
修复一下楼下速读谷正文显示不全,加一个自动切换源的按钮。
{
"bookSourceComment": "by艳阳 | 优化:姚浅书\n域名池:suduguu.com \/ shudugu.org \/ sudugu520.com\n按钮:⚡智能换源 \/ 🔄切换 \/ 🔍自动选 \/ 📋当前 \/ 📶延迟",
"bookSourceGroup": "自制",
"bookSourceName": "速读谷",
"bookSourceType": 0,
"bookSourceUrl": "https:\/\/www.suduguu.com\/",
"bookUrlPattern": "https?:\\\/\\\/(www\\.)?(shudugu\\.org|sudugu520\\.com|suduguu\\.com)\\\/\\d+(\\\/.*)?",
"concurrentRate": "1",
"customButton": false,
"customOrder": -9,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": true,
"eventListener": false,
"exploreUrl": "<js>\nvar host = getServerHost();\nvar cats = [\n {title: \"完结小说\", url: host + '\/wanjie\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"都市小说\", url: host + '\/dushi\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"玄幻小说\", url: host + '\/xuanhuan\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"轻小说\", url: host + '\/qing\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"仙侠小说\", url: host + '\/xianxia\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"历史小说\", url: host + '\/lishi\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"科幻小说\", url: host + '\/kehuan\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"诸天无限\", url: host + '\/zhutianwuxian\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"游戏小说\", url: host + '\/youxi\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"奇幻小说\", url: host + '\/qihuan\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"悬疑小说\", url: host + '\/xuanyi\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"体育小说\", url: host + '\/tiyu\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"官场小说\", url: host + '\/guanchang\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"军事小说\", url: host + '\/junshi\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"武侠小说\", url: host + '\/wuxia\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"乡村小说\", url: host + '\/xiangcun\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"现实小说\", url: host + '\/xianshi\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"言情小说\", url: host + '\/yanqing\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}},\n {title: \"最新更新\", url: host + '\/zuixin\/{{page == 1 ? \"\" : page + \".html\"}}', style: {layout_flexGrow: 1, layout_flexBasisPercent: 0.25}}\n];\nJSON.stringify(cats);\n<\/js>",
"header": "{\"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\"}",
"jsLib": "var hosts = [\n \"https:\/\/www.suduguu.com\",\n \"https:\/\/shudugu.org\",\n \"https:\/\/sudugu520.com\"\n];\n\nfunction getHosts() {\n return hosts;\n}\n\nfunction getServerHost() {\n var source = this.source;\n try {\n var config = JSON.parse(source.getVariable());\n if (config && config[0] && config[0].host) {\n return config[0].host;\n }\n return getHosts()[0];\n } catch (e) {\n return getHosts()[0];\n }\n}\n\nfunction getConfig() {\n var source = this.source;\n try {\n var configStr = source.getVariable();\n if (!configStr || configStr.trim() === \"\") {\n return { host: getHosts()[0] };\n }\n var config = JSON.parse(configStr);\n if (!config || !config.join || config.length === 0) {\n return { host: getHosts()[0] };\n }\n return config[0] || { host: getHosts()[0] };\n } catch (e) {\n return { host: getHosts()[0] };\n }\n}\n\nfunction setConfig(key, value) {\n var source = this.source;\n try {\n var config = getConfig.call(this);\n config[key] = value;\n source.setVariable(JSON.stringify([config]));\n return true;\n } catch (e) {\n return false;\n }\n}\n\nfunction setConfigs(obj) {\n var source = this.source;\n try {\n var config = getConfig.call(this);\n for (var k in obj) {\n if (obj.hasOwnProperty(k)) {\n config[k] = obj[k];\n }\n }\n source.setVariable(JSON.stringify([config]));\n return true;\n } catch (e) {\n return false;\n }\n}\n\nfunction checkConnectivity(host) {\n var timeout = 5000;\n var socket = null;\n try {\n var start = new Date().getTime();\n var jUrl = new Packages.java.net.URL(host);\n var hostname = jUrl.getHost();\n var port = jUrl.getPort();\n if (port === -1) { port = jUrl.getDefaultPort(); }\n socket = new Packages.java.net.Socket();\n var addr = new Packages.java.net.InetSocketAddress(hostname, port);\n socket.connect(addr, timeout);\n var latency = new Date().getTime() - start;\n return {ok: true, latency: latency};\n } catch (e) {\n return {ok: false, latency: -1, err: String(e)};\n } finally {\n try { if (socket !== null) { socket.close(); } } catch (e2) {}\n }\n}\n\nfunction autoSelectHost() {\n var allHosts = getHosts();\n var details = [];\n var best = null;\n var bestLatency = -1;\n for (var i = 0; i < allHosts.length; i++) {\n var r = checkConnectivity.call(this, allHosts[i]);\n r.host = allHosts[i];\n details.push(r);\n if (r.ok && (bestLatency < 0 || r.latency < bestLatency)) {\n best = allHosts[i];\n bestLatency = r.latency;\n }\n }\n if (best !== null) {\n setConfig.call(this, 'host', best);\n }\n return {success: best !== null, host: best, details: details};\n}",
"lastUpdateTime": "1791350241890",
"loginUi": "[{\"name\": \"⚡ 智能换源\", \"type\": \"button\", \"action\": \"smartswitch()\", \"style\": {\"layout_flexGrow\": 1, \"layout_flexBasisPercent\": 1.0}}, {\"name\": \"🔄 切换域名\", \"type\": \"button\", \"action\": \"sethost()\", \"style\": {\"layout_flexGrow\": 1, \"layout_flexBasisPercent\": 0.5}}, {\"name\": \"🔍 自动选可用\", \"type\": \"button\", \"action\": \"autohost()\", \"style\": {\"layout_flexGrow\": 1, \"layout_flexBasisPercent\": 0.5}}, {\"name\": \"📋 当前域名\", \"type\": \"button\", \"action\": \"checkhost()\", \"style\": {\"layout_flexGrow\": 1, \"layout_flexBasisPercent\": 0.5}}, {\"name\": \"📶 域名延迟\", \"type\": \"button\", \"action\": \"pinghost()\", \"style\": {\"layout_flexGrow\": 1, \"layout_flexBasisPercent\": 0.5}}]",
"loginUrl": "this.sethost = function() {\n try {\n var currentHost = getConfig.call(this).host || getHosts()[0];\n var currentIndex = getHosts().indexOf(currentHost);\n var newIndex = (currentIndex + 1) % getHosts().length;\n var newHost = getHosts()[newIndex];\n setConfig.call(this, 'host', newHost);\n java.toast(\"\\n已切换到:\\n\" + newHost + \"\\n刷新发现页生效\");\n } catch(e) {\n setConfig.call(this, 'host', getHosts()[0]);\n java.toast(\"\\n已初始化:\" + getHosts()[0]);\n }\n};\n\nthis.checkhost = function() {\n try {\n var currentHost = getServerHost();\n java.toast(\"\\n当前服务器:\\n\" + currentHost);\n } catch(e) {\n java.toast(\"获取失败\");\n }\n};\n\nthis.autohost = function() {\n try {\n java.toast(\"\\n正在检测,请稍候...\");\n var result = autoSelectHost.call(this);\n var msg = \"\";\n for (var i = 0; i < result.details.length; i++) {\n var d = result.details[i];\n var shortName = d.host.replace(\"https:\/\/\",\"\").replace(\"http:\/\/\",\"\");\n if (d.ok) {\n msg += \"\\n✓ \" + shortName + \" \" + d.latency + \"ms\";\n } else {\n msg += \"\\n✗ \" + shortName + \" 不可达\";\n }\n }\n if (result.success) {\n msg += \"\\n\\n已选中:\" + result.host.replace(\"https:\/\/\",\"\");\n } else {\n msg += \"\\n\\n全部不可达\";\n }\n java.toast(msg);\n } catch(e) {\n java.toast(\"检测异常:\" + String(e));\n }\n};\n\nthis.pinghost = function() {\n try {\n var currentHost = getServerHost();\n var r = checkConnectivity.call(this, currentHost);\n var shortName = currentHost.replace(\"https:\/\/\",\"\").replace(\"http:\/\/\",\"\");\n if (r.ok) {\n java.toast(\"\\n当前域名:\\n\" + shortName + \"\\n延迟:\" + r.latency + \"ms\");\n } else {\n java.toast(\"\\n当前域名:\\n\" + shortName + \"\\n连接失败\");\n }\n } catch(e) {\n java.toast(\"检测异常:\" + String(e));\n }\n};\n\nthis.smartswitch = function() {\n try {\n var current = getServerHost();\n var shortCurrent = current.replace(\"https:\/\/\",\"\").replace(\"http:\/\/\",\"\");\n var r = checkConnectivity.call(this, current);\n if (r.ok) {\n java.toast(\"\\n✓ 当前域名正常\\n\" + shortCurrent + \"\\n延迟:\" + r.latency + \"ms\\n无需切换\");\n return;\n }\n java.toast(\"\\n✗ 当前域名不可达\\n\" + shortCurrent + \"\\n正在自动选可用...\");\n var result = autoSelectHost.call(this);\n if (result.success) {\n var msg = \"\\n已自动切换到:\\n\" + result.host.replace(\"https:\/\/\",\"\").replace(\"http:\/\/\",\"\");\n for (var i = 0; i < result.details.length; i++) {\n var d = result.details[i];\n if (d.ok) {\n msg += \"\\n \" + d.host.replace(\"https:\/\/\",\"\").replace(\"http:\/\/\",\"\") + \" \" + d.latency + \"ms\";\n }\n }\n msg += \"\\n\\n请返回书架重进章节\";\n java.toast(msg);\n } else {\n java.toast(\"\\n全部域名不可达\\n请检查网络或稍后重试\");\n }\n } catch(e) {\n java.toast(\"智能换源异常:\" + String(e));\n }\n};",
"respondTime": 180000,
"ruleBookInfo": {
"author": "@css:.itemtxt p:eq(1) a@text##作者:",
"coverUrl": "@css:.item a img@src",
"intro": "class.des.0@text",
"kind": "@css:.itemtxt p:eq(0) span:eq(1)@text",
"lastChapter": "@css:.itemtxt ul li:eq(0) a@text",
"name": "@css:.itemtxt h1 a@text",
"wordCount": "@css:.itemtxt h1 i@text"
},
"ruleContent": {
"content": "@js:\nvar base = String(baseUrl);\nvar hostM = base.match(\/^https?:\\\/\\\/[^\\\/]+\/);\nvar host = hostM ? hostM[0] : '';\nvar h = String(result);\nvar bidM = h.match(\/BookID\\s*=\\s*\"(\\d+)\"\/);\nvar aidM = h.match(\/ArticleID\\s*=\\s*\"(\\d+)\"\/);\nvar bid = bidM ? bidM[1] : '';\nvar aid = aidM ? aidM[1] : '';\nfunction extractP(text) {\n var out = '';\n var pm = text.match(\/<p>[\\s\\S]*?<\\\/p>\/g);\n if (!pm || pm.length === 0) {\n var dm = text.match(\/document\\.write\\((['\"])([\\s\\S]*?)\\1\\)\/);\n if (dm) {\n pm = dm[2].match(\/<p>[\\s\\S]*?<\\\/p>\/g);\n }\n }\n if (!pm) return '';\n for (var i = 0; i < pm.length; i++) {\n var t = pm[i].replace(\/<[^>]+>\/g, '').replace(\/ \/g, ' ').trim();\n if (t) out += t + '\\n';\n }\n return out;\n}\nvar allContent = '';\ntry {\n var ps = org.jsoup.Jsoup.parse(h).select('.con p');\n for (var i = 0; i < ps.size(); i++) {\n var t = ps.get(i).text().trim();\n if (t) allContent += t + '\\n';\n }\n} catch (e1) { }\nif (bid && aid) {\n for (var p = 2; p <= 15; p++) {\n try {\n var url = host + '\/i\/a.aspx?id=' + aid + '&p=' + p + '&bid=' + bid;\n var opts = {\n headers: {\n 'Referer': base,\n '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'\n }\n };\n var resp = String(java.ajax(url + ',' + JSON.stringify(opts), 15000));\n var got = extractP(resp);\n if (!got) break;\n allContent += got;\n } catch(e2) {\n break;\n }\n }\n}\nallContent.replace(\/\\n+$\/, '\\n');"
},
"ruleExplore": {
"author": "@css:.itemtxt p:eq(1) a@text##作者:",
"bookList": "@css:.item",
"bookUrl": "@css:.itemtxt h3 a@href",
"coverUrl": "@css:.item a img@src",
"kind": "p@span@text",
"lastChapter": "@css:.itemtxt ul li:eq(0) a@text",
"name": "@css:.itemtxt h3 a@text"
},
"ruleSearch": {
"author": "@css:.itemtxt p:eq(1) a@text##作者:",
"bookList": "@css:.item",
"bookUrl": "@css:.itemtxt h3 a@href",
"checkKeyWord": "没钱修什么仙",
"coverUrl": "@css:.item a img@src",
"kind": "p@span@text",
"lastChapter": "@css:.itemtxt ul li:eq(0) a@text",
"name": "@css:.itemtxt h3 a@text"
},
"ruleToc": {
"chapterList": "@css:#list ul li",
"chapterName": "@css:a@text",
"chapterUrl": "@css:a@href",
"nextTocUrl": "@css:#pages a.gr@href"
},
"searchUrl": "<js>\nresult = getServerHost() + \"\/i\/sor.aspx?key=\" + encodeURIComponent(key);\n<\/js>",
"weight": 0
}