259 lines
7.4 KiB
TypeScript
259 lines
7.4 KiB
TypeScript
import { obfuscator } from './obfuscator'
|
|
import {
|
|
DEBUG,
|
|
NameConfigInstance,
|
|
nameImages,
|
|
usernameExtraSuffix,
|
|
} from './options'
|
|
import { NameDetails, elementTreeFind, innermostElement } from './util'
|
|
|
|
function loadChatMessage(chatboxMessage: Element) {
|
|
// only chat messages
|
|
const chatboxMessageInner = chatboxMessage.querySelector(
|
|
'.chat-line__message'
|
|
)
|
|
if (!chatboxMessageInner) {
|
|
return
|
|
}
|
|
|
|
// get chatbox details
|
|
const chatboxBadgeContainer = chatboxMessage.querySelector<HTMLSpanElement>(
|
|
'.chat-line__message--badges'
|
|
)
|
|
|
|
const chatboxUser = chatboxMessage.querySelector<HTMLSpanElement>(
|
|
'.chat-line__username'
|
|
)
|
|
if (!chatboxUser) {
|
|
console.error("[OBFUSCATOR] found message, couldn't find user")
|
|
return
|
|
}
|
|
|
|
// already applied username
|
|
if (chatboxUser.querySelector('.obf-name')) {
|
|
return
|
|
}
|
|
|
|
const chatboxUserInner = chatboxUser.querySelector<HTMLSpanElement>(
|
|
'.chat-author__display-name'
|
|
)
|
|
if (!chatboxUserInner) {
|
|
console.error("[OBFUSCATOR] found message, couldn't find userInner")
|
|
return
|
|
}
|
|
|
|
// check if mod
|
|
let isMod = false
|
|
if (chatboxBadgeContainer) {
|
|
for (const badge of chatboxBadgeContainer.children) {
|
|
if (
|
|
badge.hasAttribute('data-badge') &&
|
|
(badge.getAttribute('data-badge') === 'moderator' ||
|
|
badge.getAttribute('data-badge') === 'broadcaster')
|
|
) {
|
|
isMod = true
|
|
chatboxMessage.classList.add('ismod')
|
|
}
|
|
}
|
|
}
|
|
|
|
// combine details into object
|
|
const chatMessage: NameDetails = {
|
|
username: chatboxUserInner.textContent,
|
|
isMod,
|
|
}
|
|
|
|
// run main script (process chatMessage), return new ChatMessage
|
|
const newChatMessage = obfuscator(chatMessage)
|
|
|
|
if (newChatMessage !== null) {
|
|
setUsernameDetails(newChatMessage, chatboxUserInner, true)
|
|
}
|
|
|
|
loadReplyLine(chatboxMessage)
|
|
loadMessageMentions(chatboxMessage)
|
|
}
|
|
|
|
function loadReplyLine(chatboxMessage: Element) {
|
|
const replyline = chatboxMessage.querySelector('.ffz--fix-reply-line')
|
|
const replyUsername = replyline?.querySelector<HTMLElement>(
|
|
'p > span:nth-child(1)'
|
|
)
|
|
|
|
// already applied username
|
|
if (!replyUsername || replyUsername.querySelector('.obf-name')) {
|
|
return
|
|
}
|
|
|
|
const chatMessage: NameDetails = {
|
|
username: replyUsername.textContent.replace(/^@/, ''),
|
|
isMod: false,
|
|
}
|
|
|
|
// run main script (process chatMessage), return new ChatMessage
|
|
const newChatMessage = obfuscator(chatMessage)
|
|
|
|
if (newChatMessage !== null) {
|
|
setUsernameDetails(newChatMessage, replyUsername, false, '@')
|
|
}
|
|
}
|
|
|
|
function loadMessageMentions(chatboxMessage: Element) {
|
|
function eachMention(messageMention: HTMLElement) {
|
|
// already applied username
|
|
if (messageMention.querySelector('.obf-name')) {
|
|
return
|
|
}
|
|
|
|
const chatMessage: NameDetails = {
|
|
username: messageMention.textContent.replace(/^@/, ''),
|
|
isMod: false,
|
|
}
|
|
|
|
// run main script (process chatMessage), return new ChatMessage
|
|
const newChatMessage = obfuscator(chatMessage)
|
|
|
|
if (newChatMessage !== null) {
|
|
setUsernameDetails(newChatMessage, messageMention, false, '@')
|
|
}
|
|
}
|
|
|
|
const messageMentions = chatboxMessage.querySelectorAll<HTMLElement>(
|
|
'.chat-line__message-mention'
|
|
)
|
|
|
|
for (const messageMention of messageMentions) {
|
|
eachMention(messageMention)
|
|
}
|
|
}
|
|
|
|
function loadRaidMessage(chatboxMessage: Element) {
|
|
const usernamebox = chatboxMessage.querySelector<HTMLElement>(
|
|
'[data-test-selector="user-notice-line"] div > strong:nth-child(1)'
|
|
)
|
|
|
|
// already applied username
|
|
if (!usernamebox || usernamebox.querySelector('.obf-name')) {
|
|
return
|
|
}
|
|
|
|
const chatMessage: NameDetails = {
|
|
username: usernamebox.textContent,
|
|
isMod: false,
|
|
}
|
|
|
|
// run main script (process chatMessage), return new ChatMessage
|
|
const newChatMessage = obfuscator(chatMessage)
|
|
|
|
if (newChatMessage !== null) {
|
|
setUsernameDetails(newChatMessage, usernamebox)
|
|
}
|
|
}
|
|
|
|
function loadAdditionalUserNames(chatboxMessage: Element) {
|
|
// look for additional chat member names
|
|
const chatterNames =
|
|
chatboxMessage.querySelectorAll<HTMLElement>('.chatter-name')
|
|
|
|
for (const chatterName of chatterNames) {
|
|
const chatterNameBox = innermostElement<HTMLElement, HTMLElement>(
|
|
chatterName
|
|
)
|
|
|
|
// already applied username
|
|
if (chatterNameBox.querySelector('.obf-name')) {
|
|
continue
|
|
}
|
|
|
|
const username = chatterNameBox.textContent
|
|
if (!username) {
|
|
continue
|
|
}
|
|
|
|
// combine details into object
|
|
const chatMessage: NameDetails = {
|
|
username,
|
|
isMod: false,
|
|
}
|
|
|
|
// run main script (process chatMessage), return new ChatMessage
|
|
const newChatMessage = obfuscator(chatMessage)
|
|
|
|
if (newChatMessage !== null) {
|
|
setUsernameDetails(newChatMessage, chatterNameBox)
|
|
}
|
|
}
|
|
}
|
|
|
|
function setUsernameDetails(
|
|
newChatMessage: NameConfigInstance,
|
|
usernamebox: HTMLElement,
|
|
doColor = false,
|
|
prefix: string = ''
|
|
) {
|
|
const suffix = usernameExtraSuffix(newChatMessage)
|
|
const username = `${newChatMessage.username}${suffix}`
|
|
|
|
const container = document.createElement('span')
|
|
container.classList.add('obf-name')
|
|
|
|
const imageName = newChatMessage.image
|
|
if (imageName) {
|
|
// image name
|
|
const image = nameImages[imageName]
|
|
|
|
const imgElem = document.createElement('img')
|
|
imgElem.classList.add('obf-image', 'ffz--pointer-events', 'ffz-tooltip')
|
|
imgElem.setAttribute('data-tooltip-type', 'html')
|
|
imgElem.setAttribute('data-title', username)
|
|
imgElem.setAttribute('alt', username)
|
|
imgElem.setAttribute('src', image)
|
|
|
|
const prefixElem = document.createElement('span')
|
|
prefixElem.textContent = prefix
|
|
|
|
const suffixElem = document.createElement('span')
|
|
suffixElem.textContent = suffix
|
|
|
|
container.replaceChildren(prefixElem, imgElem, suffixElem)
|
|
} else {
|
|
// text name only
|
|
container.textContent = `${prefix}${username}`
|
|
}
|
|
|
|
if (doColor) {
|
|
container.style.color = newChatMessage.color
|
|
}
|
|
|
|
usernamebox.replaceChildren(container)
|
|
}
|
|
|
|
export function eachMutation(record: MutationRecord) {
|
|
const target = record.target as HTMLElement
|
|
if (target.classList.contains('chat-scrollable-area__message-container')) {
|
|
for (const target of record.addedNodes) {
|
|
eachMutationTarget(record, target as HTMLElement)
|
|
}
|
|
} else {
|
|
eachMutationTarget(record, record.target as HTMLElement)
|
|
}
|
|
}
|
|
|
|
function eachMutationTarget(record: MutationRecord, target: HTMLElement) {
|
|
const chatboxMessage = elementTreeFind<HTMLElement, HTMLElement>(
|
|
target,
|
|
elem =>
|
|
elem.parentElement?.classList.contains(
|
|
'chat-scrollable-area__message-container'
|
|
) || false
|
|
)
|
|
if (chatboxMessage) {
|
|
if (DEBUG) {
|
|
console.info('[OBFUSCATOR] mutated message', chatboxMessage, record)
|
|
}
|
|
loadChatMessage(chatboxMessage)
|
|
loadAdditionalUserNames(chatboxMessage)
|
|
loadRaidMessage(chatboxMessage)
|
|
}
|
|
}
|