Greasy Fork is available in English.
chatv4test
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/539361/1607387/chatv4.js
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
});
}
};