Meklin Shutdownchat Script

Modified Shutdownchat, unmatched scripts, brace to be thunderstruck

Ekde 2023/12/30. Vidu La ĝisdata versio.

// ==UserScript==
// @name         Meklin Shutdownchat Script
// @version      1.2
// @description  Modified Shutdownchat, unmatched scripts, brace to be thunderstruck
// @author       MeKLiN
// @namespace    https://greasyfork.org/en/scripts/483405-meklin-shutdownchat-script
// @match        https://www.shutdown.chat/rooms*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=shutdown.chat
// @license      MIT
// @grant        none
// @exclude      https://www.shutdown.chat/profiles*
// @exclude      https://www.shutdown.chat/manage*
// @run-at       document-start
// @require      https://cdnjs.cloudflare.com/ajax/libs/jshint/2.9.7/jshint.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-shim.min.js
// ==/UserScript==
console.log("MSS 1.1 STARTED");
debugger;

var blocked_uuids = JSON.parse(localStorage.getItem('blocked_uuids')) || [];

function getNickname(fcuserSpan) {
    if (!fcuserSpan) return;

    // Check if fcuserSpan is a direct child of p
    var isDirectChild = fcuserSpan.parentNode.nodeName === "P";
    var nickname;

    if (isDirectChild) {
        nickname = fcuserSpan.innerText.replace(/[:\-]/g, '').trim();
    } else {
        // If not a direct child, assume it's under an anchor tag (a) in the user list
        nickname = fcuserSpan.parentNode.querySelector('.fcuser').innerText.replace(/[:\-]/g, '').trim();
    }

    return nickname;
}

// Function to handle the new chat messages
function handleNewChatMessages() {
    var chatboxElems = document.querySelector('.chatbox').getElementsByTagName('p');
    for (var i = 0; i < chatboxElems.length; i++) {
        var chatElem = chatboxElems[i];
        if (!chatElem.handled) {
            chatElem.handled = true;
            var fcuserSpan = chatElem.querySelector('.nm.fcuser');
            var uuid = fcuserSpan ? fcuserSpan.dataset.uuid : null;
            if (blocked_uuids.includes(uuid)) {
                chatElem.style.display = 'none'; // hide the message
            }
        }
    }
}

// Call the handleNewChatMessages function on page load and whenever the chatbox is updated
handleNewChatMessages();
document.querySelector('.chatbox').addEventListener('DOMNodeInserted', handleNewChatMessages);


// Get the chatbox element
var chatbox = document.querySelector(".chatbox");

// Create a mutation observer to monitor changes in the chatbox
var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        mutation.addedNodes.forEach(function(node) {
            // Check if the node is a chat message
            if (node.nodeName === "P" && node.dataset.t === "c") {
                // Get the uuid of the user who sent the message
                var uuidElement = node.querySelector(".nm.fcuser");
                if (uuidElement) {
                    var uuid = uuidElement.dataset.uuid;
                    console.log("Found message with UUID:", uuid);

                    // Check if the uuid is in the blocked list
                    if (blocked_uuids.includes(uuid)) {
                        console.log("Blocking message with UUID:", uuid);
                        // Hide the message
                        node.style.display = "none";
                    }
                } else {
                    console.log("Could not find UUID element in message:", node);
                }
            }
        });
    });
});

// Start observing the chatbox
observer.observe(chatbox, { childList: true });

// Function to show a notification
function showNotification(message) {
    var notification = document.createElement("div");
    notification.innerHTML = `<div style="position: fixed; bottom: 10px; left: 10px; background-color: #f0f0f0; padding: 10px; border: 1px solid #ccc; border-radius: 5px; font-size: 12px; opacity: 1; transition: opacity 2s ease-in-out;">${message}</div>`;
    document.body.appendChild(notification);

    // Set a timeout to fade out the notification
    setTimeout(function () {
        notification.style.opacity = 0;
    }, 2000); // Adjust the timeout value as needed

    // Remove the notification from the DOM after fading out
    setTimeout(function () {
        document.body.removeChild(notification);
    }, 3000); // Adjust the timeout value to match the fade-out duration
}

