Skip to content

Commit

Permalink
fix: ws没有重连;ip属地个别页面显示不出来
Browse files Browse the repository at this point in the history
  • Loading branch information
eeelester committed Jan 4, 2025
1 parent 855fa20 commit 24573e0
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 24 deletions.
2 changes: 1 addition & 1 deletion components/ScList/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type propRef = React.MutableRefObject<HTMLDivElement | undefined | null>

function useMove(ref: propRef, scDocument: Document) {
const height = useMemo(() => scDocument.documentElement.clientHeight, [])

Check warning on line 7 in components/ScList/hook.ts

View workflow job for this annotation

GitHub Actions / CI

React Hook useMemo has a missing dependency: 'scDocument.documentElement.clientHeight'. Either include it or remove the dependency array
const [position, setPosition] = useState({ left: 10, bottom: 30, maxHeight: height - 30 })
const [position, setPosition] = useState({ left: 10, bottom: 140, maxHeight: height - 30 })
const movingRef = useRef(false)
const lastPositionRef = useRef<{ lastX: number | null, lastY: number | null }>({ lastX: 0, lastY: 0 })

Expand Down
12 changes: 6 additions & 6 deletions entrypoints/fullScreen.content/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createRoot } from 'react-dom/client'
import type { Root } from 'react-dom/client'
import { LiveWS } from 'bilibili-live-ws'
import { KeepLiveWS } from 'bilibili-live-ws'
import { ALREADY_HAVE_IT } from './const'
import type { DanmuInfo, RoomDetailInfo, RoomInfo } from './types'
import SCList from '@/components/ScList'
Expand All @@ -13,7 +13,7 @@ let isFirst = true
let isMount = false
let isInIframe = false
let root: Root | null
let liveWS: LiveWS | null
let keepLiveWS: KeepLiveWS | null

export let existElement: HTMLElement | null

Check warning on line 18 in entrypoints/fullScreen.content/utils.tsx

View workflow job for this annotation

GitHub Actions / CI

Exporting mutable 'let' binding, use 'const' instead

Expand Down Expand Up @@ -55,8 +55,8 @@ export function unmount(log: string) {
root = null
existElement?.parentNode?.removeChild(existElement)
existElement = null
liveWS?.close()
liveWS = null
keepLiveWS?.close()
keepLiveWS = null
}

