kocmapper

tester

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/534027/1591211/kocmapper.js

  1. Tabs.TabDemo = {
  2. tabOrder: 8001,
  3. tabLabel: 'Truce/AP Monitor',
  4. tabColor: 'blue',
  5. myDiv: null,
  6. targets: [],
  7. checkInterval: null,
  8. isInitialized: false,
  9.  
  10. init: function(div) {
  11. var t = this;
  12. t.myDiv = div;
  13. t.myDiv.style.display = 'none';
  14. t.updateStatus('Initializing...');
  15.  
  16. try {
  17. t.loadTargets();
  18. t.updateStatus('Ready to monitor targets');
  19. t.isInitialized = true;
  20. } catch (error) {
  21. console.error('Error initializing tab:', error);
  22. t.updateStatus('Error: ' + error.message);
  23. }
  24. },
  25.  
  26. paint: function() {
  27. var t = this;
  28. if (!t.isInitialized) {
  29. t.updateStatus('Please initialize first');
  30. return;
  31. }
  32.  
  33. var m = `
  34. <div class="divHeader" align="center">Truce/AP Monitor</div>
  35. <div class="monitorContainer">
  36. <div class="inputGroup">
  37. <label for="targetInput">Player Name/UID:</label>
  38. <input type="text" id="targetInput" class="btInput" />
  39. <button id="addTargetButton" class="buttonv2 std blue">Add Target</button>
  40. </div>
  41. <div id="targetList" class="targetList"></div>
  42. <div id="truceMonitorStatus" class="statusMessage"></div>
  43. </div>
  44. `;
  45.  
  46. t.myDiv.innerHTML = m;
  47.  
  48. var style = document.createElement('style');
  49. style.textContent = `
  50. .monitorContainer {
  51. width: 100%;
  52. max-width: 600px;
  53. padding: 15px;
  54. background: #f5f5f5;
  55. border-radius: 8px;
  56. box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  57. }
  58.  
  59. .inputGroup {
  60. display: flex;
  61. gap: 10px;
  62. margin-bottom: 20px;
  63. }
  64.  
  65. .btInput {
  66. flex: 1;
  67. padding: 8px;
  68. border: 1px solid #ccc;
  69. border-radius: 4px;
  70. background: #fff;
  71. color: #333;
  72. }
  73.  
  74. .statusMessage {
  75. font-size: 14px;
  76. color: #666;
  77. text-align: center;
  78. margin-top: 20px;
  79. padding: 10px;
  80. background: #fff;
  81. border-radius: 4px;
  82. border: 1px solid #eee;
  83. }
  84.  
  85. .targetList {
  86. margin: 20px 0;
  87. padding: 15px;
  88. background: #fff;
  89. border-radius: 4px;
  90. border: 1px solid #eee;
  91. }
  92.  
  93. .targetList ul {
  94. list-style: none;
  95. padding: 0;
  96. margin: 0;
  97. }
  98. .targetList li {
  99. padding: 10px;
  100. border-bottom: 1px solid #eee;
  101. margin-bottom: 5px;
  102. display: flex;
  103. justify-content: space-between;
  104. align-items: center;
  105. }
  106. .targetList li:last-child {
  107. border-bottom: none;
  108. margin-bottom: 0;
  109. }
  110. .targetList li:hover {
  111. background-color: #f9f9f9;
  112. }
  113. .truceNotification {
  114. position: fixed;
  115. top: 20px;
  116. right: 20px;
  117. background: #4CAF50;
  118. color: white;
  119. padding: 15px;
  120. border-radius: 5px;
  121. z-index: 1000;
  122. box-shadow: 0 2px 10px rgba(0,0,0,0.2);
  123. max-width: 300px;
  124. word-wrap: break-word;
  125. animation: slideIn 0.3s ease-out;
  126. }
  127. @keyframes slideIn {
  128. from { transform: translateX(100%); opacity: 0; }
  129. to { transform: translateX(0); opacity: 1; }
  130. }
  131. .buttonv2 {
  132. background: #4a90e2;
  133. color: white;
  134. border: none;
  135. padding: 8px 16px;
  136. border-radius: 4px;
  137. cursor: pointer;
  138. font-weight: bold;
  139. transition: background 0.2s;
  140. }
  141. .buttonv2:hover {
  142. background: #3a7bc8;
  143. }
  144. .buttonv2.blue {
  145. background: #4a90e2;
  146. }
  147. .buttonv2.blue:hover {
  148. background: #3a7bc8;
  149. }
  150. `;
  151. document.head.appendChild(style);
  152.  
  153. t.displayTargetList();
  154.  
  155. $("#addTargetButton", t.myDiv).click(function() {
  156. t.addTarget();
  157. });
  158.  
  159. if (!t.checkInterval) {
  160. t.checkInterval = setInterval(function() {
  161. try {
  162. t.checkTrucesAndAP();
  163. } catch (error) {
  164. console.error('Error checking truces/AP:', error);
  165. t.updateStatus('Error: ' + error.message);
  166. }
  167. }, 1000);
  168. }
  169. },
  170.  
  171. hide: function() {
  172. var t = this;
  173. if (t.checkInterval) {
  174. clearInterval(t.checkInterval);
  175. t.checkInterval = null;
  176. }
  177. t.myDiv.style.display = 'none';
  178. t.updateStatus('');
  179. },
  180.  
  181. show: function() {
  182. var t = this;
  183. t.myDiv.style.display = 'block';
  184. t.displayTargetList();
  185. t.updateStatus('Monitoring targets...');
  186. },
  187.  
  188. addTarget: function() {
  189. var t = this;
  190. var targetInput = $("#targetInput", t.myDiv);
  191. var targetName = targetInput.val().trim();
  192.  
  193. if (!targetName) {
  194. t.updateStatus('Please enter a target name or UID');
  195. return;
  196. }
  197.  
  198. try {
  199. var player = getPlayerInfo(targetName);
  200. if (!player) {
  201. throw new Error('Player not found');
  202. }
  203.  
  204. var existing = t.targets.find(function(tgt) {
  205. return tgt.uid === player.uid;
  206. });
  207. if (existing) {
  208. throw new Error('Player is already being monitored');
  209. }
  210.  
  211. t.targets.push({
  212. name: player.name,
  213. uid: player.uid
  214. });
  215.  
  216. t.saveTargets();
  217. t.displayTargetList();
  218. t.updateStatus(`Added target: ${player.name}`);
  219. targetInput.val('');
  220.  
  221. } catch (error) {
  222. console.error('Error adding target:', error);
  223. t.updateStatus('Error: ' + error.message);
  224. }
  225. },
  226.  
  227. displayTargetList: function() {
  228. var t = this;
  229. var targetList = $("#targetList", t.myDiv);
  230. targetList.empty();
  231.  
  232. if (t.targets.length === 0) {
  233. targetList.append(
  234. '<div class="noTargets">No targets are currently being monitored.</div>'
  235. );
  236. return;
  237. }
  238.  
  239. var html = "<ul>";
  240. t.targets.forEach(function(target) {
  241. html += `
  242. <li>
  243. <div class="targetInfo">
  244. <span class="targetName">${target.name}</span>
  245. <span class="targetUID">(${target.uid})</span>
  246. </div>
  247. </li>`;
  248. });
  249. html += "</ul>";
  250. targetList.html(html);
  251. },
  252.  
  253. updateStatus: function(message) {
  254. var t = this;
  255. var statusEl = $("#truceMonitorStatus", t.myDiv);
  256. statusEl.html(message);
  257. if (message.includes('Error')) {
  258. statusEl.css({
  259. 'color': '#dc3545',
  260. 'background-color': '#f8d7da'
  261. });
  262. } else {
  263. statusEl.css({
  264. 'color': '#28a745',
  265. 'background-color': '#d4edda'
  266. });
  267. }
  268. },
  269.  
  270. checkTrucesAndAP: function() {
  271. var t = this;
  272. t.targets.forEach(function(target) {
  273. checkPlayerTrucesAndAP(target.uid)
  274. .then(function(result) {
  275. if (result.hasTruce) {
  276. t.updateStatus(`Target ${target.name} has truce with ${result.truceWith}`);
  277. } else if (result.apEnded) {
  278. t.notifyAPEnded(target);
  279. }
  280. })
  281. .catch(function(error) {
  282. console.error('Error checking target:', error);
  283. t.updateStatus(`Error checking ${target.name}: ${error.message}`);
  284. });
  285. });
  286. },
  287.  
  288. notifyAPEnded: function(target) {
  289. var t = this;
  290. try {
  291. t.updateStatus("Target " + target.name + "'s AP has ended!");
  292. t.playNotificationSound();
  293. t.showNotification(target.name + "'s AP has ended!");
  294. } catch (error) {
  295. console.error('Error notifying AP end:', error);
  296. t.updateStatus('Error: ' + error.message);
  297. }
  298. },
  299.  
  300. showNotification: function(message) {
  301. var t = this;
  302. var notification = document.createElement('div');
  303. notification.className = 'truceNotification';
  304. notification.textContent = message;
  305. document.body.appendChild(notification);
  306.  
  307. setTimeout(function() {
  308. notification.remove();
  309. }, 5000);
  310. },
  311.  
  312. playNotificationSound: function() {
  313. // Implementation for playing notification sound
  314. try {
  315. var audio = new Audio('notification.mp3');
  316. audio.play().catch(function(error) {
  317. console.error('Error playing sound:', error);
  318. });
  319. } catch (error) {
  320. console.error('Error with audio:', error);
  321. }
  322. },
  323.  
  324. loadTargets: function() {
  325. var t = this;
  326. try {
  327. var saved = localStorage.getItem('truceMonitorTargets');
  328. if (saved) {
  329. t.targets = JSON.parse(saved);
  330. }
  331. } catch (error) {
  332. console.error('Error loading targets:', error);
  333. t.targets = [];
  334. }
  335. },
  336.  
  337. saveTargets: function() {
  338. var t = this;
  339. try {
  340. localStorage.setItem('truceMonitorTargets', JSON.stringify(t.targets));
  341. } catch (error) {
  342. console.error('Error saving targets:', error);
  343. }
  344. }
  345. };
  346.  
  347. // Simple initialization for the tab
  348. (function() {
  349. // Wait for the game to be ready
  350. function init() {
  351. // Check if we can access the game's Tabs object
  352. var gameTabs = window.Tabs || (window.unsafeWindow && unsafeWindow.Tabs);
  353. if (gameTabs && gameTabs.addTab) {
  354. try {
  355. // Add our tab to the game's UI
  356. gameTabs.addTab(Tabs.TabDemo);
  357. console.log('Truce/AP Monitor tab added');
  358. // Save the original showTab function
  359. var originalShowTab = gameTabs.showTab;
  360. // Override showTab to handle our tab
  361. gameTabs.showTab = function(tab) {
  362. // Call the original function
  363. originalShowTab.apply(this, arguments);
  364. // Handle our tab
  365. if (tab === 'TabDemo') {
  366. var tabDiv = document.getElementById('tab_TabDemo');
  367. if (tabDiv) {
  368. if (!Tabs.TabDemo.isInitialized) {
  369. Tabs.TabDemo.init(tabDiv);
  370. }
  371. Tabs.TabDemo.paint();
  372. }
  373. }
  374. };
  375. return; // Success, exit the function
  376. } catch (e) {
  377. console.error('Error initializing tab:', e);
  378. }
  379. }
  380. // If we got here, try again in 500ms
  381. setTimeout(init, 500);
  382. }
  383. // Start the initialization
  384. if (document.readyState === 'loading') {
  385. document.addEventListener('DOMContentLoaded', init);
  386. } else {
  387. init();
  388. }
  389. })();