Auto Luarmor

Finds the elements on the page such as +12H, next, start, etc.. and clicks them at the appropriate times so you never have to do luarmor yourself again! (Code was written by ChatGPT)

当前为 2025-05-07 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Auto Luarmor
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.1.2
  5. // @description Finds the elements on the page such as +12H, next, start, etc.. and clicks them at the appropriate times so you never have to do luarmor yourself again! (Code was written by ChatGPT)
  6. // @author Chatgpt
  7. // @license MIT
  8. // @match https://ads.luarmor.net/get_key*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12.  
  13. (function () {
  14. 'use strict';
  15.  
  16. let scriptPaused = false;
  17.  
  18. const selectors = {
  19. nextButton: '#nextbtn',
  20. addTimeButton: '#addtimebtn_cCtbsGjODTFXrIHLDiAPYCQDsOlttPwz',
  21. progressText: '#adprogressp',
  22. newKeyButton: '#newkeybtn',
  23. captchaCheckText: 'h1',
  24. keyTimeLeft: '#_timeleft_cCtbsGjODTFXrIHLDiAPYCQDsOlttPwz',
  25. blacklistTitle: '#swal2-title',
  26. blacklistTimeText: 'p.text-sm',
  27. keyValue: 'h6.mb-0.text-sm' // Selector for the key
  28. };
  29.  
  30. function isInPopupWindow() {
  31. return window.name === 'luarmor_popup';
  32. }
  33.  
  34. function parseTimeToMs(timeStr) {
  35. const parts = timeStr.split(':').map(Number);
  36. if (parts.length === 3) {
  37. const [h, m, s] = parts;
  38. return ((h * 60 + m) * 60 + s) * 1000;
  39. } else {
  40. const match = timeStr.match(/(\d+)\s*hours?\s*(\d+)\s*minutes?/i);
  41. if (match) {
  42. const [, h, m] = match.map(Number);
  43. return ((h * 60 + m) * 60) * 1000;
  44. }
  45. }
  46. return 0;
  47. }
  48.  
  49. function flashTitle(message, duration = 3000) {
  50. const originalTitle = document.title;
  51. let visible = true;
  52. const interval = 500;
  53. const flashCount = Math.floor(duration / interval);
  54. let i = 0;
  55. const flasher = setInterval(() => {
  56. document.title = visible ? message : originalTitle;
  57. visible = !visible;
  58. i++;
  59. if (i >= flashCount) {
  60. clearInterval(flasher);
  61. document.title = originalTitle;
  62. }
  63. }, interval);
  64. }
  65.  
  66. function updateStatus(msg) {
  67. const statusText = document.getElementById('luarmor-status-text');
  68. if (statusText) statusText.textContent = msg;
  69. console.log(msg);
  70. }
  71.  
  72. function updateUITimers() {
  73. // Update active key time if available
  74. const timeLeftElem = document.querySelector(selectors.keyTimeLeft);
  75. if (timeLeftElem) {
  76. document.getElementById('luarmor-timeleft').textContent = timeLeftElem.textContent.trim();
  77. }
  78.  
  79. // Update key from the page
  80. const keyElem = document.querySelector(selectors.keyValue);
  81. if (keyElem) {
  82. document.getElementById('luarmor-key').textContent = keyElem.textContent.trim();
  83. }
  84. // Directly read cooldown time from DOM
  85. const nextBtn = document.querySelector(selectors.nextButton);
  86. const cooldownElem = document.getElementById('luarmor-cooldown');
  87.  
  88. if (nextBtn && cooldownElem) {
  89. if (nextBtn.style.cursor === 'not-allowed') {
  90. // Extract the visible time from the button's text
  91. const match = nextBtn.textContent.match(/\d{2}:\d{2}:\d{2}/);
  92. cooldownElem.textContent = match ? match[0] : 'Waiting...';
  93. } else {
  94. cooldownElem.textContent = 'None';
  95. }
  96. }
  97.  
  98. // Only update blacklist time and cooldown if blacklisted
  99. const isBlacklisted = document.querySelector(selectors.blacklistTitle)?.textContent.includes("Temporarily Blacklisted");
  100. if (isBlacklisted) {
  101. const blacklistTextElem = document.querySelector(selectors.blacklistTimeText);
  102. if (blacklistTextElem) {
  103. const blacklistTime = blacklistTextElem.textContent.replace("You can continue in:", '').trim();
  104. document.getElementById('luarmor-blacklist').textContent = blacklistTime;
  105.  
  106. const ms = parseTimeToMs(blacklistTime);
  107. const h = String(Math.floor(ms / 3600000)).padStart(2, '0');
  108. const m = String(Math.floor((ms % 3600000) / 60000)).padStart(2, '0');
  109. const s = String(Math.floor((ms % 60000) / 1000)).padStart(2, '0');
  110. document.getElementById('luarmor-cooldown').textContent = `${h}:${m}:${s}`;
  111. }
  112. } else {
  113. document.getElementById('luarmor-blacklist').textContent = 'None';
  114. document.getElementById('luarmor-cooldown').textContent = 'None';
  115. }
  116. }
  117.  
  118. function checkBlacklist() {
  119. const title = document.querySelector(selectors.blacklistTitle);
  120. if (title && title.textContent.includes("Temporarily Blacklisted")) {
  121. const timeText = document.querySelector(selectors.blacklistTimeText)?.textContent;
  122. if (timeText) {
  123. const ms = parseTimeToMs(timeText);
  124. updateStatus("⛔ Blacklisted. Waiting...");
  125. const blacklistTime = timeText.replace("You can continue in:", '').trim();
  126. document.getElementById('luarmor-blacklist').textContent = blacklistTime;
  127.  
  128. const h = String(Math.floor(ms / 3600000)).padStart(2, '0');
  129. const m = String(Math.floor((ms % 3600000) / 60000)).padStart(2, '0');
  130. const s = String(Math.floor((ms % 60000) / 1000)).padStart(2, '0');
  131. document.getElementById('luarmor-cooldown').textContent = `${h}:${m}:${s}`;
  132.  
  133. setTimeout(() => {
  134. location.reload();
  135. }, ms);
  136. return true;
  137. }
  138. }
  139. return false;
  140. }
  141.  
  142. let cooldownInterval;
  143.  
  144. function handleCooldownAndClickStart() {
  145. if (scriptPaused) return;
  146. updateUITimers();
  147.  
  148. const nextBtn = document.querySelector(selectors.nextButton);
  149. if (!nextBtn) return console.log("❌ Next button not found.");
  150.  
  151. if (nextBtn.style.cursor === 'not-allowed') {
  152. clearInterval(cooldownInterval); // prevent duplicates
  153.  
  154. cooldownInterval = setInterval(() => {
  155. if (scriptPaused) return;
  156. const btn = document.querySelector(selectors.nextButton);
  157. if (!btn || btn.style.cursor !== 'not-allowed') {
  158. clearInterval(cooldownInterval);
  159. return;
  160. }
  161. const match = btn.textContent.match(/\d{2}:\d{2}:\d{2}/);
  162. if (match) updateStatus(`⏳ Cooldown: ${match[0]}`);
  163. }, 1000);
  164.  
  165. const match = nextBtn.textContent.match(/\d{2}:\d{2}:\d{2}/);
  166. const ms = match ? parseTimeToMs(match[0]) : 0;
  167.  
  168. if (ms > 3000) {
  169. setTimeout(() => {
  170. if (scriptPaused) return;
  171. window.focus();
  172. flashTitle("⏰ Cooldown Ending!");
  173. }, ms - 3000);
  174. }
  175.  
  176. setTimeout(() => {
  177. if (scriptPaused) return;
  178. const btn = document.querySelector(selectors.nextButton);
  179. if (btn?.style.cursor !== 'not-allowed') {
  180. clearInterval(cooldownInterval);
  181. btn.click();
  182. updateStatus("🟢 Clicked Start.");
  183. setTimeout(() => window.close(), 1000);
  184. }
  185. }, ms + 1000);
  186. } else {
  187. nextBtn.click();
  188. updateStatus("🟢 Clicked Start.");
  189. setTimeout(() => window.close(), 1000);
  190. }
  191. }
  192.  
  193. function handleProgressCheck() {
  194. if (scriptPaused) return;
  195.  
  196. const progress = document.querySelector(selectors.progressText);
  197. if (!progress) return console.log("❌ Progress not found.");
  198.  
  199. if (progress.textContent.includes("2/2")) {
  200. const addBtn = document.querySelector(selectors.addTimeButton);
  201. if (addBtn && !addBtn.classList.contains('disabled')) {
  202. addBtn.click();
  203. updateStatus("🟢 Clicked +12H.");
  204. return;
  205. }
  206.  
  207. const timeLeft = document.querySelector(selectors.keyTimeLeft);
  208. const ms = timeLeft ? parseTimeToMs(timeLeft.textContent.trim()) : 0;
  209. if (ms > 12 * 60 * 60 * 1000) {
  210. updateStatus("🕒 Max time. Retry in 12h.");
  211. setTimeout(handleProgressCheck, 12 * 60 * 60 * 1000 + 1000);
  212. return;
  213. }
  214.  
  215. const newKey = document.querySelector(selectors.newKeyButton);
  216. if (newKey && !newKey.disabled) {
  217. newKey.click();
  218. updateStatus("🟢 Clicked new key.");
  219. }
  220. } else {
  221. handleCooldownAndClickStart();
  222. }
  223. }
  224.  
  225. function checkCaptchaAndProceed() {
  226. if (scriptPaused) return;
  227.  
  228. const check = document.querySelector(selectors.captchaCheckText);
  229. if (check?.textContent.includes("Checking Your Browser")) {
  230. updateStatus("⏳ CAPTCHA detected...");
  231. setTimeout(checkCaptchaAndProceed, 3000);
  232. } else {
  233. updateStatus("🟢 Proceeding.");
  234. setTimeout(handleProgressCheck, 1000);
  235. }
  236. }
  237.  
  238. function injectUI() {
  239. const style = document.createElement('style');
  240. style.textContent = `
  241. #luarmor-status-box {
  242. position: fixed;
  243. top: 10px;
  244. left: 10px;
  245. background: rgba(0,0,0,0.85);
  246. color: #0f0;
  247. padding: 12px 16px;
  248. border-radius: 10px;
  249. font-family: monospace;
  250. font-size: 14px;
  251. z-index: 9999;
  252. box-shadow: 0 0 12px rgba(0,255,0,0.5);
  253. transition: opacity 0.5s ease;
  254. max-width: 320px;
  255. }
  256. #luarmor-logo {
  257. position: fixed;
  258. bottom: 10px;
  259. right: 10px;
  260. width: 50px;
  261. height: 50px;
  262. background: url('https://upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Green_check.svg/1024px-Green_check.svg.png') no-repeat center;
  263. background-size: contain;
  264. opacity: 0.7;
  265. z-index: 9998;
  266. }
  267. #luarmor-status-box .extra {
  268. margin-top: 8px;
  269. font-size: 12px;
  270. color: #aaa;
  271. }
  272. #luarmor-status-box .extra strong {
  273. color: #0f0;
  274. }
  275. `;
  276. document.head.appendChild(style);
  277.  
  278. const box = document.createElement('div');
  279. box.id = 'luarmor-status-box';
  280. box.innerHTML = `
  281. <div id="luarmor-status-text">🚀 Script initialized</div>
  282. <button id="luarmor-pause-btn" style="margin-top: 8px; background:#222; color:#0f0; border:1px solid #0f0; padding:4px 8px; border-radius:6px; cursor:pointer;">
  283. ⏸️ Pause Script
  284. </button>
  285. <div class="extra">
  286. 🔐 Key: <strong id="luarmor-key">loading...</strong><br>
  287. ⏱️ Time Left: <strong id="luarmor-timeleft">loading...</strong><br>
  288. Blacklist: <strong id="luarmor-blacklist">None</strong><br>
  289. 🕒 Cooldown: <strong id="luarmor-cooldown">None</strong>
  290. </div>
  291. `;
  292.  
  293. document.body.appendChild(box);
  294.  
  295. const pauseBtn = document.getElementById('luarmor-pause-btn');
  296. pauseBtn.addEventListener('click', () => {
  297. scriptPaused = !scriptPaused;
  298. pauseBtn.textContent = scriptPaused ? '▶️ Resume Script' : '⏸️ Pause Script';
  299. updateStatus(scriptPaused ? '⏸️ Script paused by user.' : '▶️ Script resumed.');
  300. if (!scriptPaused) checkCaptchaAndProceed();
  301. });
  302.  
  303. const logo = document.createElement('div');
  304. logo.id = 'luarmor-logo';
  305. document.body.appendChild(logo);
  306. }
  307.  
  308. window.addEventListener("load", () => {
  309. if (isInPopupWindow()) {
  310. window.name = 'luarmor_popup';
  311. console.log("✅ Running in popup.");
  312. flashTitle("🚀 Script Started!");
  313. injectUI();
  314. if (!checkBlacklist()) checkCaptchaAndProceed();
  315. setInterval(updateUITimers, 1000);
  316. } else {
  317. if (!window.popupOpenedOnce) {
  318. const popup = window.open(window.location.href, '_blank', 'width=500,height=600');
  319. if (popup) {
  320. popup.name = 'luarmor_popup';
  321. window.popupOpenedOnce = true;
  322. setTimeout(() => window.close(), 500);
  323. } else {
  324. console.log("❌ Failed to open popup.");
  325. }
  326. }
  327. }
  328. });
  329. })();