import { $, addStyle, DOMUtils, log, utils } from "@/env"; import { DouYinRouter } from "@/router/DouYinRouter"; import { addBlockCSS } from "@components/env.base"; import { Panel } from "@components/setting/panel"; import { DouYinElementUtil } from "../utils/DouYinElementUtil"; export const DouYinAccount = { /** * 伪装登录 */ disguiseLogin() { log.info("伪装登录"); let result: any[] = [ addBlockCSS( // 视频清晰度上面的弹出的 当前观看xxx画质,登录即可畅想xxx画质 ".login-tooltip-slot" ), ]; // DouYinNetWorkHook.hookUserNoLoginResponse(); const WAIT_TIME = 20000; const uid = parseInt((Math.random() * 1e5).toString()); // const uid = 114514; const info = { uid: uid, secUid: "", shortId: parseInt((Math.random() * 1000000000).toString()), realName: "乌萨奇", nickname: "乌萨奇", // 昵称 desc: "除草证3级", // 描述 gender: 0, // 性别 avatarUrl: "https://picshack.net/ib/F9JKlC3yhh.gif", // 头像 avatar300Url: "https://picshack.net/ib/F9JKlC3yhh.gif", followStatus: 0, followerStatus: 0, awemeCount: 0, // 作品数量 watchLaterCount: 0, // 稍后再看数量 followingCount: 0, // 关注 followerCount: 0, followerCountStr: "", mplatformFollowersCount: 9999999, // 粉丝数量 favoritingCount: 0, // 我的喜欢的数量 totalFavorited: 9999999, // 获赞 userCollectCount: { logPb: { impr_id: "", }, collectCountList: [], statusCode: 0, extra: { fatal_item_ids: [], logid: "", now: Date.now(), }, }, uniqueId: "", customVerify: "", generalPermission: { is_hit_active_fans_grayed: false, }, age: new Date().getFullYear() - 2019, // 年龄 country: "", province: "", city: "", district: "", school: "chiikawa", // 学校 schoolVisible: 1, // 控制学校显示 enterpriseVerifyReason: "", secret: 1, userCanceled: false, roomData: {}, shareQrcodeUrl: "", shareInfo: { boolPersist: 1, shareDesc: "长按复制此条消息,打开抖音搜索,查看TA的更多作品。", shareImageUrl: { uri: "", url_list: [], }, shareQrcodeUrl: { uri: "", url_list: [], }, shareUrl: "", shareWeiboDesc: "长按复制此条消息,打开抖音搜索,查看TA的更多作品。", }, coverAndHeadImageInfo: { profileCoverList: [], }, roomId: 0, favoritePermission: 1, viewHistoryPermission: true, isGovMediaVip: false, isStar: false, hideLocation: false, needSpecialShowFollowerCount: false, continuationState: 0, im_role_ids: [], accountCertInfo: {}, close_consecutive_chat: 0, profileRankLabel: null, }; Object.freeze(info); /** * 获取用户信息 * @param $el */ const getUserInfo = function ($el: HTMLElement) { const userInfoList = []; const reactInstance = utils.getReactInstance($el); const reactFiber = reactInstance?.reactFiber; const reactProps = reactInstance?.reactProps; if (reactFiber?.alternate?.return?.memoizedProps?.userInfo) { userInfoList.push(reactFiber?.alternate?.return?.memoizedProps?.userInfo); } if (reactFiber?.alternate?.return?.memoizedProps?.userInfo?.userInfo) { userInfoList.push(reactFiber?.alternate?.return?.memoizedProps?.userInfo.userInfo); } if (reactFiber?.alternate?.return?.return?.memoizedProps?.userInfo) { userInfoList.push(reactFiber?.alternate?.return?.return?.memoizedProps?.userInfo); } if (reactFiber?.alternate?.return?.return?.memoizedProps?.userInfo?.userInfo) { userInfoList.push(reactFiber?.alternate?.return?.return?.memoizedProps?.userInfo.userInfo); } return userInfoList; }; /** * 设置登录 * @param $el */ const setLogin = function ($el: HTMLElement) { getUserInfo($el).forEach((userInfo) => { if (!userInfo.isLogin) { userInfo.info = info; userInfo.isLogin = true; userInfo.statusCode = 0; } }); }; DouYinElementUtil.watchFeedVideoListChange(setLogin); DOMUtils.waitNode("#root div[class*='-os']", WAIT_TIME) .then(() => { const lockFn = new utils.LockFunction(() => { const $os = DouYinElementUtil.selectorRootOSNode(); if (!$os) { return; } setLogin($os); }, 70); const observer = utils.mutationObserver(document.body, { config: { subtree: true, childList: true, }, immediate: true, callback: () => { lockFn.run(); }, }); }) .catch((err) => {}); /* 直播的顶部live */ if (DouYinRouter.isLive()) { log.info("伪装登录:live"); DOMUtils.waitNode(`[id^="douyin-header"] div:has(.dy-tip-container)`, WAIT_TIME).then(() => { const lockFn = new utils.LockFunction(() => { setLogin($(`[id^="douyin-header"]`)!); }, 70); utils.mutationObserver(document.body, { config: { subtree: true, childList: true, }, immediate: true, callback: () => { lockFn.run(); }, }); }); } else if (DouYinRouter.isSearch()) { log.info("伪装登录:search"); /* 搜索 */ function setUserInfoBySearch($ele: HTMLElement) { /* 搜索页面的用户信息 */ const $react = utils.getReactInstance($ele); const reactFiber = $react?.reactFiber; const reactProps = $react?.reactProps; if (typeof reactProps?.children?.[1]?.props?.userInfo?.isLogin === "boolean") { Reflect.set(reactProps.children[1].props.userInfo, "isLogin", true); } if (typeof reactProps?.children?.[1]?.props?.isClient === "boolean") { Reflect.set(reactProps.children[1].props, "isClient", true); } } DOMUtils.waitNode("#root > div", WAIT_TIME).then(($rootDiv) => { if (!$rootDiv) { log.error("#root > div获取失败"); return; } const lockFn = new utils.LockFunction(() => { setUserInfoBySearch($rootDiv); }, 70); utils.mutationObserver(document, { config: { subtree: true, childList: true, }, immediate: true, callback: () => { lockFn.run(); }, }); }); } if (!Panel.getValue("watchLoginDialogToClose")) { // 避免重复 result = result.concat(this.watchLoginDialogToClose()); } result = result.concat(this.watchCommentDialogToClose()); // 清除localStorage的key window.localStorage.removeItem("UNLOGIN_CLARITY_NEW"); window.localStorage.setItem("HasUserLogin", "1"); window.localStorage.setItem( "has_login_show", JSON.stringify({ count: 1, lastTime: Date.now() - 1000 * 60 * 60 * 12, firstTime: Date.now() - 1000 * 60 * 60 * 12, }) ); return result; }, /** * 关闭登录弹窗 */ watchLoginDialogToClose() { log.info("监听登录弹窗并关闭"); const watchLoginDialogToClose = Panel.getDynamicValue("watchLoginDialogToClose"); const disguiseLogin = Panel.getDynamicValue("disguiseLogin"); const lockFn = new utils.LockFunction(() => { if (!watchLoginDialogToClose.value && !disguiseLogin.value) { // 当伪装登录和屏蔽登录弹窗都关闭时,则取消监听 return; } DOMUtils.remove(".douyin_login_iframe:has(iframe)"); const $loginDialog = $('div[id^="login-full-panel-"]'); if ($loginDialog && $loginDialog.children.length) { const $loginDialogCloseBtn = $loginDialog.querySelector(".dy-account-close") || $loginDialog.querySelector( 'div:has(>svg path[d="M12.7929 22.2426C12.4024 22.6331 12.4024 23.2663 12.7929 23.6568C13.1834 24.0474 13.8166 24.0474 14.2071 23.6568L18.5 19.3639L22.7929 23.6568C23.1834 24.0474 23.8166 24.0474 24.2071 23.6568C24.5976 23.2663 24.5976 22.6331 24.2071 22.2426L19.9142 17.9497L24.1066 13.7573C24.4971 13.3668 24.4971 12.7336 24.1066 12.3431C23.7161 11.9526 23.0829 11.9526 22.6924 12.3431L18.5 16.5355L14.3076 12.3431C13.9171 11.9526 13.2839 11.9526 12.8934 12.3431C12.5029 12.7336 12.5029 13.3668 12.8934 13.7573L17.0858 17.9497L12.7929 22.2426Z"])' ); if ($loginDialogCloseBtn) { const reactInst = utils.getReactInstance($loginDialogCloseBtn); const onClick = reactInst?.reactProps?.onClick; if (typeof onClick === "function") { onClick(new Event("click")); log.success(`调用onClick触发关闭弹窗`); } else { log.error("监听到登录弹窗但是关闭失败,原因:未获取到onClick函数"); } } else { const $logPanelNew = $loginDialog.querySelector("#login-panel-new > div"); if (!$logPanelNew || ($logPanelNew && $logPanelNew.children.length)) { log.error( "未找到登录弹出的关闭按钮,此时键盘被聚焦在登录弹窗上从而导致'快捷键'失效", $loginDialog.cloneNode(true) ); } } } const $ohterDialog = $("body > div > div:contains('为保障更好的访问体验,请在登录后继续使用抖音')"); if ($ohterDialog) { const reactInst = utils.getReactInstance($ohterDialog); const onClick = reactInst?.reactProps?.onClick; if (typeof onClick === "function") { onClick(new Event("click")); } else { log.error("监听到【为保障更好的访问体验,请在登录后继续使用抖音】但是关闭失败,原因:未获取到onClick函数"); } } }); const observer = utils.mutationObserver(document, { config: { subtree: true, childList: true, }, immediate: true, callback: () => { lockFn.run(); }, }); return [ addBlockCSS('div[id^="login-full-panel-"]', ".douyin_login_iframe:has(iframe)"), () => { observer.disconnect(); }, watchLoginDialogToClose.destory, disguiseLogin.destory, ]; }, /** * 关闭评论区的登录遮罩层 */ watchCommentDialogToClose() { const lockFn = new utils.LockFunction(() => { // 评论区的登录屏蔽罩 const $cardLoginGuide = $('[id^="related-video-card-login-guide"]'); if (!$cardLoginGuide) { return; } const $close = $cardLoginGuide.querySelector(".related-video-card-login-guide__footer-close"); if (!$close) { log.error("监听到评论区的登录遮罩层但是未获取到关闭按钮"); return; } $close.click(); }); const observer = utils.mutationObserver(document, { config: { subtree: true, childList: true, }, immediate: true, callback: () => { lockFn.run(); }, }); return [ addBlockCSS('[id^="related-video-card-login-guide"]'), addStyle(/*css*/ ` /* 去除遮罩层 */ [id^="related-video-card-login-guide"]+div{ filter: none !important; } `), () => { observer?.disconnect(); }, ]; }, };