// Function to block/unblock a user
function blockUser(uuid) {
    console.log("blockUser function is called");
    var index = blocked_uuids.indexOf(uuid);
    if (index !== -1) {
        // User is already blocked, so unblock
        blocked_uuids.splice(index, 1);
        showNotification("User unblocked!");
    } else {
        // User is not blocked, so block
        blocked_uuids.push(uuid);
        showNotification("User blocked!");
    }

    // Save the updated blocked_uuids to localStorage
    localStorage.setItem('blocked_uuids', JSON.stringify(blocked_uuids));
}

// Function to create a button to view the ignore list
function createIgnoreListButton() {
    console.log("createIgnoreListButton function is called");
    var ignoreListButton = document.createElement("button");
    ignoreListButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M20 18V8a6 6 0 0 0-12 0v10h12zM12 2C6.48 2 2 6.48 2 12v10h2V12a5.978 5.978 0 0 1 5.985-6H12V2zm8.293 2.293a1 1 0 0 1 1.414 0l1.414 1.414a1 1 0 0 1 0 1.414L19.414 10l3.707 3.707a1 1 0 0 1 0 1.414l-1.414 1.414a1 1 0 0 1-1.414 0L18 13.414l-3.707 3.707a1 1 0 0 1-1.414 0l-1.414-1.414a1 1 0 0 1 0-1.414L14.586 12 10.88 8.293a1 1 0 0 1 0-1.414L12.294 5.465a1 1 0 0 1 1.414 0z"/></svg> View Ignore List`;
    ignoreListButton.style.position = "fixed";
    ignoreListButton.style.top = "10px";
    ignoreListButton.style.left = "10px";
    ignoreListButton.addEventListener("click", function () {
        // Display the ignore list (you can customize this part)
        alert("Ignore List:\n" + blocked_uuids.join(", "));
    });

    document.body.appendChild(ignoreListButton);
}

// Call the function to create the ignore list button
createIgnoreListButton();


// Get the user list element
var userlist = document.querySelector(".userlist");

// Create the block and ignore buttons and append them to each user
var users = userlist.querySelectorAll(".fcuser");
users.forEach(function (user) {
    var uuid = user.dataset.uuid;

    // Create the block button
    var blockButton = document.createElement("button");
    blockButton.innerText = "Block";
    blockButton.addEventListener("click", function() {
        blockUser(uuid);
    });

    // Create the ignore button with a unique class
    var ignoreButton = document.createElement("button");
    ignoreButton.innerText = "Ignore";
    ignoreButton.setAttribute("data-btntype", "ignore"); // Set a new attribute for identification
    ignoreButton.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"><path fill="none" d="M0 0h24v24H0z"/><path d="M20 18V8a6 6 0 0 0-12 0v10h12zM12 2C6.48 2 2 6.48 2 12v10h2V12a5.978 5.978 0 0 1 5.985-6H12V2zm8.293 2.293a1 1 0 0 1 1.414 0l1.414 1.414a1 1 0 0 1 0 1.414L19.414 10l3.707 3.707a1 1 0 0 1 0 1.414l-1.414 1.414a1 1 0 0 1-1.414 0L18 13.414l-3.707 3.707a1 1 0 0 1-1.414 0l-1.414-1.414a1 1 0 0 1 0-1.414L14.586 12 10.88 8.293a1 1 0 0 1 0-1.414L12.294 5.465a1 1 0 0 1 1.414 0z"/></svg>`;
    ignoreButton.style.marginLeft = "5px";
    ignoreButton.style.cursor = "pointer";
    // Add a unique class to the ignore button
    ignoreButton.classList.add("ignoreButtonClass");

    ignoreButton.addEventListener("click", function () {
        // Dynamically fetch the user UUID when the "Ignore" button is clicked
        var clickedUserUUID = user.dataset.uuid;
        blockUser(clickedUserUUID);
    });

    // Create a container div for the buttons
    var buttonContainer = document.createElement("div");
    buttonContainer.style.display = "flex";
    buttonContainer.style.alignItems = "center";

    // Append the buttons to the container
    buttonContainer.appendChild(blockButton);
    buttonContainer.appendChild(ignoreButton);

    // Append the container to the user element
    user.parentElement.appendChild(buttonContainer);
});

