您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
tester
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/534027/1591211/koc%20chatv2.js
Tabs.TabDemo = { tabOrder: 8001, tabLabel: 'Truce/AP Monitor', tabColor: 'blue', myDiv: null, targets: [], checkInterval: null, isInitialized: false, init: function(div) { var t = this; t.myDiv = div; t.myDiv.style.display = 'none'; t.updateStatus('Initializing...'); try { t.loadTargets(); t.updateStatus('Ready to monitor targets'); t.isInitialized = true; } catch (error) { console.error('Error initializing tab:', error); t.updateStatus('Error: ' + error.message); } }, paint: function() { var t = this; if (!t.isInitialized) { t.updateStatus('Please initialize first'); return; } var m = ` <div class="divHeader" align="center">Truce/AP Monitor</div> <div class="monitorContainer"> <div class="inputGroup"> <label for="targetInput">Player Name/UID:</label> <input type="text" id="targetInput" class="btInput" /> <button id="addTargetButton" class="buttonv2 std blue">Add Target</button> </div> <div id="targetList" class="targetList"></div> <div id="truceMonitorStatus" class="statusMessage"></div> </div> `; t.myDiv.innerHTML = m; var style = document.createElement('style'); style.textContent = ` .monitorContainer { width: 100%; max-width: 600px; padding: 15px; background: #f5f5f5; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .inputGroup { display: flex; gap: 10px; margin-bottom: 20px; } .btInput { flex: 1; padding: 8px; border: 1px solid #ccc; border-radius: 4px; background: #fff; color: #333; } .statusMessage { font-size: 14px; color: #666; text-align: center; margin-top: 20px; padding: 10px; background: #fff; border-radius: 4px; border: 1px solid #eee; } .targetList { margin: 20px 0; padding: 15px; background: #fff; border-radius: 4px; border: 1px solid #eee; } .targetList ul { list-style: none; padding: 0; margin: 0; } .targetList li { padding: 10px; border-bottom: 1px solid #eee; margin-bottom: 5px; display: flex; justify-content: space-between; align-items: center; } .targetList li:last-child { border-bottom: none; margin-bottom: 0; } .targetList li:hover { background-color: #f9f9f9; } .truceNotification { position: fixed; top: 20px; right: 20px; background: #4CAF50; color: white; padding: 15px; border-radius: 5px; z-index: 1000; box-shadow: 0 2px 10px rgba(0,0,0,0.2); max-width: 300px; word-wrap: break-word; animation: slideIn 0.3s ease-out; } @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .buttonv2 { background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; font-weight: bold; transition: background 0.2s; } .buttonv2:hover { background: #3a7bc8; } .buttonv2.blue { background: #4a90e2; } .buttonv2.blue:hover { background: #3a7bc8; } `; document.head.appendChild(style); t.displayTargetList(); $("#addTargetButton", t.myDiv).click(function() { t.addTarget(); }); if (!t.checkInterval) { t.checkInterval = setInterval(function() { try { t.checkTrucesAndAP(); } catch (error) { console.error('Error checking truces/AP:', error); t.updateStatus('Error: ' + error.message); } }, 1000); } }, hide: function() { var t = this; if (t.checkInterval) { clearInterval(t.checkInterval); t.checkInterval = null; } t.myDiv.style.display = 'none'; t.updateStatus(''); }, show: function() { var t = this; t.myDiv.style.display = 'block'; t.displayTargetList(); t.updateStatus('Monitoring targets...'); }, addTarget: function() { var t = this; var targetInput = $("#targetInput", t.myDiv); var targetName = targetInput.val().trim(); if (!targetName) { t.updateStatus('Please enter a target name or UID'); return; } try { var player = getPlayerInfo(targetName); if (!player) { throw new Error('Player not found'); } var existing = t.targets.find(function(tgt) { return tgt.uid === player.uid; }); if (existing) { throw new Error('Player is already being monitored'); } t.targets.push({ name: player.name, uid: player.uid }); t.saveTargets(); t.displayTargetList(); t.updateStatus(`Added target: ${player.name}`); targetInput.val(''); } catch (error) { console.error('Error adding target:', error); t.updateStatus('Error: ' + error.message); } }, displayTargetList: function() { var t = this; var targetList = $("#targetList", t.myDiv); targetList.empty(); if (t.targets.length === 0) { targetList.append( '<div class="noTargets">No targets are currently being monitored.</div>' ); return; } var html = "<ul>"; t.targets.forEach(function(target) { html += ` <li> <div class="targetInfo"> <span class="targetName">${target.name}</span> <span class="targetUID">(${target.uid})</span> </div> </li>`; }); html += "</ul>"; targetList.html(html); }, updateStatus: function(message) { var t = this; var statusEl = $("#truceMonitorStatus", t.myDiv); statusEl.html(message); if (message.includes('Error')) { statusEl.css({ 'color': '#dc3545', 'background-color': '#f8d7da' }); } else { statusEl.css({ 'color': '#28a745', 'background-color': '#d4edda' }); } }, checkTrucesAndAP: function() { var t = this; t.targets.forEach(function(target) { checkPlayerTrucesAndAP(target.uid) .then(function(result) { if (result.hasTruce) { t.updateStatus(`Target ${target.name} has truce with ${result.truceWith}`); } else if (result.apEnded) { t.notifyAPEnded(target); } }) .catch(function(error) { console.error('Error checking target:', error); t.updateStatus(`Error checking ${target.name}: ${error.message}`); }); }); }, notifyAPEnded: function(target) { var t = this; try { t.updateStatus("Target " + target.name + "'s AP has ended!"); t.playNotificationSound(); t.showNotification(target.name + "'s AP has ended!"); } catch (error) { console.error('Error notifying AP end:', error); t.updateStatus('Error: ' + error.message); } }, showNotification: function(message) { var t = this; var notification = document.createElement('div'); notification.className = 'truceNotification'; notification.textContent = message; document.body.appendChild(notification); setTimeout(function() { notification.remove(); }, 5000); }, playNotificationSound: function() { // Implementation for playing notification sound try { var audio = new Audio('notification.mp3'); audio.play().catch(function(error) { console.error('Error playing sound:', error); }); } catch (error) { console.error('Error with audio:', error); } }, loadTargets: function() { var t = this; try { var saved = localStorage.getItem('truceMonitorTargets'); if (saved) { t.targets = JSON.parse(saved); } } catch (error) { console.error('Error loading targets:', error); t.targets = []; } }, saveTargets: function() { var t = this; try { localStorage.setItem('truceMonitorTargets', JSON.stringify(t.targets)); } catch (error) { console.error('Error saving targets:', error); } } }; // Simple initialization for the tab (function() { // Wait for the game to be ready function init() { // Check if we can access the game's Tabs object var gameTabs = window.Tabs || (window.unsafeWindow && unsafeWindow.Tabs); if (gameTabs && gameTabs.addTab) { try { // Add our tab to the game's UI gameTabs.addTab(Tabs.TabDemo); console.log('Truce/AP Monitor tab added'); // Save the original showTab function var originalShowTab = gameTabs.showTab; // Override showTab to handle our tab gameTabs.showTab = function(tab) { // Call the original function originalShowTab.apply(this, arguments); // Handle our tab if (tab === 'TabDemo') { var tabDiv = document.getElementById('tab_TabDemo'); if (tabDiv) { if (!Tabs.TabDemo.isInitialized) { Tabs.TabDemo.init(tabDiv); } Tabs.TabDemo.paint(); } } }; return; // Success, exit the function } catch (e) { console.error('Error initializing tab:', e); } } // If we got here, try again in 500ms setTimeout(init, 500); } // Start the initialization if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();