TriX Executor's ChatBox (for territorial.io)!
当前为
// ==UserScript==
// @name TrixBox
// @namespace http://tampermonkey.net/
// @version 0.2.9
// @description TriX Executor's ChatBox (for territorial.io)!
// @author Painsel
// @match https://territorial.io/*
// @match https://fxclient.github.io/FXclient/*
// @match https://discord.com/*
// @grant GM_xmlhttpRequest
// @grant GM_info
// ==/UserScript==
/*
Copyright (c) 2025 Painsel
All Rights Reserved.
This script is proprietary software. You may not use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software.
UNAUTHORIZED COPYING, DISTRIBUTION, OR MODIFICATION OF THIS SCRIPT,
EITHER IN WHOLE OR IN PART, IS STRICTLY PROHIBITED.
*/
(function() {
'use strict';
// --- Theme Colors (for UI elements outside the iframe) ---
const theme = {
icon: '#2f3136',
modalBg: '#2f3136',
text: '#dcddde',
buttonPrimary: '#5865f2',
buttonSecondary: '#4f545c'
};
const SCRIPT_UPDATE_URL = 'https://update.greasyfork.org/scripts/555536/TrixBox.meta.js';
const SCRIPT_INSTALL_URL = 'https://update.greasyfork.org/scripts/555536/TrixBox.user.js';
// --- 1. UPDATE CHECKING LOGIC ---
const showUpdateModal = () => {
const modalStyle = `
.trixbox-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 100000; display: flex; align-items: center; justify-content: center; }
.trixbox-modal-content { background: ${theme.modalBg}; color: ${theme.text}; padding: 25px; border-radius: 10px; text-align: center; font-family: sans-serif; box-shadow: 0 5px 15px rgba(0,0,0,0.5); }
.trixbox-modal-content h2 { margin-top: 0; }
.trixbox-modal-content p { margin: 15px 0; }
.trixbox-modal-btn { color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; margin: 0 10px; font-size: 14px; }
.trixbox-modal-btn.primary { background: ${theme.buttonPrimary}; }
.trixbox-modal-btn.secondary { background: ${theme.buttonSecondary}; }
`;
const styleSheet = document.createElement("style");
styleSheet.innerText = modalStyle;
document.head.appendChild(styleSheet);
const modalOverlay = document.createElement('div');
modalOverlay.className = 'trixbox-modal-overlay';
modalOverlay.innerHTML = `
<div class="trixbox-modal-content">
<h2>OUTDATED VERSION</h2>
<p>You are using an Outdated version of TrixBox.<br>Please update for the best experience!</p>
<button id="trixbox-update-btn" class="trixbox-modal-btn primary">Update Now!</button>
<button id="trixbox-later-btn" class="trixbox-modal-btn secondary">Remind Me Later!</button>
</div>
`;
document.body.appendChild(modalOverlay);
document.getElementById('trixbox-update-btn').onclick = () => { window.location.href = SCRIPT_INSTALL_URL; };
document.getElementById('trixbox-later-btn').onclick = () => { modalOverlay.remove(); };
};
const checkForUpdates = () => {
try {
const localVersion = GM_info.script.version;
GM_xmlhttpRequest({
method: 'GET',
url: SCRIPT_UPDATE_URL,
onload: function(response) {
if (response.status !== 200) return;
const remoteVersionMatch = response.responseText.match(/@version\s+([0-9.]+)/);
if (remoteVersionMatch && remoteVersionMatch[1]) {
if (remoteVersionMatch[1] > localVersion) {
showUpdateModal();
}
}
}
});
} catch (e) { console.error('TrixBox: Update check failed.', e); }
};
// --- 2. CREATE THE TOGGLE ICON ---
const toggleIcon = document.createElement('div');
toggleIcon.id = 'trixbox-toggle-icon';
toggleIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="${theme.text}" width="28px" height="28px"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z"/></svg>`;
// **FIX IS HERE**: Changed z-index to zIndex
Object.assign(toggleIcon.style, {
backgroundColor: theme.icon,
position: 'fixed', bottom: '20px', right: '20px', width: '50px', height: '50px',
borderRadius: '50%', display: 'flex', alignItems: 'center',
justifyContent: 'center', cursor: 'pointer', zIndex: '99998',
boxShadow: '0 2px 8px rgba(0,0,0,0.3)', transition: 'transform 0.2s ease-in-out'
});
toggleIcon.onmouseover = () => { toggleIcon.style.transform = 'scale(1.1)'; };
toggleIcon.onmouseout = () => { toggleIcon.style.transform = 'scale(1.0)'; };
document.body.appendChild(toggleIcon);
// --- 3. CREATE THE CHATBOX AND LINK BLOCKERS ---
const chatContainer = document.createElement('div');
chatContainer.id = 'trixbox-container';
Object.assign(chatContainer.style, {
position: 'fixed', bottom: '15px', right: '15px', width: '350px', height: '500px',
zIndex: '99999', display: 'none', flexDirection: 'column',
boxShadow: '0 4px 12px rgba(0,0,0,0.3)', borderRadius: '8px', overflow: 'hidden'
});
const dragHeader = document.createElement('div');
dragHeader.id = 'trixbox-header';
Object.assign(dragHeader.style, {
height: '30px', backgroundColor: 'rgb(210, 210, 255)', cursor: 'move',
userSelect: 'none', display: 'flex', alignItems: 'center',
justifyContent: 'space-between', padding: '0 5px 0 15px'
});
const headerTitle = document.createElement('span');
headerTitle.textContent = 'TrixBox Chat';
Object.assign(headerTitle.style, {
color: 'white', fontWeight: 'bold', fontSize: '14px',
textShadow: '1px 1px 0 rgb(160, 160, 230), 2px 2px 0 rgba(0, 0, 0, 0.15)'
});
dragHeader.appendChild(headerTitle);
const closeButton = document.createElement('button');
closeButton.innerHTML = '×';
Object.assign(closeButton.style, {
background: 'none', border: 'none', color: 'rgb(80, 80, 120)',
fontSize: '24px', lineHeight: '1', cursor: 'pointer', padding: '0 8px'
});
dragHeader.appendChild(closeButton);
chatContainer.appendChild(dragHeader);
const iframeWrapper = document.createElement('div');
Object.assign(iframeWrapper.style, { position: 'relative', flexGrow: '1' });
chatContainer.appendChild(iframeWrapper);
const chatLibraryScript = document.createElement('script');
chatLibraryScript.src = 'https://iframe.chat/scripts/main.min.js';
document.head.appendChild(chatLibraryScript);
const chatIframe = document.createElement('iframe');
chatIframe.src = 'https://iframe.chat/embed?chat=15234533';
chatIframe.id = 'chattable';
Object.assign(chatIframe.style, {
width: '100%', height: '100%', border: 'none',
backgroundColor: 'transparent'
});
iframeWrapper.appendChild(chatIframe);
document.body.appendChild(chatContainer);
const headerLinkBlocker = document.createElement('div');
Object.assign(headerLinkBlocker.style, { position: 'absolute', top: '0px', left: '0px', width: '100px', height: '45px', zIndex: '2' });
iframeWrapper.appendChild(headerLinkBlocker);
const settingsLinkBlocker = document.createElement('div');
Object.assign(settingsLinkBlocker.style, {
position: 'absolute', bottom: '12px', left: '50%',
transform: 'translateX(-50%)',
width: '140px',
height: '25px',
zIndex: '2'
});
iframeWrapper.appendChild(settingsLinkBlocker);
// --- 4. ADD FUNCTIONALITY (TOGGLE, DRAG, ETC.) ---
toggleIcon.addEventListener('click', () => { chatContainer.style.display = 'flex'; toggleIcon.style.display = 'none'; });
closeButton.addEventListener('click', (e) => {
e.stopPropagation();
chatContainer.style.display = 'none';
toggleIcon.style.display = 'flex';
});
let isDragging = false, offsetX, offsetY;
dragHeader.addEventListener('mousedown', (e) => {
if (e.target !== dragHeader && e.target !== headerTitle) return;
isDragging = true;
offsetX = e.clientX - chatContainer.getBoundingClientRect().left;
offsetY = e.clientY - chatContainer.getBoundingClientRect().top;
chatIframe.style.pointerEvents = 'none';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
chatContainer.style.left = `${e.clientX - offsetX}px`;
chatContainer.style.top = `${e.clientY - offsetY}px`;
chatContainer.style.bottom = 'auto';
chatContainer.style.right = 'auto';
});
document.addEventListener('mouseup', () => {
if (!isDragging) return;
isDragging = false;
chatIframe.style.pointerEvents = 'auto';
});
chatLibraryScript.onload = function() {
if (typeof chattable !== 'undefined') {
chattable.initialize({
theme: "tendo"
});
}
};
// --- 5. RUN THE UPDATE CHECKER ---
checkForUpdates();
})();