✿少年梦(知秋)✿
少年梦#知秋
zhiqiu123789 (15290)10/26 08:51
反馈群:766236637\ntg群:https://t.me/+dcNnFFZv5KtmYjIx 具体有问题请加反馈,别的请看源注释
{
"bookSourceComment": "版本:20261026\n作者:知秋\n反馈群:766236637\ntg群:https:\/\/t.me\/+dcNnFFZv5KtmYjIx\n注意:快速下载建议在登录界面的全本下载先进行缓存\n1.请登录自己号看自己订阅的书籍\n2. 内置了一个号,部分资源免费阅读,但是不支持下载,只支持在线观看\n4. 登录账密请不要多次输入错误,会出现验证码,遇到这种情况等待一会重新登录\n介绍:\n1. 使用服务器进行中转,有请求速率限制,小说为一秒3次。\n2. 临时token口令为 天一团队是倒狗(qq为1070240776和845646066和1484608559)请勿相信任何需要付费的说法欢迎来官方反馈群举报\n3. 获取token请点击登录界面,获取token按钮,点击测试\/修改token可查询日下载量,切记获取token后请保存,最后选择√存储成功,token为3日有效期,到期请重新获取,切记token变为明文,请勿外泄,异地登录多次会封禁token,如封禁请等过期重新获取。(token改为明文存源变量中防止丢失)\n4. 共享数据库如有,则优先使用数据库,共享章节开头的图标为🍅\n5. 章节目录前有图标🎉,即为共享章节\n6. 支持下载,请把预下载改成0-3之间,请求有超限拉黑,请勿大规模批量下载\n7. 支持订阅接口,但是不要重复点击\n8. 反馈q群:755947375,token问题群里找我,或者社区找也行(社区不经常在线,上线看到会回)\n9. 接口请求速率存在限制,请不要大规模下载,耐心等待。",
"bookSourceGroup": "少年梦,api,优质,禁止外传",
"bookSourceName": "✿少年梦(知秋)✿",
"bookSourceType": 0,
"bookSourceUrl": "少年梦#知秋",
"concurrentRate": "1000",
"customButton": false,
"customOrder": -1,
"enabled": true,
"enabledCookieJar": true,
"enabledExplore": true,
"eventListener": false,
"exploreUrl": "@js:\nlet token = String(source.getVariable())\nif (token == '') {\n java.longToast('\\n❌未获取共享Token,请于登录界面获取共享Token后使用')\n}\nlet data = requestApiUrl('\/novel\/explore\/init', {})\n\/\/小说·共享更新时间::@js:getApiUrl('\/novel\/novels', {page})\n\/\/我的书架::@js:getApiUrl('\/console\/bookrack', {page})\nJSON.stringify(data)",
"jsLib": "const host = '少年梦'\nconst branch = 'temp'\nconst version = '1.0.0'\nconst api = 'https:\/\/snd.vv9v.cn'\nconst apiAdmin = 'https:\/\/zqmy.vv9v.cn'\n\nfunction releasePage() {\n this.java.startBrowser(`${apiAdmin}\/source\/release\/?host=${host}&branch=${branch}&version=${version}&lastUpdateTime=${this.source.lastUpdateTime}`, '发布页')\n}\n\nfunction checkUpdate() {\n let lastCheckUpdateTime = Number(this.source.get('lastCheckUpdateTime')) || 0\n let now = Date.now()\n if (now - lastCheckUpdateTime < 12 * 3600 * 1000) return\n this.source.put('lastCheckUpdateTime', String(now))\n let data = requestApiUrl.call(this, '\/source\/sources', { host, branch, version }, apiAdmin)\n if (!data) return\n if (data.history[0].version != version) {\n releasePage.call(this)\n }\n}\n\nfunction getApiUrl(path, data, host = api) {\n const { source } = this\n data = Object.entries(data).map(v => v.join('=')).join('&')\n const option = {\n method: \"GET\",\n headers: {\n 'authorization': `Bearer ${source.getVariable()}`\n }\n }\n const url = host + path + '?' + data + ',' + JSON.stringify(option)\n return url\n}\n\nfunction requestApiUrl(path, data, host = api) {\n const url = getApiUrl.call(this, path, data, host)\n try {\n let res = this.java.ajax(url)\n res = JSON.parse(res)\n if (res.code != 0) {\n this.java.longToast(`\\n❌操作失败,code${res.code}:\\n${res.msg}`)\n } else {\n return res.data\n }\n } catch (e) {\n this.java.log(`请求共享接口${path}异常:` + e.message)\n }\n return null\n}\n\nfunction getCNTimeString(time, format = 'YYYY\/MM\/DD HH:mm:ss') {\n const date = time ? new Date(time) : new Date()\n const year = date.getFullYear()\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n const seconds = String(date.getSeconds()).padStart(2, '0')\n return format.replace('YYYY', String(year))\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hours)\n .replace('mm', minutes)\n .replace('ss', seconds)\n}",
"lastUpdateTime": "1792975903295",
"loginUi": "[\n {\n \"name\": \"源作者\",\n \"type\": \"text\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"官方反馈群\",\n \"type\": \"text\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"临时Token口令\",\n \"type\": \"text\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"查询Token\",\n \"type\": \"button\",\n \"action\": \"queryToken()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.4\n }\n },\n {\n \"name\": \"获取Token\",\n \"type\": \"button\",\n \"action\": \"getTempToken()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.4\n }\n },\n {\n \"name\": \"检查更新\",\n \"type\": \"button\",\n \"action\": \"releasePage()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.4\n }\n },\n {\n \"name\": \"数据库统计\",\n \"type\": \"button\",\n \"action\": \"showDb()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.4\n }\n },\n {\n \"name\": \"账号\",\n \"type\": \"text\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"密码\",\n \"type\": \"password\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"登录\",\n \"type\": \"button\",\n \"action\": \"_login()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"name\": \"退出登录\",\n \"type\": \"button\",\n \"action\": \"logout()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"name\": \"账号信息\",\n \"type\": \"button\",\n \"action\": \"showUserInfo()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 0.27\n }\n },\n {\n \"name\": \"开关自动订阅未购章节\",\n \"type\": \"button\",\n \"action\": \"toggleAutoBuy()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"书籍ID\",\n \"type\": \"text\"\n },\n {\n \"name\": \"全本后台下载\",\n \"type\": \"button\",\n \"action\": \"downloadNovel()\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"🛒购买全本🛒\",\n \"type\": \"button\",\n \"action\": \"buy(true)\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"购买数量\",\n \"type\": \"text\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n },\n {\n \"name\": \"🛒购买指定数量章节(默认5)🛒\",\n \"type\": \"button\",\n \"action\": \"buy(false)\",\n \"style\": {\n \"layout_flexGrow\": 1,\n \"layout_flexBasisPercent\": 1\n }\n }\n]",
"loginUrl": "function login() {\n let info = JSON.parse(String(source.getLoginInfo()))\n _login(info)\n}\n\nfunction _login(info) {\n info = info || result\n let username = info['账号']\n let password = info['密码']\n if (username == '' || password == '') {\n return java.longToast('\\n❌登录失败,用户名或密码不能为空')\n }\n let data = requestApiUrl('\/console\/login', { username, password })\n if (!data || !data.id) return\n source.putLoginInfo(JSON.stringify(info))\n showUserInfo()\n}\n\nfunction logout() {\n let data = requestApiUrl('\/console\/logout', {})\n if (!data || !data.msg) return\n let { msg } = data\n java.longToast(`\\n✅${msg}`)\n}\n\nfunction showUserInfo() {\n let data = requestApiUrl('\/console\/info', {})\n if (!data || !data.msg) return\n let { msg } = data\n java.longToast(`\\n✅${msg}`)\n}\n\nfunction toggleAutoBuy() {\n let auto = source.get('autoBuy') == '1'\n source.put('autoBuy', auto ? '0' : '1')\n java.longToast(`\\n✅自动订阅未购章节已${auto ? '关闭' : '开启\\n阅读时将自动订阅未购买章节'}`)\n}\n\nfunction queryToken() {\n let token = String(source.getVariable())\n if (token.length <= 60) {\n java.toast('请输入有效token')\n } else {\n let info = requestApiUrl('\/user\/test', { token })\n if (!info) return\n java.longToast(`\\n✅查询成功\\n用户:${info.id}${info.max ? `\\n日下载上限:${info.max}` : ''}\\n今日已下载:${info.used}\\n日下载剩余:${info.left}\\n创建时间:${info.createTime}${info.ddl ? `\\n到期时间:${info.ddlTime}` : ''}`)\n }\n}\n\nfunction getTempToken() {\n let pw1 = String(result['源作者'])\n if (pw1 == '') {\n return java.longToast('请输入源作者')\n }\n let pw2 = String(result['官方反馈群'])\n if (pw2 == '') {\n return java.longToast('请输入官方反馈群')\n }\n let pw3 = String(result['临时Token口令'])\n if (pw3 == '') {\n return java.longToast('请输入临时Token口令')\n }\n let info = requestApiUrl('\/user\/temp', { id: java.androidId(), pw1, pw2, pw3 })\n if (!info) return\n let token = info.token\n source.setVariable(token)\n java.longToast(`\\n✅获取临时token成功\\n用户:${info.id}\\n日下载剩余:${info.left}\\n创建时间:${info.createTime}\\n到期时间:${info.ddlTime}`)\n source.putLoginInfo(JSON.stringify(result))\n}\n\nfunction showDb() {\n let data = requestApiUrl('\/system\/dbinfo', {})\n if (!data) return\n let { msg } = data\n java.longToast(`\\n✅${msg}`)\n}\n\nfunction downloadNovel() {\n let novelId = +String(result['书籍ID'])\n if (!novelId) {\n return java.longToast('\\n❌请输入有效书籍ID')\n }\n let data = requestApiUrl('\/novel\/download', { novelId })\n if (!data) return\n let { msg } = data\n java.longToast(`\\n✅${msg}`)\n}\n\nfunction buy(all) {\n let novelId = +String(result['书籍ID'])\n if (!novelId) {\n return java.longToast('\\n❌请输入有效书籍ID')\n }\n let data\n if (all) {\n data = requestApiUrl('\/console\/subscribe', { novelId, num: -1 })\n } else {\n let num = +String(result['购买数量'])\n if (!num || num <= 0) {\n num = 5\n }\n data = requestApiUrl('\/console\/subscribe', { novelId, num })\n }\n if (!data) return\n java.longToast('\\n✅' + data.msg)\n}",
"respondTime": 180000,
"ruleBookInfo": {
"author": "penName",
"coverUrl": "https:\/\/aliossouterendtest.shaoniandream.com{{$.picture}}",
"init": "data",
"intro": " {{$.jianjie}}",
"kind": "{{java.getString('$.isUpdate') == '0' ? '完本' : '连载'}}\n{{java.getString('$.sortName')}}\n{{java.getString('$.booklabel')}}",
"lastChapter": "ChapterName\n@js:\nif (result != '') {\n result = String(result).replace('连载至', '')\n}\nresult",
"name": "title",
"tocUrl": "id||BookID\n@js:\n`data:;base64,${java.base64Encode(result)},{\"type\":\"SNDapi\"}`",
"wordCount": "FontCount"
},
"ruleContent": {
"content": "@js:\ncheckUpdate()\nlet chapId = java.hexDecodeToString(result)\nlet info = JSON.parse(baseUrl.slice(baseUrl.indexOf('{')))\nlet novelId = info.novelId\nlet autoBuy = source.get('autoBuy') == '1'\nlet data = requestApiUrl('\/novel\/chap', { novelId, chapId, autoBuy })\ndata.content\n",
"payAction": "\/\/ java.log('章节url:' + chapter.url)\nlet novelId = chapter.url.match(\/\"novelId\":\\s*\"(\\d+)\"\/)[1]\nlet chapId = java.base64Decode(chapter.url.match(\/base64,(.*?),\/)[1])\nlet data = requestApiUrl('\/console\/subscribe', { novelId, chapId })\nif (data.msg) {\n java.longToast('\\n✅' + data.msg)\n true\n} else {\n false\n}"
},
"ruleExplore": {},
"ruleSearch": {
"author": "penName",
"bookList": "data[*]",
"bookUrl": "BookID||BooksID||id\n@js:\ngetApiUrl('\/novel\/info', { novelId: result })",
"checkKeyWord": "",
"coverUrl": "https:\/\/aliossouterendtest.shaoniandream.com{{$.picture}}",
"intro": "jianjie",
"kind": "{{java.getString('$.isUpdate') == '0' ? '完本' : '连载'}}\n{{java.getString('$.cname')}}\n{{java.getString('$.sortName')}}\n{{java.getString('$.booklabel')}}",
"name": "title||BookName",
"wordCount": "FontCount"
},
"ruleToc": {
"chapterList": "@js:\nlet novelId = java.hexDecodeToString(result)\nlet vols = requestApiUrl('\/novel\/catalog', { novelId })\n\nlet cache = requestApiUrl('\/novel\/cache', { novelId }) || []\ncache = cache.reduce((acc, d) => {\n acc[d.chapId] = d\n return acc\n}, {})\n\nlet loginInfo = JSON.parse(source.getLoginInfo() || '{}')\nloginInfo.书籍ID = novelId\nsource.putLoginInfo(JSON.stringify(loginInfo))\n\nlet chaps = []\n\nfor (let v of vols) {\n chaps.push({\n title: v.title,\n voltype: true\n })\n for (let c of v.chapterList) {\n let cacheChap = cache[c.id]\n let isShare = !!cacheChap\n let isBuy = c.lock == 1\n let isVip = !!c.isFree\n let tag = isBuy ? '🔑' : isShare ? cacheChap.s ? '🍎' : '🎉' : ''\n if (tag) tag += ' '\n let onlineTime = (cacheChap ? cacheChap.onlineTime : getCNTimeString(c.release_time_now * 1000)) || getCNTimeString(c.release_time_now * 1000) || ''\n let info = `${onlineTime} ┃ 字数:${c.FontCount || 0}`\n chaps.push({\n title: (isVip ? tag : '') + c.title,\n info: info + (isShare ? (cacheChap.s ? '🍎' : '🎉') : tag),\n isVip,\n isBuy: isBuy || (cacheChap && cacheChap.s),\n url: `data:;base64,${java.base64Encode(c.id)},{\"type\":\"SNDapi\",\"novelId\":\"${novelId}\"}`\n })\n }\n}\n\nchaps",
"chapterName": "title",
"chapterUrl": "url",
"isPay": "isBuy",
"isVip": "isVip",
"isVolume": "voltype",
"updateTime": "info"
},
"searchUrl": "@js:\ngetApiUrl('\/novel\/search', { keyword: key, page })",
"weight": 0
}