// 有时候video在iframe里面,content-script.css的样式没法应用到里面去,所以将其应用到iframe head中
Expand Down Expand Up @@ -116,11 +116,11 @@ async function getInfo() {
const { data: { token } = { token: '' } } = res
return token
})
liveWS = new LiveWS(roomId, {
keepLiveWS = new KeepLiveWS(roomId, {
protover: 3,
key,
})
liveWS.on('SUPER_CHAT_MESSAGE', (res: DanmuDataProps) => {
keepLiveWS.on('SUPER_CHAT_MESSAGE', (res: DanmuDataProps) => {
console.log('SC', res)
processData(res)
})
Expand Down
51 changes: 43 additions & 8 deletions entrypoints/ipLocation.content/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
export default defineContentScript({

Check warning on line 1 in entrypoints/ipLocation.content/index.tsx

View workflow job for this annotation

GitHub Actions / CI

Fast refresh can't handle anonymous components. Add a name to your export
matches: ['https://bilibili.com/*', 'https://*.bilibili.com/*'],
matches: ['https://*.bilibili.com/*'],
runAt: 'document_start',
main() {
const script = document.createElement('script')
// @ts-expect-error: 实际有
script.src = browser.runtime.getURL('bilibili-web-show-ip-location.user.js') // 根据实际路径调整

script.onload = function () {
console.log('Local script loaded successfully!')
script.remove()
// 检查 head 是否已存在
if (document.head) {
initScripts();
return;
}

document.head.appendChild(script)
// 如果 head 还不存在,使用 MutationObserver 监听它的出现
const observer = new MutationObserver((_, obs) => {
if (document.head) {
obs.disconnect(); // 停止观察
initScripts();
}
});

observer.observe(document.documentElement, {
childList: true,
subtree: true
});

function initScripts() {
const proxyScript = document.createElement('script')
// @ts-expect-error: 实际有
proxyScript.src = browser.runtime.getURL('hook-vue3-proxy.js')

proxyScript.onload = function () {
console.log('Local script loaded successfully!')
proxyScript.remove()

const ipScript = document.createElement('script')
// @ts-expect-error: 实际有
ipScript.src = browser.runtime.getURL('bilibili-web-show-ip-location.user.js')

ipScript.onload = function () {
console.log('Local script loaded successfully!')
ipScript.remove()
}

document.head.appendChild(ipScript)

}

document.head.appendChild(proxyScript)
}
},
})
27 changes: 22 additions & 5 deletions public/bilibili-web-show-ip-location.user.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ==UserScript==
// @name 哔哩哔哩网页版显示 IP 属地 B站 Bilibili IP 属地显示
// @namespace http://zhangmaimai.com
// @version 1.6.4
// @version 1.6.5
// @author MaxChang3
// @description 我不喜欢 IP 属地,但是你手机都显示了,为什么电脑不显示呢?显示网页版 B 站 IP 属地,支持大部分场景的评论区
// @license MIT
Expand Down Expand Up @@ -244,12 +244,29 @@
}
});
router.serve("https://www.bilibili.com/v/topic/detail/", () => serveNewComments(".list-view"));
router.serve("https://space.bilibili.com/", () => serveNewComments(".bili-dyn-list__items"), { endsWith: "dynamic" });
router.serve("https://space.bilibili.com/", async () => {
const dynamicTab = await isElementLoaded(".n-dynamic");
dynamicTab.addEventListener("click", () => {
const biliMainHeader = await isElementLoaded("#biliMainHeader");
const isFreshSpaceDynamic = (biliMainHeader == null ? void 0 : biliMainHeader.tagName) === "HEADER";
if (isFreshSpaceDynamic) {
hookLit();
} else {
serveNewComments(".bili-dyn-list__items");
}, { once: true });
}
}, { endsWith: "dynamic" });
router.serve("https://space.bilibili.com/", async () => {
const biliMainHeader = await isElementLoaded("#biliMainHeader");
const isFreshSpaceDynamic = (biliMainHeader == null ? void 0 : biliMainHeader.tagName) === "HEADER";
if (isFreshSpaceDynamic) {
const newDyanmicTab = await isElementLoaded(".nav-tab__item:nth-child(2)");
newDyanmicTab.addEventListener("click", () => {
hookLit();
}, { once: true });
} else {
const oldDynamicTab = await isElementLoaded(".n-dynamic");
oldDynamicTab.addEventListener("click", () => {
serveNewComments(".bili-dyn-list__items");
}, { once: true });
}
});
router.serve("https://t.bilibili.com/", async () => {
const dynHome = await isElementLoaded(".bili-dyn-home--member");
Expand Down
132 changes: 132 additions & 0 deletions public/hook-vue3-proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// ==UserScript==
// @name Hook Vue3 app
// @version 1.0.3
// @description 通过劫持Proxy方法,逆向还原Vue3 app元素到DOM
// @author DreamNya
// @license MIT
// @namespace https://greasyfork.org/users/809466
// ==/UserScript==

const $window = window.unsafeWindow || document.defaultView || window
const realLog = $window.console.log; //反劫持console.log(大部分网站都会劫持console.log)
const realProxy = $window.Proxy; //劫持Proxy

var vueUnhooked = new WeakSet() //以WeakSet存储已获取到但未未劫持的app对象,作为debug用变量,正常情况WeakSet应为空
var vueHooked = new WeakMap() //以WeakMap存储已劫持的app对象,DOM元素为key,app对象为value

$window.Proxy = function () {
let app = arguments[0]._
if (app?.uid >= 0) { //判断app
let el = app.vnode.el
if (el) {
recordVue(el, app) //记录到WeakMap
recordDOM(el, app) //挂载到DOM
watch_isUnmounted(app) //观察销毁
} else {
//realLog(app,el)
vueUnhooked.add(app) //记录未劫持的app
//realLog(vueUnhooked,app)
watchEl(app.vnode) //不存在el则观察el
}
}
return new realProxy(...arguments)
}

function watchEl(vnode) { //观察el 变动时还原到DOM
let value = vnode.el
let hooked = false
Object.defineProperty(vnode, "el", {
get() {
return value
},
set(newValue) {
value = newValue
if (!hooked && this.el) {
hooked = true
recordVue(this.el, this.component)
recordDOM(this.el, this.component)
watch_isUnmounted(this.component)
//realLog(this.component,"已还原")
}
}
})
}

function watch_isUnmounted(app) { //观察isUnmounted 变动时销毁引用
let value = app.isUnmounted
let unhooked = false
Object.defineProperty(app, "isUnmounted", {
get() {
return value
},
set(newValue) {
value = newValue
if (!unhooked && this.isUnmounted) {
unhooked = true
//realLog(this,"已删除")
let el = this.vnode.el
if (el) {
let DOMvalue = el.__vue__ //删除DOMelement.__vue__挂载
if (DOMvalue) {
if (Array.isArray(DOMvalue)) {
let index = DOMvalue.findIndex(i => i == this)
index > -1 && DOMvalue.splice(index, 1)
el.__vue__ = DOMvalue.length > 1 ? DOMvalue : DOMvalue[0]
} else {
if (DOMvalue == this) {
el.__vue__ = void 0
}
}
}
let WMvalue = vueHooked.get(el) //删除WeakMap存储
if (WMvalue) {
if (Array.isArray(WMvalue)) {
let index = WMvalue.findIndex(i => i == this)
index > -1 && WMvalue.splice(index, 1)
vueHooked.set(el, WMvalue.length > 1 ? WMvalue : WMvalue[0])
} else {
if (WMvalue == this) {
vueHooked.delete(el)
}
}
}
}
}
}
})
}

function recordVue(el, app) { //将app记录到WeakMap中
vueUnhooked.delete(app)
if (vueHooked.has(el)) {
let value = vueHooked.get(el)
if (Array.isArray(value)) {
if (value.findIndex(i => i == app) == -1) {
vueHooked.set(el, vueHooked.get(el).push(app))
}
} else {
if (value != app) {
vueHooked.set(el, [value, app])
}
}
} else {
vueHooked.set(el, app)
}
}

function recordDOM(el, app) { //将app挂载到DOMelement.__vue__
if (el.__vue__) {
let value = el.__vue__
if (Array.isArray(value)) {
if (value.findIndex(i => i == app) == -1) {
el.__vue__ = value.push(app)
}
} else {
if (value != app) {
el.__vue__ = [value, app]
}
}
} else {
el.__vue__ = app
}
}
File renamed without changes
Binary file modified public/icons/icon-16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/icons/icon-32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/icons/icon-48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/icons/icon-able-16.png
Binary file not shown.
Binary file removed public/icons/icon-able-32.png
Binary file not shown.
Binary file removed public/icons/icon-able-48.png
Binary file not shown.
Binary file added public/icons/icon-disable-16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/icon-disable-32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/icons/icon-disable-48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions wxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export default defineConfig({
name: 'B站助手,全屏显示SC,评论显示IP属地',
permissions: ['storage'],
icons: {
16: './icons/icon-able-16.png',
32: './icons/icon-able-32.png',
48: './icons/icon-able-48.png',
16: './icons/icon-16.png',
32: './icons/icon-32.png',
48: './icons/icon-48.png',
},
},
runner: {
Expand All @@ -27,7 +27,7 @@ export default defineConfig({
matches: ['https://live.bilibili.com/*'],
},
{
resources: ['bilibili-web-show-ip-location.user.js'],
resources: ['bilibili-web-show-ip-location.user.js', 'hook-vue3-proxy.js'],
matches: ['https://bilibili.com/*', 'https://*.bilibili.com/*'],
},
]
Expand Down

0 comments on commit 24573e0

Please sign in to comment.