Greasy Fork

Greasy Fork is available in English.

chatv4

chatv4test

当前为 2025-06-14 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/539361/1607387/chatv4.js

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

Tabs.Chat = {
    tabOrder: 900,
    tabLabel: 'Chat',
    tabDisabled: false,
    myDiv: null,
    chatDiv: null,
    inputDiv: null,
    controlsDiv: null,
    currentChatType: 'global',
    originalInputContainer: null,
    originalControlsContainer: null,

    init: function (div) {
        var t = Tabs.Chat;
        t.myDiv = div;
        t.createMainDiv();
        t.hookGameChat();
        t.setupChatTabs();
    },

    createMainDiv: function () {
        var t = Tabs.Chat;
        var m = '<DIV class=divHeader align=center>CHAT</div>';

        // Create tab buttons similar to the game's interface
        m += '<div style="background-color:#e8d6b0; padding:5px; border-bottom:1px solid #886;">';
        m += '<button id="pbGlobalChatTab" class="tab selected" style="margin-right:5px;">Global Chat</button>';
        m += '<button id="pbAllianceChatTab" class="tab">Alliance Chat</button>';
        m += '</div>';

        // Chat content area
        m += '<div id="pbChatContent" style="height:380px; overflow-y:auto; background-color:#f9f2dd; padding:5px;"></div>';
        
        // Chat rules
        m += '<div id="pbChatRules" style="padding:5px; background-color:#f9f2dd; border-top:1px solid #886;">';
        m += 'Chat Rules: No bad language. No personal attacks. No links. Use /username to whisper to another player. Respect the mods and each other and most importantly, have fun!';
        m += '</div>';
        
        // Chat input area - we'll move the actual game input here
        m += '<div id="pbChatInput" style="padding:5px; background-color:#e8d6b0;"></div>';
        
        // Chat controls area - for emoticons, settings, report buttons
        m += '<div id="pbChatControls" style="padding:5px; background-color:#e8d6b0; border-top:1px solid #886;"></div>';

        t.myDiv.innerHTML = m;

        t.chatDiv = ById('pbChatContent');
        t.inputDiv = ById('pbChatInput');
        t.controlsDiv = ById('pbChatControls');

        // Add CSS to fix chat message display
        var style = document.createElement('style');
        style.textContent = `
            #pbChatContent > div {
                display: block !important;
                margin-bottom: 5px !important;
                clear: both !important;
            }
            #pbChatContent img {
                float: left;
                margin-right: 5px;
            }
        `;
        document.head.appendChild(style);

        // Move the game's chat input and controls to our tab
        t.moveGameChatElements();
    },

    setupChatTabs: function() {
        var t = Tabs.Chat;
        
        ById('pbGlobalChatTab').addEventListener('click', function() {
            t.switchChatType('global');
        });
        
        ById('pbAllianceChatTab').addEventListener('click', function() {
            t.switchChatType('alliance');
        });
        
        // Initialize with global chat
        t.switchChatType('global');
    },

    switchChatType: function(chatType) {
        var t = Tabs.Chat;
        t.currentChatType = chatType;
        
        // Update tab styling
        if (chatType === 'global') {
            ById('pbGlobalChatTab').className = 'tab selected';
            ById('pbAllianceChatTab').className = 'tab';
        } else {
            ById('pbGlobalChatTab').className = 'tab';
            ById('pbAllianceChatTab').className = 'tab selected';
        }
        
        // Switch to the appropriate chat tab in the game
        var gameChatTabs = document.querySelector('#mod_comm_tabs');
        if (gameChatTabs) {
            if (chatType === 'global') {
                gameChatTabs.selectedIndex = 0;
            } else {
                gameChatTabs.selectedIndex = 1;
            }
            // Trigger any events that might be needed
            var event = new Event('change');
            gameChatTabs.dispatchEvent(event);
        }
        
        // Update the chat content
        t.updateChat();
    },

    hookGameChat: function () {
        var t = Tabs.Chat;
        
        // Find the game's chat containers
        var globalChatContainer = document.querySelector('#mod_comm_list1');
        var allianceChatContainer = document.querySelector('#mod_comm_list2');

        if (globalChatContainer && allianceChatContainer) {
            // Set up observers for both chat types
            var observer = new MutationObserver(function(mutations) {
                t.updateChat();
            });

            // Observe both chat containers
            observer.observe(globalChatContainer, { childList: true, subtree: true });
            observer.observe(allianceChatContainer, { childList: true, subtree: true });

            // Initial update
            t.updateChat();
        } else {
            console.error('Could not find game chat containers');
            
            // Try again in a second - the game might not have loaded the chat yet
            setTimeout(function() {
                t.hookGameChat();
            }, 1000);
        }
    },

    updateChat: function () {
        var t = Tabs.Chat;
        
        // Get the appropriate chat container based on current chat type
        var chatSelector = (t.currentChatType === 'global') ? '#mod_comm_list1' : '#mod_comm_list2';
        var gameChatContainer = document.querySelector(chatSelector);
        
        if (gameChatContainer && t.chatDiv) {
            // Clear the current chat content
            t.chatDiv.innerHTML = '';
            
            // Clone each chat message individually
            var chatMessages = gameChatContainer.children;
            for (var i = 0; i < chatMessages.length; i++) {
                var messageClone = chatMessages[i].cloneNode(true);
                
                // Force block display for each message
                messageClone.style.display = 'block';
                messageClone.style.marginBottom = '5px';
                messageClone.style.clear = 'both';
                
                // Make sure images float left
                var img = messageClone.querySelector('img');
                if (img) {
                    img.style.float = 'left';
                    img.style.marginRight = '5px';
                }
                
                t.chatDiv.appendChild(messageClone);
            }
            
            // Scroll to bottom
            t.chatDiv.scrollTop = t.chatDiv.scrollHeight;
        }
    },

    moveGameChatElements: function () {
        var t = Tabs.Chat;
        
        // Find the game's chat input
        var gameChatInput = document.querySelector('#mod_comm_input');
        
        // Find the game's chat controls (emoticons, settings, report)
        var gameChatControls = document.querySelector('.chat_controls');
        
        if (gameChatInput && gameChatControls) {
            // Store reference to original containers
            t.originalInputContainer = gameChatInput.parentNode;
            t.originalControlsContainer = gameChatControls.parentNode;
            
            // Move the elements to our tab
            t.inputDiv.appendChild(gameChatInput);
            t.controlsDiv.appendChild(gameChatControls);
            
            // Style the input area
            gameChatInput.style.display = 'flex';
            gameChatInput.style.alignItems = 'center';
            
            var textarea = gameChatInput.querySelector('textarea');
            var sendButton = gameChatInput.querySelector('button');
            
            if (textarea && sendButton) {
                textarea.style.flexGrow = '1';
                textarea.style.marginRight = '5px';
                textarea.style.height = '40px';
                sendButton.style.height = '40px';
            }
            
            // Style the controls area
            gameChatControls.style.display = 'flex';
            gameChatControls.style.justifyContent = 'flex-start';
            gameChatControls.style.alignItems = 'center';
            
            // Add a visibility observer to handle tab switching
            t.setupVisibilityObserver();
        } else {
            console.error('Could not find game chat elements');
            
            // Try again in a second - the game might not have loaded the chat elements yet
            setTimeout(function() {
                t.moveGameChatElements();
            }, 1000);
        }
    },
    
    setupVisibilityObserver: function() {
        var t = Tabs.Chat;
        
        // Create a MutationObserver to watch for visibility changes
        var observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                if (mutation.attributeName === 'style' || 
                    mutation.attributeName === 'class' || 
                    mutation.type === 'childList') {
                    
                    // Check if our tab is visible
                    var isVisible = t.myDiv.offsetParent !== null && 
                                   window.getComputedStyle(t.myDiv).display !== 'none';
                    
                    // Get the elements
                    var gameChatInput = document.querySelector('#mod_comm_input');
                    var gameChatControls = document.querySelector('.chat_controls');
                    
                    if (!isVisible) {
                        // Move elements back to original containers when tab is hidden
                        if (gameChatInput && t.inputDiv.contains(gameChatInput) && t.originalInputContainer) {
                            t.originalInputContainer.appendChild(gameChatInput);
                        }
                        
                        if (gameChatControls && t.controlsDiv.contains(gameChatControls) && t.originalControlsContainer) {
                            t.originalControlsContainer.appendChild(gameChatControls);
                        }
                    } else {
                        // Move elements to our tab when tab becomes visible
                        if (gameChatInput && !t.inputDiv.contains(gameChatInput)) {
                            t.inputDiv.appendChild(gameChatInput);
                        }
                        
                        if (gameChatControls && !t.controlsDiv.contains(gameChatControls)) {
                            t.controlsDiv.appendChild(gameChatControls);
                        }
                    }
                }
            });
        });
        
        // Start observing the document body for visibility changes
        observer.observe(document.body, { 
            attributes: true, 
            childList: true, 
            subtree: true 
        });
    }
};