// usermenu block button event listener:
document.querySelector('.usermenu button[data-btntype="block"]').addEventListener('click', function() {
    console.log("User menu block button clicked");

    // Get the parent element of the button, assuming it contains user-related data
    var userContainer = this.closest('.user-container');

    // Assuming the user UUID is stored in a data attribute called data-uuid
    var userUUID = userContainer ? userContainer.dataset.uuid : null;

    // Check if userUUID is not null before blocking
    if (userUUID) {
        // Now you have the user UUID, and you can proceed to block the user
        blockUser(userUUID);
    } else {
        console.error("User UUID not found. Unable to block user.");
    }
});

// Function to create an ignore button in the user menu
function createIgnoreButton(username, uuid) {
    console.log("createIgnoreButton function is called");

    var ignoreButton = document.createElement("button");
    ignoreButton.innerText = "Ignore";
    ignoreButton.setAttribute("data-btntype", "ignore"); // Set a new attribute for identification
    ignoreButton.style.display = "block";
    ignoreButton.style.marginTop = "5px"; // Adjust the styling as needed


    // Insert the ignore button into the user menu
    var userMenu = document.querySelector('.usermenu');
    if (userMenu) {
        userMenu.insertBefore(ignoreButton, userMenu.firstChild);


        // Add click event directly to the button
        ignoreButton.addEventListener("click", function () {
            // Log to console to check if the button click is being registered
            console.log("Ignore button clicked");

            // Traverse the DOM to find the user UUID dynamically within FreeChat context
            var userUUID = getUserUUIDFromUserList();

            // Check if the user UUID is found
            if (userUUID) {
                blockUser(userUUID, username);
            } else {
                console.error("User UUID not found. Ignoring user without blocking.");
            }
        });
    } else {
        console.error("User menu not found.");
    }
}

// Function to get the user UUID from the user list within FreeChat context
function getUserUUIDFromUserList() {
    var userContainer = document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist p.user.fcuser[data-uuid]");

    if (userContainer) {
        return userContainer.dataset.uuid;
    } else {
        // If user container is not found, set up a MutationObserver to wait for changes
        var observer = new MutationObserver(function (mutations) {
            userContainer = document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist p.user.fcuser[data-uuid]");
            if (userContainer) {
                console.log("User container found after mutation.");
                console.log("User UUID: ", userContainer.dataset.uuid);
                // Stop observing once the user container is found
                observer.disconnect();
            }
        });

        // Start observing changes in the user list
        observer.observe(document.querySelector("#chat > div.fc > div.gridbox_list > div.userlist"), { childList: true, subtree: true });

        console.error("User container not found in the user list within FreeChat context. Waiting for mutations...");
        return null;
    }
}

// Call the function to create the ignore button in the user menu
createIgnoreButton();

// Create the ignore list div once and append the content dynamically
var ignoreListDiv = document.createElement("div");
ignoreListDiv.style.position = "fixed";
ignoreListDiv.style.bottom = "10px"; // Move to the bottom
ignoreListDiv.style.left = "10px";
ignoreListDiv.style.backgroundColor = "white"; // Adjust styling as needed
ignoreListDiv.style.padding = "10px";
ignoreListDiv.style.border = "1px solid black"; // Add border for visibility
ignoreListDiv.style.fontSize = "12px"; // Set font size to 12px


// Create a heading for the ignore list
var ignoreListHeading = document.createElement("h3");
ignoreListHeading.innerText = "Ignore List";
ignoreListDiv.appendChild(ignoreListHeading);

