Skip to content

Instantly share code, notes, and snippets.

@i30817
Created September 4, 2026 15:13
Show Gist options
  • Select an option

  • Save i30817/04506a8bab2fd32ac0a071e14d05173e to your computer and use it in GitHub Desktop.

Select an option

Save i30817/04506a8bab2fd32ac0a071e14d05173e to your computer and use it in GitHub Desktop.
block users in spacebattles without limiand logged outt
// ==UserScript==
// @name Spacebattles Filter (Main Page Native Hook)
// @namespace http://tampermonkey.net
// @version 6.9.2
// @description Hides threads by specific users. Adds a script block/unblock button instantly inside XenForo's native hover member card tooltips. Adds New Threadmarks filtering.
// @author AI Assistant
// @match https://forums.spacebattles.com/*
// @grant GM_setValue
// @grant GM_getValue
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
let blockedUsers = GM_getValue("sb_loggedout_blocks", []);
function scrubContent() {
// --- ORIGINAL 6.9 BLOCKING MECHANICS ---
const threads = document.querySelectorAll('div.structItem[data-author]');
threads.forEach(thread => {
if (!thread) return;
const author = thread.getAttribute('data-author');
if (author && blockedUsers.includes(author.toLowerCase().trim())) {
thread.remove();
}
});
const feeds = document.querySelectorAll('.js-newsFeedTarget [data-author]');
feeds.forEach(item => {
if (!item) return;
const author = item.getAttribute('data-author');
if (author && blockedUsers.includes(author.toLowerCase().trim())) {
item.remove();
}
});
const activityLinks = document.querySelectorAll('.js-newsFeedTarget a.username[data-user-id], [data-template="whats_new"] a.username[data-user-id]');
activityLinks.forEach(link => {
if (!link) return;
const author = link.textContent.toLowerCase().trim();
if (blockedUsers.includes(author)) {
const targetRow = link.closest('.contentRow, li, .block-row');
if (targetRow) {
targetRow.remove();
}
}
});
// --- NEW THREADMARKS SEPARATED FIX ---
// New Threadmarks views organize lists via table row syntax ("tr") rather than standard blocks ("div")
const threadmarkRows = document.querySelectorAll('tr.structItem[data-author]');
threadmarkRows.forEach(row => {
if (!row) return;
const author = row.getAttribute('data-author');
if (author && blockedUsers.includes(author.toLowerCase().trim())) {
row.remove();
}
});
// Deep match nested threadmark item container lists
const threadmarkContainers = document.querySelectorAll('.structItem--threadmark');
threadmarkContainers.forEach(container => {
const authorLink = container.querySelector('a.username[data-user-id]');
if (authorLink) {
const author = authorLink.textContent.toLowerCase().trim();
if (blockedUsers.includes(author)) {
container.remove();
}
}
});
}
function injectTooltipUI() {
const actionContainers = document.querySelectorAll('.memberTooltip-actions');
actionContainers.forEach(actionContainer => {
if (actionContainer.querySelector('.sb-tooltip-btn')) return;
const tooltip = actionContainer.closest('.tooltip--member');
if (!tooltip) return;
const nameNode = tooltip.querySelector('.memberTooltip-name');
if (!nameNode) return;
const username = nameNode.textContent.replace(/\[.*?\]/g, '').split('\n').join('').trim();
if (!username) return;
const normalizedName = username.toLowerCase();
const isBlocked = blockedUsers.includes(normalizedName);
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'button button--link sb-tooltip-btn';
btn.style.padding = '6px 10px';
btn.style.fontSize = '12px';
btn.style.fontWeight = 'bold';
btn.style.cursor = 'pointer';
btn.style.marginLeft = '5px';
btn.style.display = 'inline-block';
btn.style.verticalAlign = 'middle';
if (isBlocked) {
btn.textContent = `Unblock (Script)`;
btn.style.backgroundColor = '#cc2424';
btn.style.color = '#ffffff';
btn.style.borderColor = '#b31c1c';
} else {
btn.textContent = `Block (Script)`;
btn.style.backgroundColor = '#0066cc';
btn.style.color = '#ffffff';
btn.style.borderColor = '#0052a3';
}
btn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
if (blockedUsers.includes(normalizedName)) {
blockedUsers = blockedUsers.filter(name => name !== normalizedName);
} else {
blockedUsers.push(normalizedName);
}
GM_setValue("sb_loggedout_blocks", blockedUsers);
window.location.reload();
});
actionContainer.appendChild(btn);
});
}
function injectMobileUI() {
if (!window.location.pathname.includes('/members/')) return;
const targetHeader = document.querySelector('.memberHeader > .memberHeader-content, .memberHeader-content');
if (!targetHeader || targetHeader.querySelector('.sb-mobile-btn')) return;
const nameNode = targetHeader.querySelector('.memberHeader-name, h1, h2');
if (!nameNode) return;
const username = nameNode.textContent.replace(/\[.*?\]/g, '').split('\n').join('').trim();
if (!username) return;
const normalizedName = username.toLowerCase();
const isBlocked = blockedUsers.includes(normalizedName);
const btnWrapper = document.createElement('div');
btnWrapper.className = 'sb-mobile-btn';
btnWrapper.style.margin = '15px 0 5px 0';
btnWrapper.style.width = '100%';
btnWrapper.style.clear = 'both';
btnWrapper.style.display = 'block';
const btn = document.createElement('button');
btn.type = 'button';
btn.style.padding = '12px 16px';
btn.style.fontSize = '14px';
btn.style.fontWeight = 'bold';
btn.style.border = '1px solid rgba(255,255,255,0.15)';
btn.style.borderRadius = '4px';
btn.style.cursor = 'pointer';
btn.style.width = '100%';
btn.style.textAlign = 'center';
btn.style.boxShadow = '0 2px 5px rgba(0,0,0,0.4)';
// Extracted variables securely without forcing string modifications on line layout bounds
if (isBlocked) {
btn.textContent = "Unblock " + username + " (Script)";
btn.style.backgroundColor = '#cc2424';
btn.style.color = '#ffffff';
} else {
btn.textContent = "Block " + username + " (Script)";
btn.style.backgroundColor = '#0066cc';
btn.style.color = '#ffffff';
}
btn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
if (blockedUsers.includes(normalizedName)) {
blockedUsers = blockedUsers.filter(name => name !== normalizedName);
alert('"' + username + '" has been unblocked.');
} else {
blockedUsers.push(normalizedName);
alert('"' + username + '" has been blocked.');
}
GM_setValue("sb_loggedout_blocks", blockedUsers);
window.location.reload();
});
btnWrapper.appendChild(btn);
targetHeader.appendChild(btnWrapper);
}
function handleDashboardVisibility() {
const isMainPage = document.body && document.body.getAttribute('data-template') === 'forum_list';
const existingToggle = document.getElementById('sb-filter-dashboard-toggle');
const existingPanel = document.getElementById('sb-filter-dashboard-panel');
if (!isMainPage) {
if (existingToggle) existingToggle.style.display = 'none';
if (existingPanel) existingPanel.style.display = 'none';
return;
}
if (existingToggle) {
existingToggle.style.display = 'flex';
return;
}
const toggleBtn = document.createElement('button');
toggleBtn.id = 'sb-filter-dashboard-toggle';
toggleBtn.innerHTML = '⚙️';
toggleBtn.style.position = 'fixed';
toggleBtn.style.bottom = '25px';
toggleBtn.style.right = '25px';
toggleBtn.style.zIndex = '10000';
toggleBtn.style.backgroundColor = '#1f487e';
toggleBtn.style.color = '#ffffff';
toggleBtn.style.border = '2px solid #ffffff';
toggleBtn.style.borderRadius = '50%';
toggleBtn.style.width = '50px';
toggleBtn.style.height = '50px';
toggleBtn.style.fontSize = '24px';
toggleBtn.style.cursor = 'pointer';
toggleBtn.style.display = 'flex';
toggleBtn.style.alignItems = 'center';
toggleBtn.style.justifyContent = 'center';
toggleBtn.style.boxShadow = '0 4px 8px rgba(0,0,0,0.4)';
const panel = document.createElement('div');
panel.id = 'sb-filter-dashboard-panel';
panel.style.position = 'fixed';
panel.style.bottom = '85px';
panel.style.right = '25px';
panel.style.width = '280px';
panel.style.maxHeight = '350px';
panel.style.backgroundColor = '#1d2025';
panel.style.color = '#e1e2e6';
panel.style.border = '1px solid #3e4550';
panel.style.borderRadius = '8px';
panel.style.boxShadow = '0px 4px 15px rgba(0,0,0,0.5)';
panel.style.zIndex = '10000';
panel.style.display = 'none';
panel.style.flexDirection = 'column';
panel.style.overflow = 'hidden';
const header = document.createElement('div');
header.style.padding = '12px';
header.style.backgroundColor = '#141619';
header.style.fontWeight = 'bold';
header.style.borderBottom = '1px solid #3e4550';
header.style.display = 'flex';
header.style.justifyContent = 'space-between';
header.style.alignItems = 'center';
header.innerHTML = 'Blocked Users';
const closeBtn = document.createElement('span');
closeBtn.innerHTML = '×';
closeBtn.style.cursor = 'pointer';
closeBtn.style.fontSize = '20px';
closeBtn.addEventListener('click', () => {
panel.style.display = 'none';
});
header.appendChild(closeBtn);
panel.appendChild(header);
const listBody = document.createElement('div');
listBody.style.padding = '10px';
listBody.style.overflowY = 'auto';
listBody.style.flexGrow = '1';
panel.appendChild(listBody);
toggleBtn.addEventListener('click', () => {
if (panel.style.display === 'none') {
renderListItems(listBody);
panel.style.display = 'flex';
}
else {
panel.style.display = 'none';
}
});
document.body.appendChild(toggleBtn);
document.body.appendChild(panel);
}
function renderListItems(container) {
container.innerHTML = '';
if (blockedUsers.length === 0) {
container.innerHTML = 'No users blocked yet.';
return;
}
blockedUsers.forEach(user => {
const row = document.createElement('div');
row.style.display = 'flex';
row.style.justifyContent = 'space-between';
row.style.alignItems = 'center';
row.style.padding = '8px 0';
row.style.borderBottom = '1px solid #282c34';
const nameSpan = document.createElement('span');
nameSpan.textContent = user;
nameSpan.style.fontSize = '14px';
const removeBtn = document.createElement('button');
removeBtn.type = 'button';
removeBtn.textContent = 'Remove';
removeBtn.style.backgroundColor = '#a71d5d';
removeBtn.style.color = '#ffffff';
removeBtn.style.border = 'none';
removeBtn.style.borderRadius = '3px';
removeBtn.style.padding = '4px 8px';
removeBtn.style.cursor = 'pointer';
removeBtn.addEventListener('click', () => {
blockedUsers = blockedUsers.filter(name => name !== user);
GM_setValue("sb_loggedout_blocks", blockedUsers);
row.remove();
if (blockedUsers.length === 0) {
container.innerHTML = 'No users blocked yet.';
}
});
row.appendChild(nameSpan);
row.appendChild(removeBtn);
container.appendChild(row);
});
}
function masterLoop() {
scrubContent();
injectTooltipUI();
injectMobileUI();
handleDashboardVisibility();
}
masterLoop();
const globalObserver = new MutationObserver(masterLoop);
globalObserver.observe(document.documentElement, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment