魔丸小说
https://www.mowan.lol
huang-shihan (1643)09/26 00:44
老是报错,deepseek大法了一下,发现页在3.23.110211版还是有问题,不过其它的能正常使用了
{
"bookSourceComment": "番茄小说,七猫小说,塔读小说,书旗小说,起点小说,所有来源均支持段评,本章说\n\ntg群:https:\/\/t.me\/mowanxiaoshuo",
"bookSourceGroup": "番茄,个人",
"bookSourceName": "魔丸小说",
"bookSourceType": 0,
"bookSourceUrl": "https:\/\/www.mowan.lol",
"customOrder": 83,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": true,
"exploreUrl": "<js>\nfunction styles(so) {\n var today = new Date();\n var dateT = today.getFullYear()\n + '-'\n + (today.getMonth() + 1)\n + '-'\n + today.getDate()\n + '_discover_tabs';\n\n var url = Api('\/api\/discover\/tabs');\n var res = null;\n var cacheData = '';\n var sourceItem = null;\n var result = [];\n var tab;\n var count = 0;\n var i;\n var u;\n\n try {\n cacheData = cache.get(dateT)+\"1\";\n\n if (cacheData) {\n try {\n res = JSON.parse(cacheData);\n } catch (e) {\n res = null;\n }\n }\n\n if (!res) {\n res = JSON.parse(java.ajax(url));\n\n if (res && res.code == 0) {\n cache.put(dateT, JSON.stringify(res));\n }\n }\n } catch (e) {\n return [{\n title: '数据加载失败,请刷新后重试',\n url: '',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 1\n }\n }];\n }\n\n if (!res || res.code != 0 || !res.data || !res.data.sources) {\n return [{\n title: '请先登陆,登陆后刷新发现页即可',\n url: '',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 1\n }\n }];\n }\n\n for (i = 0; i < res.data.sources.length; i++) {\n if (res.data.sources[i] && res.data.sources[i].name == so) {\n sourceItem = res.data.sources[i];\n break;\n }\n }\n\n if (!sourceItem || !sourceItem.tabs || sourceItem.tabs.length == 0) {\n return [{\n title: '暂无' + (so || '') + '发现内容',\n url: '',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 1\n }\n }];\n }\n\n for (i = 0; i < sourceItem.tabs.length; i++) {\n tab = sourceItem.tabs[i];\n\n if (!tab) {\n continue;\n }\n\n if (tab.section) {\n if (count > 0) {\n while (count < 3) {\n result.push({\n title: '--',\n url: '',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 0.25\n }\n });\n count++;\n }\n }\n\n result.push({\n title: tab.title || '',\n url: '',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 1\n }\n });\n\n count = 0;\n continue;\n }\n\n u = '\/api\/discover\/content?source='\n + encodeURIComponent(sourceItem.source || '')\n + '&tab='\n + encodeURIComponent(tab.key || '')\n + '&page={{page}}&page_size=12';\n\n result.push({\n title: tab.title || '',\n url: Api(u),\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 0.25\n }\n });\n\n count++;\n\n if (count >= 3) {\n count = 0;\n }\n }\n\n if (count > 0) {\n while (count < 3) {\n result.push({\n title: '--',\n url: '',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: 0.25\n }\n });\n\n count++;\n }\n }\n\n return result;\n}\n\nvar so = cache.get('sources') || '起点小说';\n\nvar s = [\n create(\n \"请选择平台\",\n [\"番茄小说\", \"七猫小说\", \"书旗小说\", \"塔读小说\",\"红烛故事\",\"西瓜小说\",\"轻小说\",\"星星短剧\",\"依依短剧\",\"起点小说\"],\n so,\n \"sources\",\n 1\n )\n];\n\n\n\nJSON.stringify(s.concat(styles(so)), null, 2);\n<\/js>",
"jsLib": "var mw = \"https:\/\/www.mowan.lol\";\n\nfunction getCookie(k) {\n var java = this.java;\n var cookie = this.cookie;\n var cookieValue = String(cookie.getCookie(mw)) || String(java.getCookie(mw));\n var parts = cookieValue.split(\";\");\n for (var i = 0; i < parts.length; i++) {\n var part = parts[i].trim();\n var idx = part.indexOf(k + \"=\");\n if (idx === 0) {\n return part.substring(k.length + 1);\n }\n }\n return \"\";\n}\n\nfunction Api(url, method) {\n method = method || 'GET';\n var java = this.java;\n var XDeviceID = this.getCookie('X-Device-ID');\n var Authorization = this.getCookie('Authorization');\n if (typeof Authorization === 'string') {\n Authorization = Authorization.replace(\"%20\", \" \");\n } else {\n Authorization = String(Authorization).replace(\"%20\", \" \");\n }\n var options = {\n method: method,\n headers: JSON.stringify({\n 'Authorization': Authorization,\n 'X-Device-ID': XDeviceID,\n 'Content-Type': 'application\/json',\n 'User-Agent': 'yuedu_app',\n 'Referer': mw\n })\n };\n return mw + url + ',' + JSON.stringify(options);\n}\n\nfunction showPara(url) {\n var java = this.java;\n var cache = this.cache;\n var date = new Date().toLocaleDateString();\n var cacheKey = date + \"dp\";\n var htmlContent = cache.get(cacheKey);\n if (!htmlContent || String(htmlContent).indexOf(\"id=\") === -1) {\n htmlContent = java.ajax(url);\n cache.put(cacheKey, htmlContent);\n }\n var browserConfig = {\n \"expandedCornersRadius\": 20,\n \"dismissOnTouchOutside\": true,\n \"isDraggable\": true,\n \"shouldDimBackground\": true,\n \"backgroundDimAmount\": 0.5,\n \"hardwareAccelerated\": true,\n \"isNestedScrollingEnabled\": true,\n \"isGestureInsetBottomIgnored\": true,\n \"setFitToContents\": true,\n \"isHideable\": true,\n \"heightPercentage\": 0.8\n };\n java.showBrowser(url, htmlContent, \"window.java=java;\", JSON.stringify(browserConfig));\n}\n\nfunction createBubble(number, url, bubble) {\n var num = number > 99 ? \"99+\" : number.toString();\n bubble = bubble.replace('$num', num);\n var encodedBubble = this.java.base64Encode(bubble);\n encodedBubble = 'data:image\/svg+xml;base64,' + encodedBubble + ',{\"click\":\"showPara(\\'' + (mw + url) + '\\' )\",\"style\":\"text\"}';\n return '<img src=\"' + encodedBubble + '\">';\n}\n\nfunction showChapter(url) {\n var java = this.java;\n var cache = this.cache;\n var date = new Date().toLocaleDateString();\n var cacheKey = date + \"end\";\n var htmlContent = cache.get(cacheKey);\n if (!htmlContent || String(htmlContent).indexOf(\"id=\") === -1) {\n htmlContent = java.ajax(url);\n cache.put(cacheKey, htmlContent);\n }\n var browserConfig = {\n \"expandedCornersRadius\": 20,\n \"dismissOnTouchOutside\": true,\n \"isDraggable\": true,\n \"shouldDimBackground\": true,\n \"backgroundDimAmount\": 0.5,\n \"hardwareAccelerated\": true,\n \"isNestedScrollingEnabled\": true,\n \"isGestureInsetBottomIgnored\": true,\n \"setFitToContents\": true,\n \"isHideable\": true,\n \"heightPercentage\": 0.8\n };\n java.showBrowser(url, htmlContent, \"window.java=java;\", JSON.stringify(browserConfig));\n}\n\nfunction createChapter(url, svg) {\n var encodedSvg = this.java.base64Encode(svg);\n encodedSvg = 'data:image\/svg+xml;base64,' + encodedSvg + ',{\"click\":\"showChapter(\\'' + (mw + url) + '\\' )\",\"style\":\"FULL\"}';\n return '<img src=\"' + encodedSvg + '\">';\n}\n\nfunction show(k, v) {\n var java = this.java;\n var cache = this.cache;\n cache.put(v, k);\n java.refreshExplore();\n}\n\nfunction create(k, chars, defaultV, v, size) {\n return {\n title: k,\n type: \"select\",\n chars: chars,\n default: defaultV,\n action: 'show(infoMap[\\'' + k + '\\'],\\'' + v + '\\')',\n style: {\n layout_flexGrow: 1,\n layout_flexBasisPercent: size\n }\n };\n}\n\nfunction formatDate(input, fmt) {\n if (fmt === undefined) fmt = 'YYYY-MM-DD HH:mm:ss';\n var date = (input instanceof Date) ? input : new Date(input);\n if (isNaN(date.getTime())) return '';\n\n function pad(n) {\n var s = String(n);\n return s.length < 2 ? '0' + s : s;\n }\n\n var map = {\n YYYY: date.getFullYear(),\n MM: pad(date.getMonth() + 1),\n DD: pad(date.getDate()),\n HH: pad(date.getHours()),\n mm: pad(date.getMinutes()),\n ss: pad(date.getSeconds())\n };\n\n return fmt.replace(\/YYYY|MM|DD|HH|mm|ss\/g, function(m) {\n return map[m];\n });\n}\n\nfunction Env() {\n var java = this.java;\n var source = this.source;\n try {\n java.qread();\n return 4;\n } catch (e) {}\n try {\n if (typeof java.reLoginView === 'function') return 1;\n new Packages.io.legato.kazusa.utils.TimeoutCancellationException('');\n return 1;\n } catch (e) {}\n try {\n java.deviceID();\n return 3;\n } catch (e) {}\n if (typeof source.loginUi === 'function') return 2;\n return 1;\n}\n\nfunction Content(res) {\n var evn = this.Env();\n var content = \"\";\n var text = res.data.paragraphs;\n if (!text) {\n return res.data.msg || \"暂无数据,请稍后再试~\";\n }\n var enabledPara = res.data.comment.enabled;\n var bubble = enabledPara ? res.data.comment.bubble.svg : \"\";\n var enabledChapter = res.data.comment.chapter_enabled;\n var chapterSvgs = enabledChapter ? res.data.comment.chapter_card.svg : \"\";\n\n var contents = [];\n for (var i = 0; i < text.length; i++) {\n var item = text[i];\n var html = \"\";\n if (item.comment_count > 0 && enabledPara && bubble != '' && evn == 1) {\n html = '<p>' + item.text + this.createBubble(item.comment_count, item.comment_url, bubble) + '<\/p>';\n } else if (item.comment_count > 0 && enabledPara && bubble != '' && evn == 3) {\n html = '<div rs-native>' + item.text + '<comment count=\"' + item.comment_count + '\" onPress=\"java.showReadingBrowser(\\'' + (mw + item.comment_url) + '\\',\\'段评\\')\"><\/div>';\n } else {\n html = item.text;\n }\n if (item.image) {\n if (typeof item.image === 'string') {\n html += '<img src=\"' + item.image + '\">';\n } else if (Array.isArray(item.image)) {\n for (var j = 0; j < item.image.length; j++) {\n html += '<img src=\"' + item.image[j] + '\">';\n }\n }\n }\n\n contents.push(html);\n }\n\n content = contents.join(\"\\n\");\n\n if (enabledChapter && chapterSvgs != \"\" && evn == 1) {\n var chapterUrl = res.data.comment.chapter_card.url;\n content += '\\n' + this.createChapter(chapterUrl, chapterSvgs);\n } else if (enabledChapter && chapterSvgs != \"\" && evn == 3) {\n var chapterUrl = res.data.comment.chapter_card.url;\n var enChapterSvgs = java.base64Encode(chapterSvgs);\n content += '<div rs-native><img onPress=\"java.showReadingBrowser(\\'' + (mw + chapterUrl) + '\\',\\'本章说\\')\" src=\"data:image\/svg+xml;base64,' + enChapterSvgs + '\"><\/div>';\n }\n\n return content;\n}",
"lastUpdateTime": "1790354671081",
"loginCheckJs": "",
"loginUrl": "https:\/\/www.mowan.lol\/user\/me?app=yuedu&version=26.9.22",
"respondTime": 180000,
"ruleBookInfo": {
"author": "$.data.author",
"init": "<js>\nvar url = java.hexDecodeToString(result);\njava.ajax(Api(url));\n<\/js>",
"intro": "<js>\nresult = JSON.parse(result);\n\nvar typeM = {\n\t\"novel\" : \"小说\",\n\t\"audio\" : \"听书\",\n\t\"image\" : \"漫画\",\n\t\"video\" : \"短剧\"\n\t};\n\nvar bookSource = result.data.source;\nvar latest_chapter = result.data.latest_chapter;\nvar latest_update_time = result.data.latest_update_time;\nvar description = result.data.description;\nvar sourceType = result.data.type;\n\n[\n ' 源站:' + bookSource,\n latest_chapter && ('最新章节:' + latest_chapter),\n latest_update_time && ('更新时间:' + formatDate(latest_update_time)),\n '类型:' + (typeM[sourceType] || '小说'),\n \"\\n\",\n description\n].filter(Boolean).join('\\n')\n<\/js>",
"kind": "{{$.data.category}},{{$.data.status}}",
"name": "$.data.name",
"tocUrl": "\/api\/book\/chapters?source={{$.data.source}}&book_id={{$.data.id}}&type={{$.data.type}}\n<js>\n'data:;base64,' + java.base64Encode(result) + ',{\"type\":\"mw\"}'\n<\/js>"
},
"ruleContent": {
"content": "<js>\nvar url = java.hexDecodeToString(result);\njava.log(url);\nresult = java.ajax(Api(url));\nresult = JSON.parse(result);\n\nvar content;\nvar code = result.code;\nvar msg = result.message;\n\nvar sourceType = url.match(\/type=([^&]+)\/)[1];\n\nif (code != 0) {\n content = msg;\n} else if (sourceType && sourceType==\"novel\") {\n content = Content(result);\n} else {\n\tcontent = result.data.content;\n}\ncontent\n<\/js>"
},
"ruleExplore": {},
"ruleReview": {},
"ruleSearch": {
"author": "author",
"bookList": "<js>\nresult = JSON.parse(result);\nif (result.code!=0) {\n result = {\"data\":{\"items\":[\n {\n \"name\": \"❗❗❗当前未登录状态\",\n \"author\": \"请登录后使用\",\n \"latestChapterTitle\":\"请注册账号并登陆\",\n \"cover\": \"http:\/\/fc3tn.baidu.com\/it\/u=1573211303,3438572022&fm=203&src=787&fc_m=cvican\",\n \"description\":result.message,\n \"id\":\"\",\n \"source\":\"\"\n }\n ]}}\n}\nJSON.stringify(result)\n<\/js>\n$.data.items",
"bookUrl": "\/api\/book\/detail?source={{$.source}}&book_id={{$.id}}\n<js>\n'data:;base64,' + java.base64Encode(result) + ',{\"type\":\"mw\"}'\n<\/js>",
"checkKeyWord": "我的",
"coverUrl": "cover",
"intro": "description",
"kind": "{{$.category}},{{$.status}}",
"lastChapter": "源站:{{$.source}}",
"name": "name"
},
"ruleToc": {
"chapterList": "<js>\nvar url = java.hexDecodeToString(result);\nvar resStr = java.ajax(Api(url));\nvar res = JSON.parse(resStr);\nvar sourceType = url.match(\/type=([^&]+)\/)[1];\njava.put('sourceType',sourceType);\n\nif (res.code != 0) {\n var parts = book.bookUrl.split(',')[1];\n var decodedUrl = java.base64Decode(parts);\n resStr = java.ajax(Api(decodedUrl.replace('book\/detail', 'book\/chapters')));\n}\n\nvar typeMap = {\n \"novel\": {\n ios: 0,\n default: 8\n },\n \"audio\": {\n ios: 1,\n default: 32\n },\n \"image\": {\n ios: 2,\n default: 64\n },\n \"video\": {\n ios: 3,\n default: 4\n }\n};\nvar currentType = typeMap[sourceType] || typeMap[\"novel\"];\nif (Env==3) {\nbook.type = currentType.ios;\n} else {\nbook.type = currentType.default;\n}\n\nresStr;\n<\/js>\n$.data.chapters",
"chapterName": "$.name",
"chapterUrl": "\/api\/chapter\/content?source={{$.source}}&chapter_id={{$.id}}&type={{java.get('sourceType')}}\n<js>\n'data:;base64,' + java.base64Encode(result) + ',{\"type\":\"mw\"}'\n<\/js>",
"updateTime": "$.update_time\n<js>\nformatDate(result)\n<\/js>"
},
"searchUrl": "<js>Api('\/api\/search?keyword=' + key + '&page=' + page + '&page_size=20')<\/js>",
"weight": 0
}