// Create a list to display ignored users
var ignoreList = document.createElement("ul");
ignoreList.style.listStyleType = "none"; // Remove default list styling
ignoreListDiv.appendChild(ignoreList);

// Append the ignore list div to the body
document.body.appendChild(ignoreListDiv);

// Function to create a list item with the ignore list entry and remove button
function createIgnoreListItem(uuid, username) {
    var listItem = document.createElement("li");
    listItem.innerText = `${username} (${uuid})`;

    // Create a remove button for each entry
    var removeButton = document.createElement("button");
    removeButton.innerText = "Remove";
    removeButton.addEventListener("click", function () {
        // Remove the entry when the button is clicked
        removeIgnoreEntry(uuid);
    });

    // Append the remove button to the list item
    listItem.appendChild(removeButton);

    // Append the list item to the ignore list
    ignoreList.appendChild(listItem);
}


// Function to refresh the ignore list display
function refreshIgnoreList() {
    // Clear the existing content
    ignoreList.innerHTML = "";

    // Populate the ignore list with entries and remove buttons
    blocked_uuids.forEach(function (uuid) {
        createIgnoreListItem(uuid);
    });
}

// Populate the ignore list with entries and remove buttons
blocked_uuids.forEach(function (entry) {
    // Create a list item with the ignore list entry and remove button
    var listItem = document.createElement("li");
    listItem.innerText = `${entry.username} (${entry.uuid})`;

    // Create a remove button for each entry
    var removeButton = document.createElement("button");
    removeButton.innerText = "Remove";
    removeButton.addEventListener("click", function () {
        // Remove the entry when the button is clicked
        removeIgnoreEntry(entry.uuid);
    });

    // Append the remove button to the list item
    listItem.appendChild(removeButton);

    // Append the list item to the ignore list
    ignoreList.appendChild(listItem);
});


// Function to handle removing an entry from the ignore list
function removeIgnoreEntry(uuid) {
    var index = blocked_uuids.findIndex(entry => entry.uuid === uuid);
    if (index !== -1) {
        // Remove the entry from the ignore list
        blocked_uuids.splice(index, 1);
        // Refresh the ignore list display after removal
        refreshIgnoreList();
    }
}

// Function to save blocked_uuids to a text file
function saveToTextFile() {
    var textToSave = blocked_uuids.join('\n');
    var blob = new Blob([textToSave], { type: 'text/plain' });
    var link = document.createElement('a');
    link.download = 'ignore_list.txt';
    link.href = window.URL.createObjectURL(blob);
    link.onclick = function () {
        document.body.removeChild(link);
    };
    link.style.display = 'none';
    document.body.appendChild(link);
    link.click();
}

// Function to load blocked_uuids from a text file
function loadFromTextFile() {
    var input = document.createElement('input');
    input.type = 'file';
    input.accept = '.txt';
    input.onchange = function (event) {
        var file = event.target.files[0];
        if (file) {
            var reader = new FileReader();
            reader.onload = function (e) {
                // Parse the content of the file and update blocked_uuids
                blocked_uuids = e.target.result.split('\n').map(function (uuid) {
                    return uuid.trim();
                });
                // Update the ignore list display
                refreshIgnoreList();
            };
            reader.readAsText(file);
        }
    };
    input.click();
}

// Function to create a button to save and load ignore list
function createSaveLoadButtons() {
    var saveButton = document.createElement("button");
    saveButton.innerText = "Save to Text File";
    saveButton.addEventListener("click", function () {
        saveToTextFile();
    });

    var loadButton = document.createElement("button");
    loadButton.innerText = "Load from Text File";
    loadButton.addEventListener("click", function () {
        loadFromTextFile();
    });

    var buttonContainer = document.createElement("div");
    buttonContainer.style.marginTop = "10px";
    buttonContainer.appendChild(saveButton);
    buttonContainer.appendChild(loadButton);

    // Append the button container to the ignore list div
    ignoreListDiv.appendChild(buttonContainer);
}

// Call the function to create the save and load buttons
createSaveLoadButtons();