Bilibili 直播自动点赞

网页版 Bilibili 直播添加自动点赞功能

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Bilibili 直播自动点赞
// @namespace   https://gitee.com/Kaiter-Plus/TampermonkeyScript/tree/master/bilibili-live-auto-like
// @author      Kaiter-Plus
// @description 网页版 Bilibili 直播添加自动点赞功能
// @version     1.00
// @license     BSD-3-Clause
// @match       *://live.bilibili.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=bilibili.com
// @noframes
// @run-at      document-end
// @grant       unsafeWindow
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_notification
// @grant       GM_registerMenuCommand
// @grant       GM_unregisterMenuCommand
// ==/UserScript==

;(() => {
  // 多久点击一次
  const CLICK_DURATION = 300
  // 点击层的类名
  const CLICK_MODAL_CLASS = '.like-btn'
  // 点击事件层
  let clickModal = document.querySelector(CLICK_MODAL_CLASS)
  // 定时器
  let timer = null

  // 循环点击
  let prevTImestamp = 0 // 记录上一次执行的时间
  function autoClick(timestamp) {
    const duration = timestamp - prevTImestamp
    if (duration >= CLICK_DURATION + Math.random() * 100 - 50) {
      if (clickModal) {
        // 获取元素的坐标
        const rect = clickModal.getBoundingClientRect()
        const x = rect.top + Math.random() * 50 + 50
        const y = rect.left + Math.random() * 50 + 50
        // 创建模拟点击事件
        const clickEvent = new MouseEvent('click', {
          view: unsafeWindow,
          bubbles: true,
          cancelable: true,
          clientX: x,
          clientY: y
        })
        // 触发模拟点击事件
        clickModal.dispatchEvent(clickEvent)
      } else {
        clickModal = document.querySelector(CLICK_MODAL_CLASS)
      }
      prevTImestamp = timestamp
    }
    timer = requestAnimationFrame(autoClick)
  }

  // 菜单
  const menu = [
    {
      key: 'switch',
      name: '自动点赞',
      value: true,
      showNotification: true,
      tip: {
        open: '✅',
        close: '❌'
      },
      click: switchFn
    }
  ]

  // 保存已注册的菜单
  const menuRegister = []

  // 配置默认菜单
  menu.forEach(v => {
    if (GM_getValue(v.key) === undefined || GM_getValue(v.key) === null) GM_setValue(v.key, v.value)
  })

  // 注册菜单
  function registerMenuCommand() {
    if (menuRegister.length === menu.length) {
      menuRegister.forEach(v => {
        GM_unregisterMenuCommand(v)
      })
    }
    menu.forEach((v, i) => {
      v.value = GM_getValue(v.key)
      menuRegister[i] = GM_registerMenuCommand(`${v.value ? v.tip.open : v.tip.close} ${v.name}`, () => {
        menuSwitch(v)
      })
    })
  }

  // 切换菜单
  function menuSwitch(item) {
    // 设置数据
    item.value = !item.value
    GM_setValue(item.key, item.value)
    // 系统通知
    if (item.showNotification) {
      GM_notification({
        text: `已${item.value ? item.tip.open : item.tip.close}[${item.name}] 功能`,
        title: ' Bilibili 自动点赞',
        timeout: 1000
      })
    }
    // 如果有点击事件,执行
    if (item.click) item.click()
    // 重新注册
    registerMenuCommand()
  }

  // 切换开关
  function switchFn() {
    if (GM_getValue('switch')) timer = requestAnimationFrame(autoClick)
    else cancelAnimationFrame(timer)
  }

  function init() {
    clickModal = document.querySelector(CLICK_MODAL_CLASS)
    registerMenuCommand()
    if (GM_getValue('switch')) timer = requestAnimationFrame(autoClick)
  }

  // 延迟 3 秒开始, 获取必要数据
  setTimeout(() => {
    init()
  }, 3000)
})()