Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (function() {
- // Prevent multiple initializations
- if (window._comuChatInstalled) return;
- window._comuChatInstalled = true;
- // Instruct the server to send us `cmd` broadcast messages
- // (In case the user hasn't received them yet)
- OWOT.broadcastReceive(true);
- // ==========================================
- // 1. Create the Custom UI Elements
- // ==========================================
- const chatUpper = document.getElementById("chat_upper");
- const chatWindow = document.getElementById("chat_window");
- const chatLower = document.getElementById("chat_lower");
- const usrOnline = document.getElementById("usr_online");
- // Create the Tab
- const comuTab = document.createElement("div");
- comuTab.className = "chat_tab_button";
- comuTab.id = "chat_comu_tab";
- comuTab.innerHTML = 'Comu<b id="comu_unread" class="unread" style="display: none;">(-)</b>';
- // Create the Chat Field container
- const comuField = document.createElement("div");
- comuField.className = "chatfield";
- comuField.id = "comu_chatfield";
- comuField.style.display = "none";
- // Inject into OWOT's DOM
- chatUpper.insertBefore(comuTab, usrOnline);
- chatWindow.insertBefore(comuField, chatLower);
- let isComuActive = false;
- let comuUnreadCount = 0;
- const comuUnreadElm = document.getElementById("comu_unread");
- function updateComuUnread() {
- if(isComuActive || comuUnreadCount === 0) {
- comuUnreadElm.style.display = "none";
- comuUnreadCount = 0;
- } else {
- comuUnreadElm.style.display = "";
- comuUnreadElm.innerText = comuUnreadCount > 99 ? "99+" : `(${comuUnreadCount})`;
- }
- }
- // ==========================================
- // 2. Handle Tab Switching Logic
- // ==========================================
- const pageTab = document.getElementById("chat_page_tab");
- const globalTab = document.getElementById("chat_global_tab");
- comuTab.addEventListener("click", function() {
- isComuActive = true;
- // Update tab visuals
- comuTab.classList.add("chat_tab_selected");
- pageTab.classList.remove("chat_tab_selected");
- globalTab.classList.remove("chat_tab_selected");
- // Swap chatfields
- comuField.style.display = "";
- document.getElementById("page_chatfield").style.display = "none";
- document.getElementById("global_chatfield").style.display = "none";
- updateComuUnread();
- comuField.scrollTop = comuField.scrollHeight; // Snap to bottom
- });
- // Make sure we un-select the custom tab if native tabs are clicked
- pageTab.addEventListener("click", () => {
- isComuActive = false;
- comuField.style.display = "none";
- comuTab.classList.remove("chat_tab_selected");
- });
- globalTab.addEventListener("click", () => {
- isComuActive = false;
- comuField.style.display = "none";
- comuTab.classList.remove("chat_tab_selected");
- });
- // ==========================================
- // 3. Intercept Outgoing Chat Messages
- // ==========================================
- OWOT.on("chatSend", function(e) {
- if(isComuActive) {
- e.cancel = true; // Stop native chat from sending
- let msg = e.message.trim();
- if(!msg) return;
- // Respect the user's selected chat color
- let colorInt = window.defaultChatColor !== null ? window.defaultChatColor : YourWorld.Color;
- let colorHex = "#" + ("000000" + colorInt.toString(16)).slice(-6);
- // Construct payload
- let payload = JSON.stringify({
- type: "comu_chat",
- msg: msg,
- color: colorHex
- });
- // Broadcast over OWOT's `cmd` network protocol
- // true = Tells server to append the sender's username & ID natively
- OWOT.broadcastCommand(payload, true);
- // Clear input
- document.getElementById("chatbar").value = "";
- }
- });
- // Helper: Prevent XSS in chat
- function escapeHtml(text) {
- let map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
- return text.replace(/[&<>"']/g, function(m) { return map[m]; });
- }
- // ==========================================
- // 4. Handle Incoming Comu Messages
- // ==========================================
- OWOT.on("cmd", function(e) {
- try {
- let data = JSON.parse(e.data);
- if(data.type === "comu_chat") {
- renderComuMessage(e.id, e.username, data.msg, data.color);
- // Update unread counter if tab isn't active
- if(!isComuActive) {
- comuUnreadCount++;
- updateComuUnread();
- }
- }
- } catch(err) {
- // Not a valid JSON or not our protocol, safely ignore
- }
- });
- // ==========================================
- // 5. Custom Renderer
- // ==========================================
- function renderComuMessage(id, username, msg, color) {
- let chatGroup = document.createElement("div");
- // Nickname wrapper
- let nickDom = document.createElement("span");
- nickDom.style.fontWeight = "bold";
- nickDom.style.color = color || "#000000";
- let safeUsername = escapeHtml(username || "Anonymous");
- let safeMsg = escapeHtml(msg);
- // Add ID tags just like native chat
- let idTag = id ? `[${id}] ` : "";
- nickDom.innerHTML = idTag + safeUsername + ": ";
- // Message wrapper
- let msgDom = document.createElement("span");
- msgDom.innerHTML = safeMsg;
- chatGroup.appendChild(nickDom);
- chatGroup.appendChild(msgDom);
- // Calculate scroll behavior (snap to bottom if they already are at bottom)
- let isAtBottom = (comuField.scrollHeight - comuField.scrollTop - comuField.clientHeight) < 20;
- comuField.appendChild(chatGroup);
- if(isAtBottom || isComuActive) {
- comuField.scrollTop = comuField.scrollHeight;
- }
- // Limit history to prevent DOM memory leaks
- if(comuField.children.length > 500) {
- comuField.removeChild(comuField.firstChild);
- }
- }
- console.log("Custom Comu Chat Protocol successfully initialized.");
- })();
Advertisement
Add Comment
Please, Sign In to add comment