├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── build └── prod.js ├── bun.lock ├── bunfig.toml ├── package.json ├── packages ├── auto-scroll │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── bilibili-live-auto-click-like │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── cocomanga-subscription-sort │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── douyin-live-auto-click-like │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts ├── mooc-skip-questions │ ├── README.md │ ├── package.json │ └── src │ │ └── index.ts └── tencent-kt-box │ ├── README.md │ ├── package.json │ └── src │ └── index.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | 23 | pids 24 | _.pid 25 | _.seed 26 | *.pid.lock 27 | 28 | # Directory for instrumented libs generated by jscoverage/JSCover 29 | 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | 47 | bower_components 48 | 49 | # node-waf configuration 50 | 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | 55 | build/Release 56 | 57 | # Dependency directories 58 | 59 | node_modules/ 60 | jspm_packages/ 61 | 62 | # Snowpack dependency directory (https://snowpack.dev/) 63 | 64 | web_modules/ 65 | 66 | # TypeScript cache 67 | 68 | *.tsbuildinfo 69 | 70 | # Optional npm cache directory 71 | 72 | .npm 73 | 74 | # Optional eslint cache 75 | 76 | .eslintcache 77 | 78 | # Optional stylelint cache 79 | 80 | .stylelintcache 81 | 82 | # Microbundle cache 83 | 84 | .rpt2_cache/ 85 | .rts2_cache_cjs/ 86 | .rts2_cache_es/ 87 | .rts2_cache_umd/ 88 | 89 | # Optional REPL history 90 | 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | 95 | *.tgz 96 | 97 | # Yarn Integrity file 98 | 99 | .yarn-integrity 100 | 101 | # dotenv environment variable files 102 | 103 | .env 104 | .env.development.local 105 | .env.test.local 106 | .env.production.local 107 | .env.local 108 | 109 | # parcel-bundler cache (https://parceljs.org/) 110 | 111 | .parcel-cache 112 | 113 | # Next.js build output 114 | 115 | .next 116 | out 117 | 118 | # Nuxt.js build / generate output 119 | 120 | .nuxt 121 | dist 122 | 123 | # Gatsby files 124 | 125 | # Comment in the public line in if your project uses Gatsby and not Next.js 126 | 127 | # https://nextjs.org/blog/next-9-1#public-directory-support 128 | 129 | # public 130 | 131 | # vuepress build output 132 | 133 | .vuepress/dist 134 | 135 | # vuepress v2.x temp and cache directory 136 | 137 | .temp 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "editor.formatOnSave": true, 4 | "editor.codeActionsOnSave": { 5 | "source.organizeImports": "explicit" 6 | }, 7 | "prettier.tabWidth": 2, 8 | "prettier.semi": false, 9 | "prettier.printWidth": 120, 10 | "prettier.singleQuote": true, 11 | "prettier.arrowParens": "avoid", 12 | "prettier.trailingComma": "none", 13 | "prettier.htmlWhitespaceSensitivity": "ignore" 14 | } 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2025, Kaiter-Plus 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 油猴脚本 2 | 3 | ### 支持作者 4 | 5 | ![支持作者小程序码](https://greasyfork.org/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBekdIQVE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--56691abdd507118966e2810dd47b1e2a3b9b82e8/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lKYW5CbFp3WTZCa1ZVT2hSeVpYTnBlbVZmZEc5ZmJHbHRhWFJiQjJrQnlHa0J5QT09IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--4c3cded9533f8c872a82572269844d930809aad4/support.png?locale=zh-CN) 6 | ![支付宝](https://greasyfork.s3.us-east-2.amazonaws.com/lg94h87tgo1nuetf5n2fuhvloa2s) 7 | 微信 8 | 9 | ## 1 项目介绍 10 | 11 | - 用来保存平时学习时写的油猴脚本的项目 12 | 13 | ## 2 项目脚本功能介绍 14 | 15 | ### 2.1 网页翻译(重构中) 16 | 17 | #### 2.1.1 Translate 18 | 19 | - 网页翻译(整页翻译),给每个非中文的网页添加一个 google 翻译图标 20 | - 位置:默认右下角,可以设置到左下角 21 | - 设置:点击浏览器的油猴或者暴力猴插件图标即可看见脚本的配置选项,点击配置选项即可切换按钮的位置 22 | 23 | #### 2.1.2 Translate_ext 24 | 25 | - 网页翻译(整页翻译),给每个非中文的网页添加一个 google 翻译图标 26 | - 位置:默认右下角 27 | - 简介:本版本主要适配不能安装 Tampermonkey 或 Violentmonkey 的手机浏览器 28 | 29 | #### 2.1.2 Translate_only_chinese 30 | 31 | - 网页翻译(整页翻译),给每个非中文的网页添加一个 google 翻译图标 32 | - 位置:默认右下角 33 | - 简介:本版本主要针对只需要把外语翻译为中文的用户使用 34 | 35 | ### 2.2 AutoScroll 36 | 37 | - 自动滚动,给每个网页添加两个按钮,当鼠标分别覆盖这两个按钮时,页面将会自动向上或者向下滚动 38 | 39 | ### 2.3 MOOCSkipQuestion 40 | 41 | - 慕课网自动跳过播放过程中的题目,同时自动播放 42 | 43 | ### 2.4 TencentKTBox 44 | 45 | - 腾讯课堂自动自动签到脚本 46 | 47 | ### 2.5 COCO 漫画收藏按更新时间排序 48 | 49 | - 顾名思义,给[COCO 漫画](http://www.cocomanhua.com/)的收藏界面添加按照更新时间排序的功能 50 | - 最近的更新排在最上面 51 | 52 | ### 2.6 抖音自动点赞 53 | 54 | - 网页版抖音看直播自动点赞工具,同时优化了抖音官方点赞过多网页卡顿的问题(bug) 55 | 56 | ### 2.7 虎牙直播功能增强(重构中) 57 | 58 | - 给虎牙直播添加两个功能:时间同步和镜像画面 59 | - 时间同步:同步到最新时间 60 | - 镜像画面:顾名思义,直接让画面反转 180° 61 | - 自动选择最高画质 62 | - 自动领取百宝箱奖励 63 | - 自动网页全屏 64 | -------------------------------------------------------------------------------- /build/prod.js: -------------------------------------------------------------------------------- 1 | import { Glob } from 'bun' 2 | import minimist from 'minimist' 3 | import { resolve } from 'node:path' 4 | 5 | // 获取打包命令的参数 6 | const args = minimist(Bun.argv.slice(2)) 7 | 8 | // 需要打包的项目 9 | const project = args.p 10 | 11 | // 如果没有指定打包的项目,默认全部打包 12 | if (!project) { 13 | // 扫描路径 14 | const scanPath = resolve(__dirname, `../packages`) 15 | // 创建一个全局搜索对象,并指定搜索的表达式 16 | const glob = new Glob(`**/index.ts`) 17 | // 开始搜索,找到项目名称 18 | for await (const file of glob.scan(scanPath)) { 19 | // 拿到项目名称 20 | const project = file.split(/[\\\/]/)[0] 21 | // 打包 22 | await build(project) 23 | } 24 | } else { 25 | await build(project) 26 | } 27 | 28 | function getBanner(pkg) { 29 | // 公共头部 30 | const commonBanner = ` 31 | // @name ${pkg.buildOptions.name.default} 32 | // @author ${pkg.author} 33 | // @description ${pkg.description} 34 | // @namespace ${pkg.repository.url} 35 | // @license ${pkg.license} 36 | // @version ${pkg.version}` 37 | 38 | // 每个脚本自定义头部 39 | let payloadBanner = `` 40 | const spaceLength = pkg.buildOptions.spaces 41 | const payload = pkg.buildOptions.payload 42 | if (payload) { 43 | for (const key in payload) { 44 | for (const item of payload[key]) { 45 | payloadBanner += `\n// @${key.padEnd(spaceLength, ' ')}${item}` 46 | } 47 | } 48 | } 49 | 50 | return `// ==UserScript==${commonBanner}${payloadBanner}\n// ==/UserScript==\n;` 51 | } 52 | 53 | async function build(projectName) { 54 | const entry = resolve(__dirname, `../packages/${projectName}/src/index.ts`) 55 | const pkg = require(`../packages/${projectName}/package.json`) 56 | const banner = getBanner(pkg) 57 | // 打包 58 | await Bun.build({ 59 | entrypoints: [entry], 60 | outdir: resolve(__dirname, '../dist'), 61 | target: 'browser', 62 | format: 'iife', 63 | banner, 64 | naming: `[dir]/${projectName}.user.[ext]` 65 | }).catch(err => { 66 | console.log('打包失败,原因: ', err) 67 | }) 68 | } 69 | -------------------------------------------------------------------------------- /bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 0, 3 | "workspaces": { 4 | "": { 5 | "devDependencies": { 6 | "@types/bun": "latest", 7 | "@types/tampermonkey": "^5.0.4", 8 | "minimist": "^1.2.8", 9 | }, 10 | "peerDependencies": { 11 | "typescript": "^5.0.0", 12 | }, 13 | }, 14 | "packages/auto-scroll": { 15 | "name": "auto-scroll", 16 | "version": "1.0.1", 17 | }, 18 | }, 19 | "packages": { 20 | "@types/bun": ["@types/bun@1.1.14", "https://registry.npmmirror.com/@types/bun/-/bun-1.1.14.tgz", { "dependencies": { "bun-types": "1.1.37" } }, "sha512-opVYiFGtO2af0dnWBdZWlioLBoxSdDO5qokaazLhq8XQtGZbY4pY3/JxY8Zdf/hEwGubbp7ErZXoN1+h2yesxA=="], 21 | 22 | "@types/node": ["@types/node@20.12.14", "https://registry.npmmirror.com/@types/node/-/node-20.12.14.tgz", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="], 23 | 24 | "@types/tampermonkey": ["@types/tampermonkey@5.0.4", "https://registry.npmmirror.com/@types/tampermonkey/-/tampermonkey-5.0.4.tgz", {}, "sha512-HEJ0O5CkDZSwIgd9Zip4xM8o7gZC8zBmJuH1YEXNINIC+aCWEXD10pnpo3NQG5IWHx+Xr4fMSGq1jqeKXH2lpA=="], 25 | 26 | "@types/ws": ["@types/ws@8.5.13", "https://registry.npmmirror.com/@types/ws/-/ws-8.5.13.tgz", { "dependencies": { "@types/node": "*" } }, "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA=="], 27 | 28 | "auto-scroll": ["auto-scroll@workspace:packages/auto-scroll", {}], 29 | 30 | "bun-types": ["bun-types@1.1.37", "https://registry.npmmirror.com/bun-types/-/bun-types-1.1.37.tgz", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-C65lv6eBr3LPJWFZ2gswyrGZ82ljnH8flVE03xeXxKhi2ZGtFiO4isRKTKnitbSqtRAcaqYSR6djt1whI66AbA=="], 31 | 32 | "minimist": ["minimist@1.2.8", "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], 33 | 34 | "typescript": ["typescript@5.7.2", "https://registry.npmmirror.com/typescript/-/typescript-5.7.2.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg=="], 35 | 36 | "undici-types": ["undici-types@5.26.5", "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="], 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /bunfig.toml: -------------------------------------------------------------------------------- 1 | [install] 2 | saveTextLockfile = true 3 | registry = "https://registry.npmmirror.com" -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tampermonkeyscript", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "repository": { 7 | "url": "https://github.com/Kaiter-Plus/TampermonkeyScript" 8 | }, 9 | "scripts": { 10 | "build": "bun build/prod.js" 11 | }, 12 | "workspaces": [ 13 | "packages/*" 14 | ], 15 | "devDependencies": { 16 | "@types/bun": "latest", 17 | "@types/tampermonkey": "^5.0.4", 18 | "minimist": "^1.2.8" 19 | }, 20 | "peerDependencies": { 21 | "typescript": "^5.0.0" 22 | } 23 | } -------------------------------------------------------------------------------- /packages/auto-scroll/README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | ### 支持作者 4 | 5 | ![支付宝](https://greasyfork.s3.us-east-2.amazonaws.com/lg94h87tgo1nuetf5n2fuhvloa2s) 6 | 微信 7 | 8 | ### 所有脚本开源地址,欢迎 star ⭐ 9 | 10 | - gitee:[https://gitee.com/Kaiter-Plus/TampermonkeyScript](https://gitee.com/Kaiter-Plus/TampermonkeyScript) 11 | - github:[https://github.com/Kaiter-Plus/TampermonkeyScript](https://github.com/Kaiter-Plus/TampermonkeyScript) 12 | 13 | ## 1 功能介绍 14 | 15 | 给网页添加自动向上、向下滚动的按钮。对于一些经常需要滚动的场景很有用,比如看文章,看小说,看漫画等场景 16 | 17 | ### 1.1 如何使用它 18 | 19 | 使用很简单,直接使用【鼠标指针】移动覆盖到相应的按钮上即可使网页自动滚动,【鼠标指针】移动覆盖到【中间数值】,然后使用【鼠标滚轮】滚动即可调整滚动速度 20 | 21 | ### 1.2 功能截图 22 | 23 | ![功能截图](https://greasyfork.org/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBN3liQVE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--ee0d49a093c6d2f9d6e2c83c65b6537621a6ee30/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFISWFRSEkiLCJleHAiOm51bGwsInB1ciI6InZhcmlhdGlvbiJ9fQ==--e4f27e4605e5535222e2c2f9dcbe36f4bd1deb29/image.png?locale=zh-CN) 24 | 25 | ## 2 更新日志 26 | 27 | ### 2.1 2022 更新日志 28 | 29 | - 2023/04/09 添加拖动功能 30 | - 2023/04/07 优化显示 31 | - 2023/04/06 添加滚动速度调整功能 32 | - 2021/03/17 实现鼠标覆盖自动向上向下滚动功能 33 | -------------------------------------------------------------------------------- /packages/auto-scroll/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "auto-scroll", 3 | "version": "1.0.1", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "description": "给网页添加自动向上、向下滚动的按钮,对于看文章,看小说,看漫画等场景下使用极为舒适", 7 | "repository": { 8 | "url": "https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/packages/auto-scroll" 9 | }, 10 | "license": "BSD-3-Clause", 11 | "buildOptions": { 12 | "name": { 13 | "default": "自动滚动" 14 | }, 15 | "spaces": 12, 16 | "payload": { 17 | "include": ["*://*"], 18 | "grant": [ 19 | "GM_addStyle", 20 | "GM_getValue", 21 | "GM_setValue", 22 | "GM_addElement" 23 | ], 24 | "noframes": [""] 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /packages/auto-scroll/src/index.ts: -------------------------------------------------------------------------------- 1 | interface Position { 2 | top: number 3 | left: number 4 | } 5 | 6 | enum DIRECTION { 7 | UP = -1, DOWN = 1 8 | } 9 | 10 | // 默认速度 11 | let defaultSpeed: number = 5 12 | // 定时器id 13 | let currentFrameId: number = 0 14 | // 记录上一次执行的时间 15 | let prevTIme: number = 0 16 | // 按下的位置 17 | const pressPosition: Position = { top: 0, left: 0 } 18 | 19 | // 初始化速度 20 | const speed: string = GM_getValue('speed') 21 | speed ? (defaultSpeed = +speed) : GM_setValue('speed', defaultSpeed) 22 | 23 | // 创建一个滚动容器 24 | const scrollContainer = GM_addElement(document.body, 'div', { 25 | id: 'scroll-container', 26 | class: 'scroll-container' 27 | }) 28 | scrollContainer.addEventListener('mousedown', press) 29 | 30 | // 创建自动向上的按钮 31 | const scrollUp = GM_addElement(scrollContainer, 'div', { 32 | id: 'scroll-up', 33 | class: 'scroll-up' 34 | }) 35 | scrollUp.addEventListener('mouseover', () => { 36 | autoScroll(DIRECTION.UP) 37 | }) 38 | scrollUp.addEventListener('mouseout', stopScroll) 39 | 40 | // 创建速度显示 41 | const scrollSpeed = GM_addElement(scrollContainer, 'div', { 42 | id: 'scroll-speed', 43 | class: 'scroll-speed', 44 | textContent: speed 45 | }) 46 | scrollSpeed.addEventListener('wheel', settingSpeed) 47 | 48 | // 创建自动向下的按钮 49 | const scrollDown = GM_addElement(scrollContainer, 'div', { 50 | id: 'scroll-down', 51 | class: 'scroll-down' 52 | }) 53 | scrollDown.addEventListener('mouseover', () => { 54 | autoScroll(DIRECTION.DOWN) 55 | }) 56 | scrollDown.addEventListener('mouseout', stopScroll) 57 | 58 | // 自动滚动 59 | function autoScroll(direction: DIRECTION) { 60 | scroll(direction) 61 | } 62 | 63 | // 滚动 64 | function scroll(direction: DIRECTION) { 65 | currentFrameId = window.requestAnimationFrame(time => { 66 | if (!prevTIme) prevTIme = time 67 | const elapsed = (time - prevTIme) / 1000 68 | // 每 50ms 执行一次 69 | window.scrollBy(0, defaultSpeed * 10 * direction * elapsed) 70 | prevTIme = time 71 | scroll(direction) 72 | }) 73 | } 74 | 75 | // 停止滚动 76 | function stopScroll() { 77 | prevTIme = 0 78 | window.cancelAnimationFrame(currentFrameId) 79 | } 80 | 81 | // 设置滚动速度 82 | function settingSpeed(e: WheelEvent) { 83 | e.preventDefault() 84 | if (e.deltaY < 0) defaultSpeed += 1 85 | else defaultSpeed -= 1 86 | scrollSpeed.textContent = `${defaultSpeed}` 87 | GM_setValue('speed', defaultSpeed) 88 | } 89 | 90 | // 按下事件 91 | function press(e: MouseEvent) { 92 | // 设置只有在速度显示区域才能拖动 93 | if ((e.target as HTMLElement).id === 'scroll-speed') { 94 | // 记录位置 95 | pressPosition.top = e.clientY - (e.currentTarget as HTMLDivElement).offsetTop 96 | pressPosition.left = e.clientX - (e.currentTarget as HTMLDivElement).offsetLeft 97 | // 修改样式显示 98 | scrollSpeed.style.cursor = 'move' 99 | // 开始监听移动事件 100 | document.addEventListener('mousemove', move) 101 | document.addEventListener('mouseup', release) 102 | } 103 | } 104 | 105 | // 移动事件 106 | function move(e: MouseEvent) { 107 | const top = e.clientY - pressPosition.top 108 | const left = e.clientX - pressPosition.left 109 | scrollContainer.style.right = `unset` 110 | scrollContainer.style.top = `${top}px` 111 | scrollContainer.style.left = `${left}px` 112 | } 113 | 114 | // 抬起事件 115 | function release() { 116 | // 修改样式显示 117 | scrollSpeed.style.cursor = 's-resize' 118 | // 清除事件 119 | document.removeEventListener('mousemove', move) 120 | document.removeEventListener('mouseup', release) 121 | } 122 | 123 | // 添加自定义样式 124 | GM_addStyle(` 125 | .scroll-container { 126 | position: fixed; 127 | top: 50%; 128 | right: 10px; 129 | z-index: 99999; 130 | text-align: center; 131 | transform: translateY(-50%); 132 | border-radius: 20px; 133 | overflow: hidden; 134 | background-color: rgba(204, 204, 204, 0.4); 135 | line-height: 40px; 136 | color: rgba(60, 60, 67, .92); 137 | } 138 | .scroll-up, 139 | .scroll-down { 140 | width: 40px; 141 | height: 40px; 142 | text-align: center; 143 | } 144 | .scroll-up::after, 145 | .scroll-down::after { 146 | content: ''; 147 | display: inline-block; 148 | width: 16px; 149 | height: 16px; 150 | font-size: 16px; 151 | box-sizing: border-box; 152 | border-width: 2px; 153 | border-style: solid; 154 | } 155 | .scroll-up::after { 156 | transform: rotate(-45deg); 157 | border-color: rgba(60, 60, 67, .92) rgba(60, 60, 67, .92) transparent transparent; 158 | margin-top: 14.3425px; 159 | } 160 | .scroll-down::after { 161 | transform: rotate(-45deg); 162 | border-color: transparent transparent rgba(60, 60, 67, .92) rgba(60, 60, 67, .92); 163 | margin-top: 8.685px; 164 | } 165 | .scroll-up:hover, 166 | .scroll-down:hover { 167 | background-color: rgba(204, 204, 204, 0.8); 168 | } 169 | 170 | .scroll-speed { 171 | font-size: 18px; 172 | user-select: none; 173 | cursor: s-resize; 174 | } 175 | `) -------------------------------------------------------------------------------- /packages/bilibili-live-auto-click-like/README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | ### 支持作者 4 | 5 | ![支付宝](https://greasyfork.s3.us-east-2.amazonaws.com/lg94h87tgo1nuetf5n2fuhvloa2s) 6 | 微信 7 | 8 | ### 所有脚本开源地址,欢迎 star ⭐ 9 | 10 | - gitee:[https://gitee.com/Kaiter-Plus/TampermonkeyScript](https://gitee.com/Kaiter-Plus/TampermonkeyScript) 11 | - github:[https://github.com/Kaiter-Plus/TampermonkeyScript](https://github.com/Kaiter-Plus/TampermonkeyScript) 12 | 13 | # !!注意!! 14 | 15 | - 本脚本仅供学习交流使用,请勿用于非法用途! 16 | - 使用本脚本用于非法用途后果自负! 17 | - 请于下载后 24 小时内删除! 18 | - 作者本人不负任何法律责任! 19 | 20 | ## 1 脚本介绍 21 | 22 | 实现网页版 Bilibili 直播自动点赞功能 23 | 24 | ## 更新日志 25 | 26 | - 2023/07/12 脚本发布 27 | -------------------------------------------------------------------------------- /packages/bilibili-live-auto-click-like/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bilibili-live-auto-click-like", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "description": "网页版哔哩哔哩直播添加自动点赞功能", 7 | "repository": { 8 | "url": "https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/packages/bilibili-live-auto-click-like" 9 | }, 10 | "license": "BSD-3-Clause", 11 | "buildOptions": { 12 | "name": { 13 | "default": "哔哩哔哩直播自动点赞" 14 | }, 15 | "spaces": 12, 16 | "payload": { 17 | "icon": [ 18 | "https://www.google.com/s2/favicons?sz=64&domain=bilibili.com" 19 | ], 20 | "match": [ 21 | "*://live.bilibili.com/*" 22 | ], 23 | "run-at": [ 24 | "document-end" 25 | ], 26 | "grant": [ 27 | "unsafeWindow", 28 | "GM_getValue", 29 | "GM_setValue", 30 | "GM_notification", 31 | "GM_registerMenuCommand", 32 | "GM_unregisterMenuCommand" 33 | ], 34 | "noframes": [ 35 | "" 36 | ] 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /packages/bilibili-live-auto-click-like/src/index.ts: -------------------------------------------------------------------------------- 1 | // 多久点击一次 2 | const CLICK_DURATION: number = 300 3 | // 点击层的类名 4 | const CLICK_MODAL_CLASS: string = '.like-btn' 5 | // 点击事件层 6 | let clickModal = document.querySelector(CLICK_MODAL_CLASS) 7 | // 定时器 8 | let timer: number | null = null 9 | 10 | // 循环点击 11 | let prevTImestamp = 0 // 记录上一次执行的时间 12 | function autoClick(timestamp: number) { 13 | const duration = timestamp - prevTImestamp 14 | if (duration >= CLICK_DURATION + Math.random() * 100 - 50) { 15 | if (clickModal) { 16 | // 获取元素的坐标 17 | const rect = clickModal.getBoundingClientRect() 18 | const x = rect.top + Math.random() * 50 + 50 19 | const y = rect.left + Math.random() * 50 + 50 20 | // 创建模拟点击事件 21 | const clickEvent = new MouseEvent('click', { 22 | view: unsafeWindow, 23 | bubbles: true, 24 | cancelable: true, 25 | clientX: x, 26 | clientY: y 27 | }) 28 | // 触发模拟点击事件 29 | clickModal.dispatchEvent(clickEvent) 30 | } else { 31 | clickModal = document.querySelector(CLICK_MODAL_CLASS) 32 | } 33 | prevTImestamp = timestamp 34 | } 35 | timer = requestAnimationFrame(autoClick) 36 | } 37 | 38 | interface Tip { 39 | open: string 40 | close: string 41 | } 42 | 43 | interface MenuItem { 44 | key: string 45 | name: string 46 | value: boolean 47 | showNotification: boolean 48 | tip: Tip 49 | click: () => void 50 | } 51 | 52 | // 菜单 53 | const menu: MenuItem[] = [ 54 | { 55 | key: 'switch', 56 | name: '自动点赞', 57 | value: true, 58 | showNotification: true, 59 | tip: { 60 | open: '✅', 61 | close: '❌' 62 | }, 63 | click: switchFn 64 | } 65 | ] 66 | 67 | // 保存已注册的菜单 68 | const menuRegister: number[] = [] 69 | 70 | // 配置默认菜单 71 | menu.forEach(v => { 72 | if (GM_getValue(v.key) === undefined || GM_getValue(v.key) === null) GM_setValue(v.key, v.value) 73 | }) 74 | 75 | // 注册菜单 76 | function registerMenuCommand() { 77 | if (menuRegister.length === menu.length) { 78 | menuRegister.forEach(v => { 79 | GM_unregisterMenuCommand(v) 80 | }) 81 | } 82 | menu.forEach((v, i) => { 83 | v.value = GM_getValue(v.key) 84 | menuRegister[i] = GM_registerMenuCommand(`${v.value ? v.tip.open : v.tip.close} ${v.name}`, () => { 85 | menuSwitch(v) 86 | }) 87 | }) 88 | } 89 | 90 | // 切换菜单 91 | function menuSwitch(item: MenuItem) { 92 | // 设置数据 93 | item.value = !item.value 94 | GM_setValue(item.key, item.value) 95 | // 系统通知 96 | if (item.showNotification) { 97 | GM_notification({ 98 | text: `已${item.value ? item.tip.open : item.tip.close}[${item.name}] 功能`, 99 | title: ' Bilibili 自动点赞', 100 | timeout: 1000 101 | }) 102 | } 103 | // 如果有点击事件,执行 104 | if (item.click) item.click() 105 | // 重新注册 106 | registerMenuCommand() 107 | } 108 | 109 | // 切换开关 110 | function switchFn() { 111 | if (GM_getValue('switch')) timer = requestAnimationFrame(autoClick) 112 | else cancelAnimationFrame(timer!) 113 | } 114 | 115 | function init() { 116 | clickModal = document.querySelector(CLICK_MODAL_CLASS) 117 | registerMenuCommand() 118 | if (GM_getValue('switch')) timer = requestAnimationFrame(autoClick) 119 | } 120 | 121 | // 延迟 3 秒开始, 获取必要数据 122 | setTimeout(() => { 123 | init() 124 | }, 3000) -------------------------------------------------------------------------------- /packages/cocomanga-subscription-sort/README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | ### 支持作者 4 | 5 | ![支付宝](https://greasyfork.s3.us-east-2.amazonaws.com/lg94h87tgo1nuetf5n2fuhvloa2s) 6 | 微信 7 | 8 | ### 所有脚本开源地址,欢迎 star ⭐ 9 | 10 | - gitee:[https://gitee.com/Kaiter-Plus/TampermonkeyScript](https://gitee.com/Kaiter-Plus/TampermonkeyScript) 11 | - github:[https://github.com/Kaiter-Plus/TampermonkeyScript](https://github.com/Kaiter-Plus/TampermonkeyScript) 12 | 13 | ## 1 痛点分析 14 | 15 | - 每次打开 COCO 漫画的 “我的收藏” 界面,看一下有什么漫画更新了,但是每次都要自己找最新的日期看,太麻烦了 16 | 17 | ## 2 功能介绍 18 | 19 | - 直接给在 “我的收藏” 界面添加了按更新时间排序的功能,当然如果有多页看完请手动下一页,脚本只是在当前页面排序功能,不会访问其它页 20 | 21 | ## 3 更新记录 22 | 23 | - 2024/07/12 修复脚本图标不显示 24 | - 2023/10/07 COCO 漫画域名更新 25 | - 2021/10/31 COCO 漫画域名更新 26 | - 2021/03/04 更新访问过的最新标题为黑色,不用自己记有没有访问过了 27 | - 2021/03/03 最新的更新标题标为红色,更加显眼 28 | - 2021/03/02 保留表格标题 29 | - 2021/03/01 COCO 漫画 我的收藏 界面根据 更新日进行排序 30 | -------------------------------------------------------------------------------- /packages/cocomanga-subscription-sort/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cocomanga-subscription-sort", 3 | "version": "0.8.0", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "description": "COCO 漫画“我的收藏”界面根据“更新日”进行排序", 7 | "repository": { 8 | "url": "https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/packages/cocomanga-subscription-sort" 9 | }, 10 | "license": "BSD-3-Clause", 11 | "buildOptions": { 12 | "name": { 13 | "default": "COCO漫画收藏按更新时间排序" 14 | }, 15 | "spaces": 12, 16 | "payload": { 17 | "icon": [ 18 | "https://www.colamanga.com/favicon.ico" 19 | ], 20 | "match": [ 21 | "*://*.cocomanhua.com/dynamic/user/subscription", 22 | "*://*.cocomanga.com/dynamic/user/subscription", 23 | "*://*.colamanhua.com/dynamic/user/subscription", 24 | "*://*.colamanga.com/dynamic/user/subscription" 25 | ], 26 | "run-at": [ 27 | "document-end" 28 | ], 29 | "grant": [ 30 | "GM_addStyle" 31 | ] 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /packages/cocomanga-subscription-sort/src/index.ts: -------------------------------------------------------------------------------- 1 | 2 | const container: Element = document.getElementsByClassName('fed-user-list fed-part-rows fed-back-whits')[0] 3 | const all: HTMLCollectionOf = document.getElementsByClassName('fed-padding-x fed-part-rows fed-line-top') 4 | // 实现排序 5 | container.innerHTML = 6 | document.getElementsByClassName('fed-padding-x fed-part-rows')[0].outerHTML + 7 | Array.from(all) 8 | .sort((a, b) => getDateTime(b) - getDateTime(a)) 9 | .map(item => item.outerHTML) 10 | .join('') 11 | 12 | // 添加最新更新样式 13 | GM_addStyle(` 14 | .lastUpdate a { 15 | color: red; 16 | } 17 | .lastUpdate a:visited { 18 | color: #000; 19 | } 20 | .lastUpdate a:hover { 21 | color: #27ae60; 22 | } 23 | `) 24 | 25 | // 获取更新时间戳 26 | function getDateTime(DOM: Element) { 27 | const updateTime = new Date(DOM.children[0].children[3].innerHTML).getTime() 28 | if (new Date(updateTime).toLocaleDateString() === new Date().toLocaleDateString()) { 29 | DOM.classList.add('lastUpdate') 30 | } 31 | return updateTime 32 | } -------------------------------------------------------------------------------- /packages/douyin-live-auto-click-like/README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | ### 支持作者 4 | 5 | ![支付宝](https://greasyfork.s3.us-east-2.amazonaws.com/lg94h87tgo1nuetf5n2fuhvloa2s) 6 | 微信 7 | 8 | ### 所有脚本开源地址,欢迎 star ⭐ 9 | 10 | - gitee:[https://gitee.com/Kaiter-Plus/TampermonkeyScript](https://gitee.com/Kaiter-Plus/TampermonkeyScript) 11 | - github:[https://github.com/Kaiter-Plus/TampermonkeyScript](https://github.com/Kaiter-Plus/TampermonkeyScript) 12 | 13 | # !!注意!! 14 | 15 | - 本脚本仅供学习交流使用,请勿用于非法用途! 16 | - 使用本脚本用于非法用途后果自负! 17 | - 请于下载后 24 小时内删除! 18 | - 作者本人不负任何法律责任! 19 | 20 | ## 1 脚本介绍 21 | 22 | 最近网页版的抖音直播终于添加了点赞功能,手动点赞太伤鼠标了。所以写了该脚本实现自动点赞。 23 | 24 | ## 更新日志 25 | 26 | - 2023/11/27 修复【手速太快】提示移除失败的 bug 27 | - 2023/11/25 修复脚本失效的问题 28 | - 2023/10/07 修复【手速太快】提示移除失败的 bug 29 | - 2023/06/09 修复功能关闭之后刷新页面还是自动点赞的 bug 30 | - 2023/06/02 添加脚本开关菜单 31 | - 2023/06/01 修复 TamperMonkey 无法使用的 bug 32 | - 2023/05/31 优化显示,在左上角显示点赞效果 33 | - 2023/05/30 代码优化,移除【您手速太快了,请休息一下】提示 34 | - 2023/05/29 解决官方没有优化,点赞太多,元素不会自动清理导致浏览器卡顿的问题 35 | - 2023/05/28 抖音直播自动点赞功能 36 | -------------------------------------------------------------------------------- /packages/douyin-live-auto-click-like/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "douyin-live-auto-click-like", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "description": "网页版抖音直播添加自动点赞功能", 7 | "repository": { 8 | "url": "https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/packages/douyin-live-auto-click-like" 9 | }, 10 | "license": "BSD-3-Clause", 11 | "buildOptions": { 12 | "name": { 13 | "default": "抖音直播自动点赞" 14 | }, 15 | "spaces": 12, 16 | "payload": { 17 | "icon": [ 18 | "https://lf1-cdn-tos.bytegoofy.com/goofy/ies/douyin_web/public/favicon.ico" 19 | ], 20 | "match": [ 21 | "*://live.douyin.com/*" 22 | ], 23 | "run-at": [ 24 | "document-end" 25 | ], 26 | "grant": [ 27 | "unsafeWindow", 28 | "GM_getValue", 29 | "GM_setValue", 30 | "GM_notification", 31 | "GM_registerMenuCommand", 32 | "GM_unregisterMenuCommand" 33 | ], 34 | "noframes": [ 35 | "" 36 | ] 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /packages/douyin-live-auto-click-like/src/index.ts: -------------------------------------------------------------------------------- 1 | // 多久点击一次 2 | const CLICK_DURATION: number = 300 3 | // 点击层的类名 4 | const CLICK_MODAL_CLASS: string = '.LO5TGkc0' 5 | // 点击事件层 6 | let clickModal = document.querySelector(CLICK_MODAL_CLASS) 7 | // 定时器 8 | let timer: number | null = null 9 | // 重新恢复点赞的定时器 10 | let restartTimer: number | null = null 11 | // 重新开始点赞的时间 12 | let restartTimestamp: number = GM_getValue('restartTimestamp') ? Number(GM_getValue('restartTimestamp')) : 0 13 | 14 | // 循环点击 15 | let prevTImestamp: number = 0 // 记录上一次执行的时间 16 | function autoClick(timestamp: number) { 17 | const duration = timestamp - prevTImestamp 18 | if (duration >= CLICK_DURATION + Math.random() * 100 - 50) { 19 | if (clickModal) { 20 | clearLikeIcon() 21 | // 获取元素的坐标 22 | const rect = clickModal.getBoundingClientRect() 23 | const x = rect.top + Math.random() * 50 + 50 24 | const y = rect.left + Math.random() * 50 + 50 25 | // 创建模拟点击事件 26 | const clickEvent = new MouseEvent('click', { 27 | view: unsafeWindow, 28 | bubbles: true, 29 | cancelable: true, 30 | clientX: x, 31 | clientY: y 32 | }) 33 | // 触发模拟点击事件 34 | clickModal.dispatchEvent(clickEvent) 35 | } else { 36 | clickModal = document.querySelector(CLICK_MODAL_CLASS) 37 | } 38 | prevTImestamp = timestamp 39 | } 40 | timer = requestAnimationFrame(autoClick) 41 | } 42 | 43 | // 自动清理点赞之后留下的元素(抖音前端工程师长点心吧!无限添加元素,想卡死用户是吧!不会复用元素?) 44 | function clearLikeIcon() { 45 | if (clickModal!.children.length > 30) { 46 | clickModal!.textContent = '' 47 | } 48 | } 49 | 50 | // 如果已经提示【手速太快】,暂停 1 分钟再重新开始 51 | let prevRestartTimestamp = 0 52 | function restart(timestamp: number) { 53 | cancelAnimationFrame(timer!) 54 | const duration = timestamp - prevRestartTimestamp 55 | if (duration >= CLICK_DURATION) { 56 | const currentTimestamp = +new Date() 57 | if (currentTimestamp >= restartTimestamp) { 58 | if (GM_getValue('switch')) { 59 | timer = requestAnimationFrame(autoClick) 60 | restartTimer = null 61 | return 62 | } 63 | } 64 | prevRestartTimestamp = timestamp 65 | } 66 | restartTimer = requestAnimationFrame(restart) 67 | } 68 | 69 | // 移除【您手速太快了,请休息一下】提示 70 | let prevRemoveTipTimestamp = 0 71 | function removeTip(timestamp: number) { 72 | const duration = timestamp - prevRemoveTipTimestamp 73 | if (duration >= CLICK_DURATION) { 74 | const reg = /.*手速太快.*/ 75 | const toastContainer = document.getElementById('toastContainer') 76 | if (toastContainer) { 77 | if (toastContainer.children[0]) { 78 | toastContainer.textContent = `` 79 | if (!restartTimer) { 80 | const nextTimestamp = +new Date() + 60000 81 | restartTimestamp = nextTimestamp - restartTimestamp > 60000 ? nextTimestamp : restartTimestamp 82 | GM_setValue('restartTimestamp', restartTimestamp) 83 | restart(timestamp) 84 | } 85 | } 86 | } 87 | const toast = document.querySelector('[data-e2e="toast"]') 88 | if (toast && reg.test(toast.textContent!)) { 89 | toast.parentNode?.removeChild(toast) 90 | if (!restartTimer) { 91 | const nextTimestamp = +new Date() + 60000 92 | restartTimestamp = nextTimestamp - restartTimestamp > 60000 ? nextTimestamp : restartTimestamp 93 | GM_setValue('restartTimestamp', restartTimestamp) 94 | restart(timestamp) 95 | } 96 | } 97 | prevRemoveTipTimestamp = timestamp 98 | } 99 | requestAnimationFrame(removeTip) 100 | } 101 | 102 | interface Tip { 103 | open: string 104 | close: string 105 | } 106 | 107 | interface MenuItem { 108 | key: string 109 | name: string 110 | value: boolean 111 | showNotification: boolean 112 | tip: Tip 113 | click: () => void 114 | } 115 | 116 | // 菜单 117 | const menu: MenuItem[] = [ 118 | { 119 | key: 'switch', 120 | name: '自动点赞', 121 | value: true, 122 | showNotification: true, 123 | tip: { 124 | open: '✅', 125 | close: '❌' 126 | }, 127 | click: switchFn 128 | } 129 | ] 130 | 131 | // 保存已注册的菜单 132 | const menuRegister: number[] = [] 133 | 134 | // 配置默认菜单 135 | menu.forEach(v => { 136 | if (GM_getValue(v.key) === undefined || GM_getValue(v.key) === null) GM_setValue(v.key, v.value) 137 | }) 138 | 139 | // 注册菜单 140 | function registerMenuCommand() { 141 | if (menuRegister.length === menu.length) { 142 | menuRegister.forEach(v => { 143 | GM_unregisterMenuCommand(v) 144 | }) 145 | } 146 | menu.forEach((v, i) => { 147 | v.value = GM_getValue(v.key) 148 | menuRegister[i] = GM_registerMenuCommand(`${v.value ? v.tip.open : v.tip.close} ${v.name}`, () => { 149 | menuSwitch(v) 150 | }) 151 | }) 152 | } 153 | 154 | // 切换菜单 155 | function menuSwitch(item: MenuItem) { 156 | // 设置数据 157 | item.value = !item.value 158 | GM_setValue(item.key, item.value) 159 | // 系统通知 160 | if (item.showNotification) { 161 | GM_notification({ 162 | text: `已${item.value ? item.tip.open : item.tip.close}[${item.name}] 功能`, 163 | title: '抖音自动点赞', 164 | timeout: 1000 165 | }) 166 | } 167 | // 如果有点击事件,执行 168 | if (item.click) item.click() 169 | // 重新注册 170 | registerMenuCommand() 171 | } 172 | 173 | // 切换开关 174 | function switchFn() { 175 | if (GM_getValue('switch')) timer = requestAnimationFrame(autoClick) 176 | else cancelAnimationFrame(timer!) 177 | } 178 | 179 | function init() { 180 | clickModal = document.querySelector(CLICK_MODAL_CLASS) 181 | registerMenuCommand() 182 | requestAnimationFrame(removeTip) 183 | if (GM_getValue('switch')) timer = requestAnimationFrame(autoClick) 184 | } 185 | 186 | // 延迟 3 秒开始,抖音需要获取登录数据 187 | setTimeout(() => { 188 | init() 189 | }, 3000) -------------------------------------------------------------------------------- /packages/mooc-skip-questions/README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | ### 所有脚本开源地址,欢迎 star ⭐ 4 | 5 | - gitee:[https://gitee.com/Kaiter-Plus/TampermonkeyScript](https://gitee.com/Kaiter-Plus/TampermonkeyScript) 6 | - github:[https://github.com/Kaiter-Plus/TampermonkeyScript](https://github.com/Kaiter-Plus/TampermonkeyScript) 7 | 8 | # !!注意!! 9 | 10 | - 本脚本仅供学习使用,请勿用于非法用途! 11 | - 使用本脚本用于非法用途后果自负! 12 | - 请于下载后 24 小时内删除! 13 | 14 | ## 功能介绍 15 | 16 | - 中国大学 MOOC,icourse163 视频中题目自动跳过,移除弹题元素,防止暂停 17 | -------------------------------------------------------------------------------- /packages/mooc-skip-questions/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mooc-skip-questions", 3 | "version": "0.1.0", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "description": "中国大学MOOC,icourse163视频中题目自动跳过,移除弹题元素,防止暂停(本脚本仅供学习使用,请在24小时内删除!)", 7 | "repository": { 8 | "url": "https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/packages/mooc-skip-questions" 9 | }, 10 | "license": "BSD-3-Clause", 11 | "buildOptions": { 12 | "name": { 13 | "default": "中国大学MOOC视频中题目自动跳过" 14 | }, 15 | "spaces": 12, 16 | "payload": { 17 | "match": [ 18 | "*://www.icourse163.org/learn/*" 19 | ], 20 | "grant": [ 21 | "none" 22 | ] 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /packages/mooc-skip-questions/src/index.ts: -------------------------------------------------------------------------------- 1 | setInterval(function () { 2 | let question = document.querySelector('.u-btn.u-btn-default.cont.j-continue') 3 | if (question) { 4 | (question.parentNode as HTMLElement)?.remove() 5 | } 6 | let video = document.querySelector('video') 7 | if (video?.paused) { 8 | video.play() 9 | } 10 | }, 5000) -------------------------------------------------------------------------------- /packages/tencent-kt-box/README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 3 | ### 所有脚本开源地址,欢迎 star ⭐ 4 | 5 | - gitee:[https://gitee.com/Kaiter-Plus/TampermonkeyScript](https://gitee.com/Kaiter-Plus/TampermonkeyScript) 6 | - github:[https://github.com/Kaiter-Plus/TampermonkeyScript](https://github.com/Kaiter-Plus/TampermonkeyScript) 7 | 8 | ## 1 脚本介绍 9 | 10 | - 腾讯课堂自动签到以及去除“xxx 正在观看 xx”水印! 11 | 12 | ## 2 更新日志 13 | 14 | - 2020/03/26 去除腾讯课堂“xxx 正在观看 xx”的水印,提高学习效率! 15 | - 2020/03/31 增加自动签到功能!避免学习被打扰! 16 | - 2020/04/11 添加自动签到开关按钮,默认打开,不用可以关闭,节约内存! 17 | - 2020/04/13 修改命名空间,预防 Bug! 18 | - 2020/04/17 修复开关按钮挡住“分享”的 bug 19 | - 2020/04/17 紧急修复自动签到不能使用的 bug 20 | - 2020/04/21 最近腾讯课堂又更新了,自动签到暂时不能用,先下架功能研究一下,后期完善再上架 21 | - 2020/04/21 脚本重新加入了自动签到功能,但是没有课堂可以测试,希望可以帮忙测试之后,反馈一下 22 | - 2020/04/22 添加自动签到如果成功会弹框提示,没有弹框提示则没有签到 23 | - 2020/04/23 修改签到成功提示在自动签到开关的左边进行显示 24 | - 2020/05/07 修复可能不会点击确定按钮的 Bug 25 | -------------------------------------------------------------------------------- /packages/tencent-kt-box/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tencent-kt-box", 3 | "version": "1.4.5", 4 | "type": "module", 5 | "author": "Kaiter-Plus", 6 | "description": "主要功能是腾讯课堂自动签到以及去除“xxx正在观看xx”水印!", 7 | "repository": { 8 | "url": "https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/packages/tencent-kt-box" 9 | }, 10 | "license": "BSD-3-Clause", 11 | "buildOptions": { 12 | "name": { 13 | "default": "腾讯课堂自动签到 + 去除“xxx正在观看xx”水印" 14 | }, 15 | "spaces": 12, 16 | "icon": [ 17 | "https://8.url.cn/edu/edu_modules/edu-ui/img/nohash/favicon.ico" 18 | ], 19 | "payload": { 20 | "match": [ 21 | "https://ke.qq.com/webcourse/*" 22 | ], 23 | "grant": [ 24 | "GM_addStyle", 25 | "GM_addElement" 26 | ] 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /packages/tencent-kt-box/src/index.ts: -------------------------------------------------------------------------------- 1 | // 签到成功次数 2 | let count = 0 3 | 4 | //去除水印, 添加开关样式 5 | GM_addStyle( 6 | [ 7 | "a[class*='marquee animation'],txpdiv[class*='player-inject'],.switchButton-checkbox {", 8 | ' display: none!important;', 9 | '}', 10 | '/* 开关 */', 11 | '.switchButton {', 12 | ' position: relative;', 13 | ' width: 90px;', 14 | ' margin: 15px 514.33px 15px auto;', 15 | ' z-index: 9999;', 16 | ' user-select: none;', 17 | ' -webkit-user-select: none;', 18 | ' -moz-user-select: none;', 19 | ' -ms-user-select: none;', 20 | '}', 21 | '.switchButton::before {', 22 | ' display: block;', 23 | " content: '自动签到开关';", 24 | ' color: #aaa;', 25 | ' font-size: 18px;', 26 | ' line-height: 33px;', 27 | ' position: absolute;', 28 | ' left: -115px;', 29 | '}', 30 | '.switchButton-label {', 31 | ' display: block;', 32 | ' overflow: hidden;', 33 | ' cursor: pointer;', 34 | ' border: 2px solid #999999;', 35 | ' border-radius: 20px;', 36 | '}', 37 | '.switchButton-inner {', 38 | ' display: block;', 39 | ' width: 200%;', 40 | ' margin-left: -100%;', 41 | ' transition: margin 0.3s ease-in 0s;', 42 | '}', 43 | '.switchButton-inner::before,', 44 | '.switchButton-inner::after {', 45 | ' display: block;', 46 | ' float: right;', 47 | ' width: 50%;', 48 | ' height: 30px;', 49 | ' padding: 0;', 50 | ' line-height: 30px;', 51 | ' font-size: 14px;', 52 | ' color: white;', 53 | ' font-family: Trebuchet, Arial, sans-serif;', 54 | ' font-weight: bold;', 55 | ' box-sizing: border-box;', 56 | '}', 57 | '.switchButton-inner::after {', 58 | ' content: attr(data-on);', 59 | ' padding-left: 10px;', 60 | ' background-color: #23b8ff;', 61 | ' color: #FFFFFF;', 62 | '}', 63 | '.switchButton-inner::before {', 64 | ' content: attr(data-off);', 65 | ' padding-right: 10px;', 66 | ' background-color: ##1d1d1d;', 67 | ' color: #FFFFFF;', 68 | ' text-align: right;', 69 | '}', 70 | '.switchButton-switch {', 71 | ' position: absolute;', 72 | ' display: block;', 73 | ' width: 26px;', 74 | ' height: 26px;', 75 | ' margin: 4px;', 76 | ' background: #FFFFFF;', 77 | ' top: 0;', 78 | ' bottom: 0;', 79 | ' right: 56px;', 80 | ' border: 2px solid #999999;', 81 | ' border-radius: 20px;', 82 | ' transition: all 0.3s ease-in 0s;', 83 | '}', 84 | '.switchButton-checkbox:checked+.switchButton-label .switchButton-inner {', 85 | ' margin-left: 0;', 86 | '}', 87 | '.switchButton-checkbox:checked+.switchButton-label .switchButton-switch {', 88 | ' right: 0px;', 89 | '}', 90 | '.myTips {', 91 | ' display: none;', 92 | ' position: absolute;', 93 | ' font-size: 18px;', 94 | ' line-height: 33px;', 95 | ' color: #aaa;', 96 | ' left: -270px;', 97 | ' top: 0;', 98 | '}' 99 | ].join('\n') 100 | ) 101 | 102 | // 创建开关 103 | const switchButton = GM_addElement(document.body, 'div', { 104 | class: 'switchButton' 105 | }) 106 | GM_addElement(switchButton, 'input', { 107 | id: 'ON_OFF', 108 | type: 'checkbox', 109 | checked: true 110 | }) 111 | const label = GM_addElement(switchButton, 'label', { 112 | class: 'switchButton-label', 113 | for: 'ON_OFF' 114 | }) 115 | GM_addElement(label, 'span', { 116 | class: 'switchButton-inner', 117 | 'data-on': 'ON', 118 | 'data-off': 'OFF' 119 | }) 120 | GM_addElement(label, 'span', { 121 | class: 'switchButton-switch' 122 | }) 123 | 124 | 125 | // 签到成功提示 126 | const tips = GM_addElement(switchButton, 'div', { 127 | class: 'myTips' 128 | }) 129 | 130 | // 点击确认按钮 131 | function autoConfirm() { 132 | const confirmButton = document.querySelector('.s-btn.s-btn--primary.s-btn--m') as HTMLElement 133 | try { 134 | if (/确.*定/g.test(confirmButton.innerHTML)) { 135 | confirmButton!.click() 136 | } 137 | } catch (e) { 138 | console.error('点击确定按钮失败,原因: ', e) 139 | } 140 | } 141 | 142 | // 点击签到按钮 143 | function autoSign() { 144 | const signButton = document.querySelector('.s-btn.s-btn--primary.s-btn--m') as HTMLElement 145 | try { 146 | if (/签.*到/g.test(signButton.innerHTML)) { 147 | signButton.click() 148 | count += 1 149 | tips.innerHTML = `签到成功${count}次!` 150 | tips.style.display = `block` 151 | setTimeout(autoConfirm, 2000) 152 | } 153 | } catch (e) { 154 | console.error('点击签到按钮失败,原因: ', e) 155 | } 156 | } 157 | 158 | // 默认开启自动签到 159 | let timer = setInterval(autoSign, 3500) 160 | 161 | // 控制自动签到的开关状态 162 | const switchBtn = document.getElementById('ON_OFF') as HTMLInputElement 163 | switchBtn?.addEventListener('click', () => { 164 | 165 | if (switchBtn.checked) { 166 | // 开启自动签到 167 | timer = setInterval(autoSign, 3500) 168 | } else { 169 | // 关闭自动签到 170 | clearInterval(timer) 171 | } 172 | }) 173 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Enable latest features 4 | "lib": ["ESNext", "DOM"], 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleDetection": "force", 8 | "jsx": "react-jsx", 9 | "allowJs": true, 10 | 11 | // Bundler mode 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "noEmit": true, 16 | 17 | // Best practices 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "noFallthroughCasesInSwitch": true, 21 | 22 | // Some stricter flags (disabled by default) 23 | "noUnusedLocals": false, 24 | "noUnusedParameters": false, 25 | "noPropertyAccessFromIndexSignature": false, 26 | 27 | "baseUrl": ".", 28 | "paths": { 29 | "@kaiter/*": ["packages/*"] 30 | } 31 | } 32 | } 33 | --------------------------------------------------------------------------------