您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
tab
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/538683/1605117/allie%20test.js
Tabs.Chat = { tabOrder: 900, tabLabel: 'Chat', tabDisabled: false, myDiv: null, globalChatDiv: null, allianceChatDiv: null, inputDiv: null, userListDiv: null, currentChatType: 'global', chatObservers: {}, init: function(div) { var t = Tabs.Chat; t.myDiv = div; t.createMainDiv(); t.hookGameChat(); t.updateUserList(); }, createMainDiv: function() { var t = Tabs.Chat; var m = '<DIV class=divHeader align=center>' + tx('CHAT') + '</div>'; m += '<div id="pbChatTabs" style="margin-bottom:10px;">'; m += '<button id="pbGlobalChatTab" class="tabActive">Global Chat</button>'; m += '<button id="pbAllianceChatTab">Alliance Chat</button>'; m += '</div>'; m += '<div id="pbChatRoom" style="display:flex; height:500px; border:1px solid #888;">'; m += '<div id="pbUserList" style="width:150px; border-right:1px solid #888; overflow-y:auto;"></div>'; m += '<div style="flex-grow:1; display:flex; flex-direction:column;">'; // Create chat content divs that will mirror the game's chat exactly m += '<div id="pbGlobalChatContent" style="flex-grow:1; overflow-y:auto; padding:5px;"></div>'; m += '<div id="pbAllianceChatContent" style="flex-grow:1; overflow-y:auto; padding:5px; display:none;"></div>'; m += '<div id="pbChatInput" style="border-top:1px solid #888; padding:10px;">'; // Custom chat input area m += '<textarea id="pbChatTextArea" style="width:100%; height:60px; margin-bottom:5px; padding:5px; resize:none;"></textarea>'; m += '<button id="pbChatSendButton" style="width:100%; padding:5px; cursor:pointer;">Send</button>'; m += '</div>'; m += '</div>'; m += '</div>'; t.myDiv.innerHTML = m; t.globalChatDiv = ById('pbGlobalChatContent'); t.allianceChatDiv = ById('pbAllianceChatContent'); t.userListDiv = ById('pbUserList'); t.inputDiv = ById('pbChatInput'); ById('pbGlobalChatTab').addEventListener('click', function() { t.switchChatType('global'); }); ById('pbAllianceChatTab').addEventListener('click', function() { t.switchChatType('alliance'); }); // Add event listeners for the custom chat input var chatTextArea = ById('pbChatTextArea'); var sendButton = ById('pbChatSendButton'); chatTextArea.addEventListener('keypress', function(e) { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); t.sendChat(); } }); sendButton.addEventListener('click', function() { t.sendChat(); }); }, hookGameChat: function() { var t = Tabs.Chat; // Clear any existing observers if (t.chatObservers.global) t.chatObservers.global.disconnect(); if (t.chatObservers.alliance) t.chatObservers.alliance.disconnect(); // Find the game's chat containers var gameChatContainer = document.querySelector('#mod_comm_list1'); var gameAllianceChatContainer = document.querySelector('#mod_comm_list2'); if (gameChatContainer && gameAllianceChatContainer) { // Create new observers t.chatObservers.global = new MutationObserver(function(mutations) { t.updateChat('global'); }); t.chatObservers.alliance = new MutationObserver(function(mutations) { t.updateChat('alliance'); }); // Configure and start the observers var observerConfig = { childList: true, subtree: true, attributes: true, characterData: true }; t.chatObservers.global.observe(gameChatContainer, observerConfig); t.chatObservers.alliance.observe(gameAllianceChatContainer, observerConfig); // Initial update t.updateChat('global'); t.updateChat('alliance'); } else { console.error('Could not find game chat containers'); // Set up a retry mechanism setTimeout(function() { t.hookGameChat(); }, 2000); } }, updateChat: function(chatType) { var t = Tabs.Chat; // Find the game's chat container var gameChatContainer = (chatType === 'global') ? document.querySelector('#mod_comm_list1') : document.querySelector('#mod_comm_list2'); var targetDiv = (chatType === 'global') ? t.globalChatDiv : t.allianceChatDiv; if (gameChatContainer && targetDiv) { // Clone the content exactly as it appears in the game targetDiv.innerHTML = gameChatContainer.innerHTML; // Maintain scroll position at bottom if already at bottom var isAtBottom = targetDiv.scrollHeight - targetDiv.scrollTop <= targetDiv.clientHeight + 50; if (isAtBottom) { targetDiv.scrollTop = targetDiv.scrollHeight; } } }, switchChatType: function(chatType) { var t = Tabs.Chat; t.currentChatType = chatType; // Update tab buttons ById('pbGlobalChatTab').className = (chatType === 'global') ? 'tabActive' : ''; ById('pbAllianceChatTab').className = (chatType === 'alliance') ? 'tabActive' : ''; // Show/hide chat content t.globalChatDiv.style.display = (chatType === 'global') ? 'block' : 'none'; t.allianceChatDiv.style.display = (chatType === 'alliance') ? 'block' : 'none'; // Update user list t.updateUserList(); // Make sure the chat is up to date t.updateChat(chatType); }, updateUserList: function() { var t = Tabs.Chat; // Try to get the actual user list from the game var gameUserList = null; if (t.currentChatType === 'global') { gameUserList = document.querySelector('#mod_comm_userlist1'); } else { gameUserList = document.querySelector('#mod_comm_userlist2'); } if (gameUserList) { // Clone the user list from the game t.userListDiv.innerHTML = gameUserList.innerHTML; } else { // Fallback to placeholder content var html = '<div style="padding:10px; font-weight:bold;">Online Users</div>'; html += '<div style="padding:5px 10px;">User 1</div>'; html += '<div style="padding:5px 10px;">User 2</div>'; html += '<div style="padding:5px 10px;">User 3</div>'; t.userListDiv.innerHTML = html; } }, sendChat: function() { var t = Tabs.Chat; var chatTextArea = ById('pbChatTextArea'); var message = chatTextArea.value.trim(); if (message === '') return; console.log("Attempting to send message: " + message); // Try multiple methods to ensure the message gets sent var success = false; // Method 1: Direct access to game's chat function if available if (typeof Chat !== 'undefined' && typeof Chat.sendMessage === 'function') { console.log("Using Chat.sendMessage"); var channel = (t.currentChatType === 'global') ? 'global' : 'alliance'; Chat.sendMessage(channel, message); success = true; } // Method 2: Find and use the game's chat input field if (!success) { console.log("Trying game's chat input"); var gameInputField = null; var sendButton = null; if (t.currentChatType === 'global') { gameInputField = document.querySelector('#mod_comm_input1'); sendButton = document.querySelector('#mod_comm_send1'); } else { gameInputField = document.querySelector('#mod_comm_input2'); sendButton = document.querySelector('#mod_comm_send2'); } if (gameInputField && sendButton) { // Set the value and dispatch events to simulate user typing gameInputField.value = message; gameInputField.dispatchEvent(new Event('input', { bubbles: true })); gameInputField.dispatchEvent(new Event('change', { bubbles: true })); // Click the send button sendButton.click(); success = true; } } // Method 3: Try to find and trigger the chat submit function if (!success) { console.log("Trying to find chat submit function"); // Look for common function names that might handle chat submission var possibleFunctions = ['submitChat', 'sendChat', 'postMessage', 'sendMessage']; for (var i = 0; i < possibleFunctions.length; i++) { var funcName = possibleFunctions[i]; if (typeof window[funcName] === 'function') { try { window[funcName](message, t.currentChatType); success = true; break; } catch (e) { console.log("Error calling " + funcName + ": " + e); } } } } // Method 4: Last resort - create and dispatch a custom event if (!success) { console.log("Dispatching custom chat event"); var chatEvent = new CustomEvent('powerbot_chat', { detail: { message: message, channel: t.currentChatType }, bubbles: true, cancelable: true }); document.dispatchEvent(chatEvent); } // Clear the input field regardless of success chatTextArea.value = ''; } };