thz-helper

thz论坛 98堂论坛

  1. // ==UserScript==
  2. // @name thz-helper
  3. // @description thz论坛 98堂论坛
  4. // @namespace http://tampermonkey.net/
  5. // @version 1.0.5
  6. // @author paso
  7. // @match http://96thz.cc/*
  8. // @match http://97thz.cc/*
  9. // @match http://98thz.cc/*
  10. // @match http://thzb.cc/*
  11. // @match http://thzv.cc/*
  12. // @match https://wpzo.app/*
  13. // @match *://www.example.net/*
  14. // @require https://greasyfork.org/scripts/473442-cross-origin-storage/code/cross-origin-storage.js?version=1237609
  15. // @require https://greasyfork.org/scripts/473443-popup-inject/code/popup-inject.js?version=1237616
  16. // @grant none
  17. // @license MIT
  18. // ==/UserScript==
  19.  
  20. ;(function () {
  21. 'use strict'
  22. // Your code here...
  23. // http://96thz.cc/forum.php?mod=forumdisplay&fid=181&filter=typeid&typeid=36&orderby=heats&page=2
  24.  
  25. const namespace = 'paso-thz-helper'
  26. const middlewareHost = 'www.example.net'
  27. if (window.location.hostname === middlewareHost) {
  28. window.paso.crossOriginStorage.startStorageServer()
  29. } else {
  30. handleTarget(window.location.protocol + '//' + middlewareHost)
  31. }
  32.  
  33. function handleTarget(server) {
  34. const CONTEXT = { env: 'prod' }
  35. const storage = window.paso.crossOriginStorage.createStorageClient(server)
  36. const querySearch = resolveQuerySearch()
  37. const instance = getInstance({ querySearch })
  38. if (!instance) {
  39. console.error('No instance matched!')
  40. return
  41. }
  42. const storageKey = `${namespace}-${instance.name}`
  43.  
  44. const POPUP_INJECT_CONFIG = {
  45. namespace,
  46. actionName: 'Settings',
  47. collapse: '70%',
  48. location: '35%',
  49. content: `<div id="${namespace}-app"></div>`,
  50. style: `
  51. <style>
  52. .${namespace} * {
  53. font-size: 14px;
  54. color: black;
  55. }
  56. .${namespace} .table {
  57. display: table;
  58. border-collapse: separate;
  59. border-spacing: 4px 4px;
  60. }
  61. .${namespace} .table-row {
  62. display: table-row;
  63. }
  64. .${namespace} .table-cell {
  65. display: table-cell;
  66. }
  67. .${namespace} .text-right {
  68. text-align: right;
  69. }
  70. .${namespace} .flex.gap-8 {
  71. gap: 8px;
  72. }
  73. </style>`
  74. }
  75.  
  76. const VUE_COMPONENT_PARAM_SELECT = {
  77. template: `
  78. <label class="table-row">
  79. <div class="table-cell text-right">{{title}}</div>
  80. <div class="table-cell">
  81. <div class="flex">
  82. <input class="input monospace" v-if="!hideInput" v-model.trim="inputValue" />
  83. <select class="input" v-if="!!options" v-model="inputValue">
  84. <option v-for="o in options" :value="o.value">{{o.label}}</option>
  85. </select>
  86. </div>
  87. </div>
  88. </label>`,
  89. props: ['title', 'value', 'options', 'hideInput'],
  90. emits: ['update:value'],
  91. computed: {
  92. inputValue: {
  93. get() {
  94. return this.$props.value
  95. },
  96. set(v) {
  97. this.$emit('update:value', v)
  98. }
  99. }
  100. }
  101. }
  102.  
  103. const VUE_APP_CONFIG = {
  104. template: `
  105. <div class="flex col gap-8">
  106. <div class="table">
  107. <SelectFormItem title="执行时机" v-model:value="executeSelector" />
  108. <SelectFormItem title="path" v-model:value="path" />
  109. <SelectFormItem title="板块" v-model:value="params.fid" :options="forms.fidOptions" />
  110. <SelectFormItem title="筛选" v-model:value="params.filter" :options="forms.filterOptions" :hideInput="true" />
  111. <SelectFormItem title="系列" v-if="params.filter === 'typeid'" v-model:value="params.typeid" :options="forms.typeidOptions[params.fid]" />
  112. <SelectFormItem title="排序" v-model:value="params.orderby" :options="forms.orderbyOptions" :hideInput="true" />
  113. <SelectFormItem title="搜索" v-model:value="search" />
  114. </div>
  115. <button class="button" @click="apply">应用</button>
  116. </div>`,
  117. components: {
  118. SelectFormItem: VUE_COMPONENT_PARAM_SELECT
  119. },
  120. data() {
  121. return {
  122. ...instance.getDefaultData(),
  123. forms: Object.freeze(instance.getFormsData())
  124. }
  125. },
  126. computed: {},
  127. methods: {
  128. apply() {
  129. storage
  130. .setItem(storageKey, {
  131. executeSelector: this.executeSelector,
  132. path: this.path,
  133. params: {
  134. ...this.params
  135. },
  136. search: this.search
  137. })
  138. .then(() => (window.location = getPageLocation(this.path, this.params, querySearch.page || '1')))
  139. }
  140. },
  141. mounted() {
  142. storage
  143. .getItem(storageKey)
  144. .then((resp) => JSON.parse(resp.data || ''))
  145. .catch(() => instance.getDefaultData())
  146. .then((data) => {
  147. this.executeSelector = data.executeSelector
  148. this.path = data.path
  149. this.params.fid = data.params.fid
  150. this.params.filter = data.params.filter
  151. this.params.typeid = data.params.typeid
  152. this.params.orderby = data.params.orderby
  153. this.search = data.search
  154. })
  155. }
  156. }
  157.  
  158. loadJS('https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/3.2.31/vue.global.prod.min.js')
  159. .then(() => window.paso.injectPopup(POPUP_INJECT_CONFIG))
  160. .then(() => window.Vue.createApp(VUE_APP_CONFIG).mount(`#${namespace}-app`))
  161.  
  162. storage
  163. .getItem(storageKey)
  164. .then((resp) => JSON.parse(resp.data || ''))
  165. .catch(() => instance.getDefaultData())
  166. .then((data) =>
  167. ready(data.executeSelector)
  168. .then(() => handlePageContent(data))
  169. .catch((e) => {
  170. console.warn(e)
  171. })
  172. )
  173.  
  174. function handlePageContent(data) {
  175. const pageMode = instance.getPageMode()
  176. // 隐藏广告
  177. instance.getNeedToHideElements(pageMode)?.forEach((el) => {
  178. el.setAttribute('style', 'display: none !important;')
  179. })
  180.  
  181. switch (pageMode) {
  182. case 'forumdisplay':
  183. instance.handlePostList(data)
  184. break
  185. case 'viewthread':
  186. instance.handlePostContent()
  187. break
  188. }
  189. }
  190.  
  191. if (CONTEXT.env === 'dev') {
  192. window._$_getCategory = function () {
  193. const arr = []
  194. document.querySelectorAll('.bm_c .fl_g dt a')?.forEach((a) => {
  195. const item = {}
  196. if (a.firstChild && a.firstChild instanceof Text) {
  197. item.label = a.firstChild.wholeText
  198. }
  199. if (a.href) {
  200. item.value = getStartInt(a.href)
  201. }
  202. arr.push(item)
  203. })
  204. console.log(arr)
  205. console.log(JSON.stringify(arr))
  206. }
  207. window._$_getTypes = function () {
  208. const arr = []
  209. document.querySelectorAll('ul#thread_types > li > a')?.forEach((a) => {
  210. const item = { value: '' }
  211. if (a.firstChild && a.firstChild instanceof Text) {
  212. item.label = a.firstChild.wholeText
  213. }
  214. if (a.href) {
  215. const i = a.href.indexOf('?')
  216. if (i >= 0) {
  217. const qs = resolveQuerySearch(a.href.substring(i))
  218. item.value = qs.typeid || ''
  219. }
  220. }
  221. arr.push(item)
  222. })
  223. if (!arr.length) arr.push({ value: '', label: '全部' })
  224. console.log(arr)
  225. console.log(JSON.stringify(arr))
  226. }
  227. }
  228. }
  229.  
  230. function resolveQuerySearch(search) {
  231. const result = {}
  232. search = search || window.location.search
  233. if (search) {
  234. if (search.startsWith('?')) {
  235. search = search.substring(1)
  236. }
  237. search
  238. .split('&')
  239. .map((entry) => {
  240. return entry.split('=')
  241. })
  242. .forEach((entry) => {
  243. result[entry[0]] = entry[1]
  244. })
  245. }
  246. return result
  247. }
  248.  
  249. function loadJS(src) {
  250. return new Promise((resolve) => {
  251. const script = document.createElement('script')
  252. script.src = src
  253. script.onload = resolve
  254. document.head.append(script)
  255. })
  256. }
  257.  
  258. function ready(selector, interval = 300, timeout = 3000) {
  259. return new Promise((resolve, reject) => {
  260. const loopId = setInterval(
  261. (startTime) => {
  262. if (document.querySelector(selector)) {
  263. clearInterval(loopId)
  264. resolve()
  265. } else {
  266. if (Date.now() - startTime > timeout) {
  267. clearInterval(loopId)
  268. reject(`look up for target '${selector}' timeout: ${timeout}ms`)
  269. }
  270. }
  271. },
  272. interval,
  273. Date.now()
  274. )
  275. })
  276. }
  277.  
  278. function getStartInt(str) {
  279. let result = ''
  280. if (str) {
  281. for (let i = 0; i < str.length; i++) {
  282. if (isNaN(parseInt(str[i]))) {
  283. if (result) break
  284. } else {
  285. result += str[i]
  286. }
  287. }
  288. }
  289. return parseInt(result)
  290. }
  291.  
  292. function getEndInt(str) {
  293. let result = ''
  294. if (str) {
  295. for (let i = str.length - 1; i >= 0; i--) {
  296. if (isNaN(parseInt(str[i]))) {
  297. if (result) break
  298. } else {
  299. result = str[i] + result
  300. }
  301. }
  302. }
  303. return parseInt(result)
  304. }
  305.  
  306. function getPageLocation(path, p, num) {
  307. const params = {
  308. mod: 'forumdisplay',
  309. fid: p.fid || '',
  310. filter: p.filter || '',
  311. typeid: p.typeid || '',
  312. orderby: p.orderby || '',
  313. page: num
  314. }
  315. const paramStr =
  316. '?' +
  317. Object.entries(params)
  318. .map((entry) => {
  319. return `${entry[0]}=${entry[1]}`
  320. })
  321. .join('&')
  322. return path + paramStr
  323. }
  324.  
  325. function getInstance(arg) {
  326. const { querySearch } = arg
  327.  
  328. const getPageMode = () => {
  329. const path = window.location.pathname
  330. if (path === '/forum.php') return querySearch.mod || 'index'
  331. if (path.includes('forum')) return 'forumdisplay'
  332. if (path.includes('thread')) return 'viewthread'
  333. return 'index'
  334. }
  335. const handlePostList = (data) => {
  336. const { path, params, search } = data
  337. // 替换分页
  338. document.querySelectorAll('#fd_page_bottom > .pg, #fd_page_top > .pg')?.forEach((pw) => {
  339. const strong = pw.querySelector('strong')
  340. let currentPage = 1
  341. if (strong) {
  342. currentPage = getStartInt(strong.innerText)
  343. }
  344. pw.querySelectorAll('a[href]')?.forEach((page) => {
  345. const pageNum = getEndInt(page.innerText)
  346. if (isNaN(pageNum)) {
  347. if (page.classList.contains('prev')) {
  348. page.href = getPageLocation(path, params, currentPage - 1)
  349. } else if (page.classList.contains('nxt')) {
  350. page.href = getPageLocation(path, params, currentPage + 1)
  351. }
  352. } else {
  353. page.href = getPageLocation(path, params, pageNum)
  354. }
  355. })
  356. const pageInput = pw.querySelector('input[name=custompage]')
  357. if (pageInput) {
  358. pageInput.onkeydown = function (event) {
  359. if (event.keyCode === 13) {
  360. window.location = getPageLocation(path, params, this.value)
  361. window.doane?.(event)
  362. }
  363. }
  364. }
  365. })
  366. // 过滤结果
  367. const notMatch = []
  368. const match = (t) => {
  369. return t && t.indexOf && t.indexOf(search) >= 0
  370. }
  371. document.querySelectorAll('#threadlisttableid > tbody')?.forEach((item) => {
  372. if (!match(item.querySelector('a.s.xst')?.innerText)) {
  373. notMatch.push(item)
  374. }
  375. })
  376. const setFilter = (filter) => {
  377. notMatch.forEach((item) => {
  378. if (filter) {
  379. item.setAttribute('style', 'display: none !important;')
  380. } else {
  381. item.removeAttribute('style')
  382. }
  383. })
  384. }
  385. // 增加过滤按钮
  386. const tf = document.querySelector('#threadlist .tf')
  387. if (tf) {
  388. let filterCB = tf.querySelector(`label input.${namespace}`)
  389. if (!filterCB) {
  390. filterCB = document.createElement('input')
  391. filterCB.classList.add(namespace)
  392. filterCB.type = 'checkbox'
  393. const label = document.createElement('label')
  394. label.append(filterCB, document.createTextNode('只看搜索结果'))
  395. tf.append(document.createTextNode('\xA0'), label)
  396. }
  397. filterCB.checked = !!search
  398. if (search) setFilter(true)
  399. filterCB.onchange = (e) => setFilter(e.target.checked)
  400. }
  401. }
  402. const addHideFloorCheckbox = () => {
  403. // 添加隐藏楼层按钮
  404. const pt = document.querySelector('#pt')
  405. if (pt) {
  406. let hideCB = pt.querySelector(`label input.${namespace}`)
  407. if (!hideCB) {
  408. hideCB = document.createElement('input')
  409. hideCB.classList.add(namespace)
  410. hideCB.type = 'checkbox'
  411. const label = document.createElement('label')
  412. label.append(hideCB, document.createTextNode('隐藏其他楼层'))
  413. pt.append(document.createTextNode('\xA0'), label)
  414. }
  415. const otherReply = []
  416. document.querySelectorAll('#postlist > div[id]')?.forEach((div) => {
  417. otherReply.push(div)
  418. })
  419. if (otherReply.length) otherReply.shift()
  420. const hideOther = (h) => {
  421. otherReply.forEach((div) => {
  422. if (h) {
  423. div.setAttribute('style', 'display: none !important;')
  424. } else {
  425. div.removeAttribute('style')
  426. }
  427. })
  428. }
  429. hideCB.checked = true
  430. hideOther(true)
  431. hideCB.onchange = (e) => hideOther(e.target.checked)
  432. }
  433. }
  434.  
  435. if (window.location.hostname.includes('thz')) {
  436. return {
  437. name: 'thz',
  438. getDefaultData() {
  439. return {
  440. executeSelector: '#discuz_tips',
  441. path: '/forum.php',
  442. params: {
  443. fid: '181',
  444. filter: 'typeid',
  445. typeid: '',
  446. orderby: 'heats'
  447. },
  448. search: ''
  449. }
  450. },
  451. getFormsData() {
  452. return {
  453. fidOptions: [
  454. { value: '181', label: '亚洲無碼原創' },
  455. { value: '220', label: '亚洲有碼原創' },
  456. { value: '182', label: '欧美無碼' },
  457. { value: '69', label: '国内原创(BT)' },
  458. { value: '203', label: '各类合集资源' },
  459. { value: '177', label: '蓝光高清原盘' },
  460. { value: '39', label: '日韩情色(BT)' },
  461. { value: '40', label: '西方美人(BT)' },
  462. { value: '60', label: '国产专栏(BT)' },
  463. { value: '58', label: '三级伦理(BT)' },
  464. { value: '41', label: '动漫精品(BT)' },
  465. { value: '63', label: '精美套图(BT)' },
  466. { value: '79', label: '桃花原創發片預告' },
  467. { value: '172', label: '桃花原創合集(BT)' },
  468. { value: '73', label: '三级*未分级(BT)' },
  469. { value: '137', label: '美圖寫真(BT)' },
  470. { value: '196', label: '热门电影(BT)' }
  471. ],
  472. filterOptions: [{ value: 'typeid', label: '系列' }],
  473. typeidOptions: {
  474. 181: [
  475. { value: '', label: '全部' },
  476. { value: '664', label: 'FC2PPV' },
  477. { value: '33', label: '美女步兵' },
  478. { value: '35', label: '一本道系' },
  479. { value: '36', label: '加勒比系' },
  480. { value: '64', label: '1919go' },
  481. { value: '39', label: '10musu' },
  482. { value: '47', label: '性孽變態' },
  483. { value: '53', label: '素人系列' },
  484. { value: '37', label: '东京热系' },
  485. { value: '38', label: 'HEYZO' },
  486. { value: '116', label: 'MuraTV' },
  487. { value: '67', label: 'HeYPPV' },
  488. { value: '50', label: '仟人斬系' },
  489. { value: '51', label: '金髪天國' },
  490. { value: '52', label: '盜撮系列' },
  491. { value: '49', label: 'ガチん娘' },
  492. { value: '40', label: '人妻熟女' },
  493. { value: '319', label: 'pacoma' },
  494. { value: '195', label: '無毛宣言' },
  495. { value: '194', label: 'メス豚系' },
  496. { value: '226', label: 'RealDiva' },
  497. { value: '114', label: 'XXX-AV' },
  498. { value: '196', label: '誘惑天国' },
  499. { value: '198', label: '经典稀缺' },
  500. { value: '200', label: '問答無用' },
  501. { value: '44', label: 'JavHD' },
  502. { value: '321', label: 'h4610系' },
  503. { value: '322', label: '素人妻系' },
  504. { value: '320', label: '人妻斬系' },
  505. { value: '501', label: 'AV志向系' },
  506. { value: '616', label: '店長推薦' },
  507. { value: '731', label: '本生素人' },
  508. { value: '48', label: '3D影畫' },
  509. { value: '523', label: 'H:G:M:O' },
  510. { value: '222', label: '写真专辑' },
  511. { value: '768', label: '无码流出' },
  512. { value: '770', label: '麻豆传媒' }
  513. ],
  514. 220: [
  515. { value: '', label: '全部' },
  516. { value: '91', label: '高清騎兵' },
  517. { value: '92', label: '美女騎兵' },
  518. { value: '109', label: '美素人系' },
  519. { value: '110', label: '剧情系列' },
  520. { value: '221', label: '无损原盘' }
  521. ],
  522. 182: [
  523. { value: '', label: '全部' },
  524. { value: '41', label: 'x-Art' },
  525. { value: '42', label: 'Wow' },
  526. { value: '43', label: 'bangbros' },
  527. { value: '45', label: 'brazzers' },
  528. { value: '120', label: 'naughtyamerica' },
  529. { value: '122', label: 'babes' },
  530. { value: '46', label: 'realitykings' },
  531. { value: '115', label: 'DDF' },
  532. { value: '111', label: '按摩师系' },
  533. { value: '214', label: 'twistys' },
  534. { value: '121', label: 'nubilefilms' },
  535. { value: '197', label: 'hegre-art' },
  536. { value: '227', label: 'wicked' },
  537. { value: '150', label: 'BDSM' },
  538. { value: '216', label: '邪惡天使' },
  539. { value: '219', label: 'vixen' },
  540. { value: '220', label: 'passion-hd' },
  541. { value: '223', label: '18yoga' },
  542. { value: '224', label: 'private' },
  543. { value: '193', label: 'joymii' },
  544. { value: '201', label: '21members' },
  545. { value: '202', label: 'colette' },
  546. { value: '213', label: 'mofos' },
  547. { value: '215', label: 'nubiles' },
  548. { value: '217', label: 'blacked' },
  549. { value: '225', label: 'sexart' },
  550. { value: '199', label: 'Femjoy' },
  551. { value: '228', label: 'digitalplayground' },
  552. { value: '496', label: '18xgirls' },
  553. { value: '497', label: 'teamskeet' },
  554. { value: '498', label: 'sexyhub' },
  555. { value: '499', label: 'fakehub' },
  556. { value: '500', label: 'realitygang' },
  557. { value: '218', label: 'julesjordan' },
  558. { value: '513', label: 'TUSHY' },
  559. { value: '605', label: 'ANALIZED' },
  560. { value: '615', label: 'HARDX' },
  561. { value: '730', label: 'nubiles-porn' },
  562. { value: '732', label: 'lubed' },
  563. { value: '769', label: 'deeper' },
  564. { value: '87', label: 'SM变态' },
  565. { value: '88', label: '其它分类' },
  566. { value: '86', label: '肛交天堂' }
  567. ],
  568. 69: [
  569. { value: '', label: '全部' },
  570. { value: '9', label: '国内无码' },
  571. { value: '10', label: '国内偷拍' },
  572. { value: '11', label: '主播探花' },
  573. { value: '65', label: '美女资源' },
  574. { value: '192', label: '国模私拍' }
  575. ],
  576. 203: [
  577. { value: '', label: '全部' },
  578. { value: '55', label: '亚洲无码' },
  579. { value: '56', label: '亚洲有码' },
  580. { value: '57', label: '欧美情色' },
  581. { value: '63', label: '其他资源' }
  582. ],
  583. 177: [
  584. { value: '', label: '全部' },
  585. { value: '27', label: '亚洲无码' },
  586. { value: '28', label: '亚洲有码' },
  587. { value: '29', label: '欧美情色' },
  588. { value: '30', label: '其他原盘' }
  589. ],
  590. 39: [
  591. { value: '', label: '全部' },
  592. { value: '1', label: '无码' },
  593. { value: '2', label: '有码' }
  594. ],
  595. 40: [{ value: '', label: '全部' }],
  596. 60: [{ value: '', label: '全部' }],
  597. 58: [{ value: '', label: '全部' }],
  598. 41: [{ value: '', label: '全部' }],
  599. 63: [{ value: '', label: '全部' }],
  600. 79: [{ value: '', label: '全部' }],
  601. 172: [
  602. { value: '', label: '全部' },
  603. { value: '18', label: '亚洲无码' },
  604. { value: '19', label: '亚洲有码' },
  605. { value: '20', label: '中文字幕' },
  606. { value: '21', label: '欧美情色' },
  607. { value: '22', label: '伦理电影' },
  608. { value: '23', label: '美女写真' },
  609. { value: '24', label: '成人动漫' }
  610. ],
  611. 73: [{ value: '', label: '全部' }],
  612. 137: [{ value: '', label: '全部' }],
  613. 196: [{ value: '', label: '全部' }]
  614. },
  615. orderbyOptions: [
  616. { value: 'heats', label: '最热' },
  617. { value: 'lastpost', label: '最新' },
  618. { value: 'dateline', label: '时间' }
  619. ]
  620. }
  621. },
  622. getPageMode,
  623. getNeedToHideElements(pageMode) {
  624. const elements = []
  625. let selector =
  626. '.a_fl, .a_fr, .a_cn, #toptb + div[align=center], #diynavtop, #toptb, #hd, #ft, #f_pst, #newspecial'
  627. switch (pageMode) {
  628. case 'forumdisplay':
  629. selector += ', #autopbn, #newspecialtmp'
  630. break
  631. case 'viewthread':
  632. selector += ', #pgt, .pgt, .pgbtn, #hiddenpoststip, .pgs'
  633. break
  634. case 'index':
  635. selector += ', #autopbn, #ct > .mn > style + div, #ct > .mn > div + table'
  636. break
  637. }
  638. if (selector) {
  639. elements.push(...document.querySelectorAll(selector))
  640. }
  641. return elements
  642. },
  643. handlePostList,
  644. handlePostContent() {
  645. addHideFloorCheckbox()
  646. }
  647. }
  648. }
  649. if (window.location.hostname.includes('wpzo')) {
  650. return {
  651. name: '98t',
  652. getDefaultData() {
  653. return {
  654. executeSelector: '#scrolltop',
  655. path: '/forum.php',
  656. params: {
  657. fid: '36',
  658. filter: 'typeid',
  659. typeid: '',
  660. orderby: 'heats'
  661. },
  662. search: ''
  663. }
  664. },
  665. getFormsData() {
  666. return {
  667. fidOptions: [
  668. { label: '国产原创', value: 2 },
  669. { label: '亚洲无码原创', value: 36 },
  670. { label: '亚洲有码原创', value: 37 },
  671. { label: '高清中文字幕', value: 103 },
  672. { label: '三级写真', value: 107 },
  673. { label: 'VR视频区', value: 160 },
  674. { label: '素人有码系列', value: 104 },
  675. { label: '欧美无码', value: 38 },
  676. { label: '4K原版', value: 151 },
  677. { label: '韩国主播', value: 152 },
  678. { label: '动漫原创', value: 39 },
  679. { label: '国产自拍', value: 41 },
  680. { label: '中文字幕', value: 109 },
  681. { label: '日韩无码', value: 42 },
  682. { label: '日韩有码', value: 43 },
  683. { label: '欧美风情', value: 44 },
  684. { label: '卡通动漫', value: 45 },
  685. { label: '剧情三级', value: 46 },
  686. { label: '自提字幕区', value: 145 },
  687. { label: '自译字幕区', value: 146 },
  688. { label: '字幕分享区', value: 121 },
  689. { label: '新作区', value: 159 },
  690. { label: '原创自拍区', value: 155 },
  691. { label: '转贴自拍', value: 125 },
  692. { label: '华人街拍区', value: 50 },
  693. { label: '亚洲性爱', value: 48 },
  694. { label: '欧美性爱', value: 49 },
  695. { label: '卡通动漫', value: 117 },
  696. { label: '套图下载', value: 165 },
  697. { label: '综合讨论区', value: 95 },
  698. { label: 'AI专区', value: 166 },
  699. { label: '网友原创区', value: 141 },
  700. { label: '转帖交流区', value: 141 }
  701. ],
  702. filterOptions: [{ value: 'typeid', label: '系列' }],
  703. typeidOptions: {
  704. 2: [
  705. { value: '', label: '全部' },
  706. { value: '684', label: '国产无码' },
  707. { value: '', label: '主播录制' },
  708. { value: '686', label: '360水滴' },
  709. { value: '687', label: '厕所偷拍' }
  710. ],
  711. 36: [
  712. { value: '', label: '全部' },
  713. { value: '586', label: 'sm-miracle' },
  714. { value: '822', label: 'cospuri' },
  715. { value: '724', label: '盗窃系列' },
  716. { value: '723', label: 'japornxxx' },
  717. { value: '683', label: 'レズのしんぴ' },
  718. { value: '672', label: '无码破解' },
  719. { value: '671', label: '加勒比PPV' },
  720. { value: '660', label: '金髪天國' },
  721. { value: '654', label: '无码流出' },
  722. { value: '631', label: 'urabukkake' },
  723. { value: '619', label: 'handjobjapan' },
  724. { value: '618', label: 'spermmania' },
  725. { value: '591', label: 'fellatiojapan' },
  726. { value: '590', label: 'uralesbian' },
  727. { value: '589', label: 'legsjapan' },
  728. { value: '587', label: 'roselip-fetish' },
  729. { value: '368', label: 'FC2PPV' },
  730. { value: '583', label: '本生素人TV' },
  731. { value: '553', label: 'エッチな4610' },
  732. { value: '552', label: 'エッチな0930' },
  733. { value: '551', label: '人妻斬り' },
  734. { value: '537', label: 'xxx-av' },
  735. { value: '523', label: '熟女俱樂部' },
  736. { value: '449', label: '东京热' },
  737. { value: '379', label: '店長推薦' },
  738. { value: '375', label: 'heyppv' },
  739. { value: '374', label: 'pacoma' },
  740. { value: '373', label: '女体のしんぴ' },
  741. { value: '372', label: '10musu' },
  742. { value: '371', label: '一本道系' },
  743. { value: '370', label: '加勒比系' },
  744. { value: '369', label: 'HEYZO' }
  745. ],
  746. 37: [{ value: '', label: '全部' }],
  747. 103: [
  748. { value: '', label: '全部' },
  749. { value: '480', label: '有码高清' },
  750. { value: '481', label: '无码高清' }
  751. ],
  752. 107: [
  753. { value: '', label: '全部' },
  754. { value: '629', label: '巴西三级' },
  755. { value: '628', label: '克罗地亚三级' },
  756. { value: '624', label: '德国三级' },
  757. { value: '623', label: '美国写真' },
  758. { value: '622', label: '俄罗斯三级' },
  759. { value: '621', label: '墨西哥三级' },
  760. { value: '620', label: '西班牙三级' },
  761. { value: '617', label: '国产写真' },
  762. { value: '616', label: '波兰三级' },
  763. { value: '615', label: '泰国四级' },
  764. { value: '614', label: '阿根廷三级' },
  765. { value: '613', label: '香港四级' },
  766. { value: '612', label: '瑞士四级' },
  767. { value: '611', label: '瑞士三级' },
  768. { value: '610', label: '挪威三级' },
  769. { value: '609', label: '台湾三级' },
  770. { value: '608', label: '荷兰三级' },
  771. { value: '607', label: '意大利三级' },
  772. { value: '606', label: '加拿大三级' },
  773. { value: '605', label: '法国四级' },
  774. { value: '604', label: '泰国三级' },
  775. { value: '603', label: '台湾四级' },
  776. { value: '602', label: '英国三级' },
  777. { value: '601', label: '英国四级' },
  778. { value: '600', label: '国产四级' },
  779. { value: '599', label: '美国四级' },
  780. { value: '598', label: '法国三级' },
  781. { value: '597', label: '国产三级' },
  782. { value: '596', label: '香港三级' },
  783. { value: '595', label: '美国三级' },
  784. { value: '594', label: '日本三级' },
  785. { value: '593', label: '韩国三级' },
  786. { value: '592', label: '日本写真' },
  787. { value: '625', label: '丹麦三级' },
  788. { value: '630', label: '意大利四级' },
  789. { value: '633', label: '德国四级' },
  790. { value: '634', label: '瑞典四级' },
  791. { value: '645', label: '丹麦四级' },
  792. { value: '646', label: '荷兰写真' },
  793. { value: '650', label: '比利时四级' },
  794. { value: '655', label: '澳大利亚三级' },
  795. { value: '656', label: '印度三级' },
  796. { value: '657', label: '菲律宾三级' },
  797. { value: '658', label: '新加坡写真' },
  798. { value: '659', label: '韩国写真' },
  799. { value: '667', label: '法国写真' },
  800. { value: '668', label: '英国写真' },
  801. { value: '669', label: '俄罗斯写真' },
  802. { value: '670', label: '智利三级' }
  803. ],
  804. 160: [{ value: '', label: '全部' }],
  805. 104: [
  806. { value: '', label: '全部' },
  807. { value: '533', label: 'G-area' },
  808. { value: '728', label: '300MIUM' },
  809. { value: '729', label: '332NAMA' },
  810. { value: '730', label: '326EVA' },
  811. { value: '731', label: '328HMDN' },
  812. { value: '807', label: '336KNB' },
  813. { value: '808', label: '200GANA' },
  814. { value: '809', label: '300MAAN' },
  815. { value: '810', label: '300NTK' },
  816. { value: '811', label: '390JAC' },
  817. { value: '812', label: '326SCP' },
  818. { value: '727', label: '259LUXU' },
  819. { value: '726', label: 'SIRO' },
  820. { value: '534', label: 'Mywife' },
  821. { value: '535', label: 'S-cute' },
  822. { value: '536', label: 'FC2' },
  823. { value: '557', label: 'himemix' },
  824. { value: '563', label: 'getchu' },
  825. { value: '588', label: 'siro-hame' },
  826. { value: '626', label: 'r-file' },
  827. { value: '627', label: 'giga-web' },
  828. { value: '632', label: 'knights-visual' },
  829. { value: '725', label: '230OREX' },
  830. { value: '813', label: '其他系列' }
  831. ],
  832. 38: [{ value: '', label: '全部' }],
  833. 151: [
  834. { value: '', label: '全部' },
  835. { value: '823', label: '无码' },
  836. { value: '824', label: '有码' }
  837. ],
  838. 152: [{ value: '', label: '全部' }],
  839. 39: [
  840. { value: '', label: '全部' },
  841. { value: '404', label: '无码' },
  842. { value: '405', label: '有码' }
  843. ],
  844. 41: [{ value: '', label: '全部' }],
  845. 109: [{ value: '', label: '全部' }],
  846. 42: [{ value: '', label: '全部' }],
  847. 43: [{ value: '', label: '全部' }],
  848. 44: [{ value: '', label: '全部' }],
  849. 45: [{ value: '', label: '全部' }],
  850. 46: [{ value: '', label: '全部' }],
  851. 145: [
  852. { value: '', label: '全部' },
  853. { value: '814', label: '有码字幕' },
  854. { value: '815', label: '无码字幕' }
  855. ],
  856. 146: [
  857. { value: '', label: '全部' },
  858. { value: '845', label: '欧美' },
  859. { value: '846', label: '日本' }
  860. ],
  861. 121: [
  862. { value: '', label: '全部' },
  863. { value: '664', label: '有码字幕' },
  864. { value: '665', label: '无码字幕' },
  865. { value: '848', label: '缺字需修正' }
  866. ],
  867. 159: [
  868. { value: '', label: '全部' },
  869. { value: '849', label: '新作' }
  870. ],
  871. 155: [
  872. { value: '', label: '全部' },
  873. { value: '820', label: '原创自拍' },
  874. { value: '821', label: '投稿送码' }
  875. ],
  876. 125: [
  877. { value: '', label: '全部' },
  878. { value: '831', label: '性爱自拍' },
  879. { value: '832', label: '生活自拍' }
  880. ],
  881. 50: [
  882. { value: '', label: '全部' },
  883. { value: '833', label: '原创街拍' },
  884. { value: '838', label: '转帖街拍' },
  885. { value: '834', label: '模拍' }
  886. ],
  887. 48: [{ value: '', label: '全部' }],
  888. 49: [{ value: '', label: '全部' }],
  889. 117: [
  890. { value: '', label: '全部' },
  891. { value: '647', label: '日文' },
  892. { value: '648', label: '中文' },
  893. { value: '649', label: '韩文' },
  894. { value: '835', label: '3D' },
  895. { value: '836', label: '黑白' },
  896. { value: '837', label: '彩漫' }
  897. ],
  898. 165: [{ value: '', label: '全部' }],
  899. 95: [
  900. { value: '', label: '全部' },
  901. { value: '709', label: '困惑求助' },
  902. { value: '710', label: '技术交流' },
  903. { value: '711', label: '心情感悟' },
  904. { value: '712', label: 'AV新闻' },
  905. { value: '713', label: '图文故事' },
  906. { value: '714', label: '今日话题' },
  907. { value: '715', label: '不吐不快' },
  908. { value: '716', label: '情色分享' },
  909. { value: '843', label: '游客投稿' }
  910. ],
  911. 166: [
  912. { value: '', label: '全部' },
  913. { value: '851', label: 'AI换脸' },
  914. { value: '852', label: 'AI破解' },
  915. { value: '853', label: 'AI增强' },
  916. { value: '854', label: 'AI作图' },
  917. { value: '855', label: '教程工具' }
  918. ],
  919. 141: [
  920. { value: '', label: '全部' },
  921. { value: '688', label: '个人导航' },
  922. { value: '689', label: '国产合集' },
  923. { value: '690', label: '欧美合集' },
  924. { value: '691', label: '日本合集' },
  925. { value: '692', label: 'AI破解/换脸' },
  926. { value: '693', label: '动漫/二次元' },
  927. { value: '694', label: '蓝光原盘' },
  928. { value: '695', label: '套图系列' },
  929. { value: '696', label: '其他資源' },
  930. { value: '705', label: '自压/增强' },
  931. { value: '708', label: '版务管理' },
  932. { value: '844', label: '合集推荐' }
  933. ],
  934. 142: [
  935. { value: '', label: '全部' },
  936. { value: '697', label: '国产自拍' },
  937. { value: '698', label: '直播视频' },
  938. { value: '699', label: '亚洲无码' },
  939. { value: '700', label: '亚洲有码' },
  940. { value: '701', label: '偷拍視頻' },
  941. { value: '702', label: '动漫/二次元' },
  942. { value: '703', label: '欧美风情' },
  943. { value: '704', label: '其他資源' },
  944. { value: '706', label: '合集资源' }
  945. ]
  946. },
  947. orderbyOptions: [
  948. { value: 'heats', label: '最热' },
  949. { value: 'lastpost', label: '最新' },
  950. { value: 'dateline', label: '时间' }
  951. ]
  952. }
  953. },
  954. getPageMode,
  955. getNeedToHideElements(pageMode) {
  956. const elements = []
  957. let selector = '.show-text, .show-text2, .show-text3, .show-text4, #toptb, #hd, #ft, #f_pst, #newspecial'
  958. switch (pageMode) {
  959. case 'forumdisplay':
  960. selector += ', #autopbn, #newspecialtmp'
  961. break
  962. case 'viewthread':
  963. selector += ', #pgt, .pgt, .pgbtn, #hiddenpoststip, .pgs'
  964. break
  965. case 'index':
  966. selector += ''
  967. break
  968. }
  969. if (selector) {
  970. elements.push(...document.querySelectorAll(selector))
  971. }
  972. return elements
  973. },
  974. handlePostList,
  975. handlePostContent() {
  976. addHideFloorCheckbox()
  977. // 收起评分
  978. const hideRate = document.querySelector('.rate a.op')
  979. if (hideRate && hideRate.innerText === '收起') {
  980. hideRate.dispatchEvent(new MouseEvent('click'))
  981. }
  982. }
  983. }
  984. }
  985. }
  986. })()