이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greasyfork.ip-ddns.com/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();
}
})();