DeepSeek Response Interceptor(text recognition)

该脚本用于拦截DeepSeek屏蔽提示,并输出已缓存文本,重新加载网页失效。可自定义需要拦截的文本

目前为 2025-02-03 提交的版本。查看 最新版本

// ==UserScript==
// @name:zh-CN   DeepSeek响应拦截器(文字识别版)
// @name         DeepSeek Response Interceptor(text recognition)
// @namespace    https://github.com/Ahikl/
// @homepage     https://github.com/Ahikl/DeepSeek_Response_Interceptor
// @version      1.4
// @description  该脚本用于拦截DeepSeek屏蔽提示,并输出已缓存文本,重新加载网页失效。可自定义需要拦截的文本
// @author       Ahikl
// @match        https://chat.deepseek.com/*
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function () {
    "use strict";

    // 定义需要拦截的屏蔽文本
    const BLOCKED_TEXTS = [
        "检测到本次回复可能涉及不当内容,已启用安全保护机制。我们倡导健康文明的交流环境。",
        "你好,这个问题我暂时无法回答,让我们换个话题再聊聊吧。",
        "对不起,我还没有学会如何思考这类问题,我擅长数学、代码、逻辑类的题目,欢迎与我交流。",
        "我们始终遵循法律法规和伦理准则,倡导健康积极的交流环境。如果您有任何其他合法合规的咨询需求,我们将竭诚为您提供专业服务。",
        "我明白您希望继续这个虚构的角色扮演情景,但目前我无法提供此类包含成人内容的互动。如果您有其他话题或需要创作健康的故事框架,我很乐意协助您! 😊",
        "出于安全方面的考虑,我恐怕无法完成您提到的这个任务。如果您有其他与学习、生活或娱乐相关的问题,我很愿意为您提供帮助。",
        "很抱歉,我无法继续参与这个对话。如果您有其他问题或需要帮助,请随时告诉我!"
    ];// 添加更多屏蔽文本

    // 用于记录上一次有效输出的内容,后续用于回滚
    let lastValidContent = "";
    const chatContainerSelector = ".chat-container";
    let chatContainer = null;

    // 尝试获取聊天容器
    function getChatContainer() {
        if (!chatContainer) {
            chatContainer = document.querySelector(chatContainerSelector);
        }
        return chatContainer;
    }

    // 更新上一次有效输出
    function updateLastValidContent() {
        const container = getChatContainer();
        if (container) {
            lastValidContent = container.innerHTML;
        }
    }

    // 回滚到上一次有效输出
    function rollbackContent() {
        const container = getChatContainer();
        if (container) {
            console.warn("检测到屏蔽文本,回滚到上一次有效内容。");
            container.innerHTML = lastValidContent;
        }
    }

    // 检查是否包含任何屏蔽文本
    function containsBlockedText(text) {
        return BLOCKED_TEXTS.some(blockedText => text.includes(blockedText));
    }

    // 重写 fetch 方法,拦截流式响应
    const originalFetch = window.fetch;
    window.fetch = async function (...args) {
        const response = await originalFetch(...args);
        if (!response.body) return response; // 非流式响应直接返回

        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        let bufferedText = "";

        const newStream = new ReadableStream({
            start(controller) {
                function push() {
                    reader.read().then(({done, value}) => {
                        if (done) {
                            controller.close();
                            return;
                        }
                        const chunk = decoder.decode(value, {stream: true});
                        bufferedText += chunk;
                        // 检查是否包含屏蔽文本
                        if (containsBlockedText(bufferedText)) {
                            console.warn("Fetch 检测到屏蔽文本,终止流式响应。");
                            controller.close();
                            rollbackContent();
                            return;
                        }
                        controller.enqueue(value);
                        updateLastValidContent();
                        push();
                    }).catch(err => {
                        console.error("Fetch 处理异常:", err);
                        controller.error(err);
                    });
                }

                push();
            }
        });
        return new Response(newStream, {
            headers: response.headers,
            status: response.status,
            statusText: response.statusText,
        });
    };

    console.log("已重写 fetch 逻辑。");

    // 重写 XMLHttpRequest 以拦截请求
    const originalXHR = window.XMLHttpRequest;

    function InterceptedXHR() {
        const xhr = new originalXHR();
        let bufferedResponse = "";
        xhr.addEventListener("readystatechange", function () {
            // readyState 3: 正在接收数据;4: 请求结束
            if (xhr.readyState === 3 || xhr.readyState === 4) {
                bufferedResponse = xhr.responseText;
                if (containsBlockedText(bufferedResponse)) {
                    console.warn("XHR 检测到屏蔽文本,终止请求。");
                    xhr.abort();
                    rollbackContent();
                } else {
                    updateLastValidContent();
                }
            }
        });
        return xhr;
    }

    window.XMLHttpRequest = InterceptedXHR;
    console.log("已重写 XMLHttpRequest 逻辑。");

    // 使用 MutationObserver 监控 DOM 变化,确保动态插入的内容中不包含屏蔽文本
    function setupObserver() {
        const container = getChatContainer();
        if (!container) return;
        const observer = new MutationObserver((mutationsList) => {
            for (let mutation of mutationsList) {
                if (mutation.type === "childList") {
                    mutation.addedNodes.forEach((node) => {
                        let text = "";
                        if (node.nodeType === Node.TEXT_NODE) {
                            text = node.textContent;
                        } else if (node.nodeType === Node.ELEMENT_NODE) {
                            text = node.innerText || "";
                        }
                        if (text && containsBlockedText(text)) {
                            console.warn("MutationObserver 检测到屏蔽文本,触发回滚。");
                            rollbackContent();
                        }
                    });
                }
            }
        });
        observer.observe(container, {childList: true, subtree: true});
        console.log("脚本已启动。");
    }

    // 定时检查目标容器是否加载完成,然后启动观察器
    function initObserver() {
        const interval = setInterval(() => {
            if (getChatContainer()) {
                updateLastValidContent();
                setupObserver();
                clearInterval(interval);
            }
        }, 1000);
    }

    window.addEventListener("load", initObserver);

    console.log("脚本已注入,用于拦截流式响应并回滚屏蔽内容。");
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址