您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
chatv4test
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/539361/1607368/chatv4.js
Tabs.Chat = { tabOrder: 900, tabLabel: 'Chat', tabDisabled: false, myDiv: null, chatDiv: null, inputDiv: null, currentChatType: 'global', chatMessages: { global: [], alliance: [] }, 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>' + tx('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:450px; 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 m += '<div id="pbChatInput" style="padding:5px; background-color:#e8d6b0;"></div>'; t.myDiv.innerHTML = m; t.chatDiv = ById('pbChatContent'); t.inputDiv = ById('pbChatInput'); t.cloneGameChatInput(); }, 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.renderChatMessages(); }, hookGameChat: function () { var t = Tabs.Chat; 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 globalObserver = new MutationObserver(function(mutations) { t.processChatMessages('global'); }); var allianceObserver = new MutationObserver(function(mutations) { t.processChatMessages('alliance'); }); globalObserver.observe(globalChatContainer, { childList: true, subtree: true }); allianceObserver.observe(allianceChatContainer, { childList: true, subtree: true }); // Initial processing t.processChatMessages('global'); t.processChatMessages('alliance'); } else { console.error('Could not find game chat containers'); } }, processChatMessages: function(chatType) { var t = Tabs.Chat; var chatContainer = (chatType === 'global') ? document.querySelector('#mod_comm_list1') : document.querySelector('#mod_comm_list2'); if (chatContainer) { // Clear existing messages t.chatMessages[chatType] = []; // Process each chat message var chatItems = chatContainer.querySelectorAll('.chat-message'); for (var i = 0; i < chatItems.length; i++) { var item = chatItems[i]; var avatar = item.querySelector('img') ? item.querySelector('img').src : ''; var username = ''; var timestamp = ''; var message = ''; // Extract username, timestamp and message var textContent = item.textContent.trim(); var parts = textContent.split(':'); if (parts.length >= 2) { // Extract username and timestamp var userPart = parts[0].trim(); var timeParts = userPart.match(/(\d+:\d+)/); if (timeParts) { timestamp = timeParts[0]; username = userPart.replace(timestamp, '').trim(); } else { username = userPart; } // Extract message message = parts.slice(1).join(':').trim(); } else { message = textContent; } // Add to messages array t.chatMessages[chatType].push({ avatar: avatar, username: username, timestamp: timestamp, message: message }); } // Render if this is the current chat type if (t.currentChatType === chatType) { t.renderChatMessages(); } } }, renderChatMessages: function() { var t = Tabs.Chat; var messages = t.chatMessages[t.currentChatType]; var html = ''; for (var i = 0; i < messages.length; i++) { var msg = messages[i]; html += '<div style="display:flex; margin-bottom:5px;">'; // Avatar if (msg.avatar) { html += '<div style="margin-right:5px;"><img src="' + msg.avatar + '" style="width:40px; height:40px;"></div>'; } // Message content html += '<div>'; if (msg.username) { html += '<div><b>' + msg.username + '</b>'; if (msg.timestamp) { html += ' <span style="color:#888;">' + msg.timestamp + '</span>'; } html += '</div>'; } html += '<div>' + msg.message + '</div>'; html += '</div>'; html += '</div>'; } if (t.chatDiv) { t.chatDiv.innerHTML = html; t.chatDiv.scrollTop = t.chatDiv.scrollHeight; } }, cloneGameChatInput: function () { var t = Tabs.Chat; var gameChatInput = document.querySelector('#mod_comm_input'); if (gameChatInput) { var inputClone = gameChatInput.cloneNode(true); // Style the input area to match the game inputClone.style.display = 'flex'; inputClone.style.alignItems = 'center'; var textarea = inputClone.querySelector('textarea'); var sendButton = inputClone.querySelector('button'); if (textarea && sendButton) { textarea.style.flexGrow = '1'; textarea.style.marginRight = '5px'; textarea.style.height = '40px'; sendButton.style.height = '40px'; // Clear any existing event listeners var newTextarea = textarea.cloneNode(true); var newSendButton = sendButton.cloneNode(true); textarea.parentNode.replaceChild(newTextarea, textarea); sendButton.parentNode.replaceChild(newSendButton, sendButton); // Add our event listeners newTextarea.addEventListener('keypress', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); t.sendChat(); } }); newSendButton.addEventListener('click', function() { t.sendChat(); }); } t.inputDiv.innerHTML = ''; t.inputDiv.appendChild(inputClone); } else { console.error('Could not find game chat input'); } }, sendChat: function () { var t = Tabs.Chat; var chatTextArea = t.inputDiv.querySelector('textarea'); var gameChatTextArea = document.querySelector('#mod_comm_input textarea'); var gameSendButton = document.querySelector('#mod_comm_input button'); var gameChatTabs = document.querySelector('#mod_comm_tabs'); if (chatTextArea && gameChatTextArea && gameSendButton && gameChatTabs) { var message = chatTextArea.value.trim(); if (message !== '') { // Make sure the correct chat tab is selected in the game if (t.currentChatType === 'global') { gameChatTabs.selectedIndex = 0; } else { gameChatTabs.selectedIndex = 1; } // Trigger any events that might be needed var event = new Event('change'); gameChatTabs.dispatchEvent(event); // Send the message gameChatTextArea.value = message; gameSendButton.click(); chatTextArea.value = ''; // Process the new message after a short delay setTimeout(function() { t.processChatMessages(t.currentChatType); }, 500); } } else { console.error('Could not find necessary elements to send chat'); } } };