RubixYT1

KiwiTest's keyboard script

Jul 4th, 2026
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.94 KB | None | 0 0
  1. // Assumed environment functions:
  2. // writeCharAt(char, color, x, y)
  3. // w.on('cursor', callback)
  4. // w.cursors()
  5.  
  6. // Color IDs
  7. const CID = {
  8. BLACK: 0, GRAY: 1, LIME: 8, YELLOW: 7, CYAN: 10, WHITE: 15, RED: 4
  9. };
  10.  
  11. // Authorization List
  12. const Auth = ["KiwiTest", "Ultimer"];
  13.  
  14. // State variables
  15. let fieldText = "";
  16. let shiftActive = false;
  17. let symActive = false;
  18. let lastChar = "";
  19. let authOnly = true;
  20. let miniHudVisible = true;
  21. let startTime = Date.now();
  22.  
  23. const userCooldowns = {};
  24. const lastPositions = {};
  25. const keyMap = {};
  26.  
  27. // HUD State
  28. let scriptRunning = true;
  29. let hudMinimized = false;
  30. let autoRefreshEnabled = true;
  31. let hudKeyMap = {};
  32. let pollingInterval = null;
  33. let timerInterval = null;
  34. let floatingHudEl = null;
  35. let floatingHudStyleEl = null;
  36.  
  37. // Animation Queue Control
  38. let animAbortFlag = { stop: false };
  39.  
  40. // Invert Y-axis wrapper
  41. function draw(char, color, x, y) {
  42. if (!scriptRunning) return;
  43. writeCharAt(char, color, x, -y);
  44. }
  45.  
  46. function drawString(str, color, x, y) {
  47. for (let i = 0; i < str.length; i++) draw(str[i], color, x + i, y);
  48. }
  49.  
  50. const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
  51.  
  52. // --- FLOATING GLASSMORPHIC POPUP HUD (In-Page, Draggable) ---
  53. function createFloatingHud() {
  54. try {
  55. floatingHudStyleEl = document.createElement('style');
  56. floatingHudStyleEl.textContent = `
  57. @keyframes rkh-fadeIn { from { opacity: 0; transform: translateY(-10px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } }
  58. @keyframes rkh-glow { 0%, 100% { box-shadow: 0 0 15px rgba(0,255,255,0.4), 0 0 30px rgba(150,0,255,0.2); } 50% { box-shadow: 0 0 25px rgba(0,255,255,0.7), 0 0 50px rgba(150,0,255,0.4); } }
  59.  
  60. #rkh-container {
  61. position: fixed; top: 80px; right: 40px; width: 340px;
  62. background: rgba(15, 15, 25, 0.75);
  63. backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  64. border: 1px solid rgba(0, 255, 255, 0.4);
  65. border-radius: 14px;
  66. font-family: 'Segoe UI', 'Courier New', monospace;
  67. color: #e0faff;
  68. z-index: 999999;
  69. animation: rkh-fadeIn 0.35s ease-out, rkh-glow 3s infinite ease-in-out;
  70. overflow: hidden;
  71. user-select: none;
  72. }
  73. #rkh-header {
  74. display: flex; justify-content: space-between; align-items: center;
  75. padding: 10px 14px;
  76. background: linear-gradient(90deg, rgba(0,255,255,0.15), rgba(150,0,255,0.15));
  77. cursor: grab; border-bottom: 1px solid rgba(0,255,255,0.3);
  78. }
  79. #rkh-header:active { cursor: grabbing; }
  80. #rkh-title { font-weight: bold; font-size: 14px; letter-spacing: 1px; color: #7dfcff; text-shadow: 0 0 8px #00ffff; }
  81. .rkh-winbtn {
  82. background: rgba(255,255,255,0.08); border: none; color: #e0faff;
  83. width: 22px; height: 22px; border-radius: 6px; cursor: pointer;
  84. font-size: 12px; margin-left: 5px; transition: 0.2s;
  85. }
  86. .rkh-winbtn:hover { background: rgba(0,255,255,0.3); }
  87. #rkh-body { padding: 14px; display: flex; flex-direction: column; gap: 10px; }
  88. #rkh-body.rkh-hidden { display: none; }
  89.  
  90. #rkh-input {
  91. background: rgba(0,0,0,0.4); border: 1px solid rgba(0,255,255,0.3);
  92. color: #baffff; padding: 10px; border-radius: 8px; font-family: inherit;
  93. font-size: 13px; outline: none; transition: 0.2s;
  94. }
  95. #rkh-input:focus { border-color: #00ffff; box-shadow: 0 0 10px rgba(0,255,255,0.5); }
  96.  
  97. .rkh-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  98. .rkh-row3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; }
  99.  
  100. .rkh-btn {
  101. background: linear-gradient(135deg, rgba(0,255,255,0.12), rgba(150,0,255,0.12));
  102. border: 1px solid rgba(0,255,255,0.3);
  103. color: #e0faff; padding: 9px 6px; border-radius: 8px;
  104. font-family: inherit; font-size: 12px; cursor: pointer;
  105. transition: 0.2s; text-align: center;
  106. }
  107. .rkh-btn:hover { background: linear-gradient(135deg, #00ffff, #9600ff); color: #05050a; box-shadow: 0 0 12px rgba(0,255,255,0.6); transform: translateY(-1px); }
  108. .rkh-btn.rkh-danger { border-color: rgba(255,50,50,0.4); }
  109. .rkh-btn.rkh-danger:hover { background: linear-gradient(135deg, #ff3333, #990000); box-shadow: 0 0 12px rgba(255,50,50,0.6); color: #fff; }
  110. .rkh-status { font-size: 11px; opacity: 0.6; text-align: center; margin-top: 2px; }
  111. `;
  112. document.head.appendChild(floatingHudStyleEl);
  113.  
  114. floatingHudEl = document.createElement('div');
  115. floatingHudEl.id = 'rkh-container';
  116. floatingHudEl.innerHTML = `
  117. <div id="rkh-header">
  118. <span id="rkh-title">⌨ REMOTE KEYBOARD</span>
  119. <div>
  120. <button class="rkh-winbtn" id="rkh-min">_</button>
  121. <button class="rkh-winbtn" id="rkh-close">✕</button>
  122. </div>
  123. </div>
  124. <div id="rkh-body">
  125. <input type="text" id="rkh-input" placeholder="Type message + Enter to send...">
  126. <div class="rkh-row3">
  127. <button class="rkh-btn" id="rkh-nl">↵ NewLine</button>
  128. <button class="rkh-btn" id="rkh-bksp">⌫ Bksp</button>
  129. <button class="rkh-btn" id="rkh-space">␣ Space</button>
  130. </div>
  131. <div class="rkh-row">
  132. <button class="rkh-btn" id="rkh-sym">Ω Symbols: ON</button>
  133. <button class="rkh-btn" id="rkh-clearqueue">🧹 Clear Queue</button>
  134. </div>
  135. <div class="rkh-row">
  136. <button class="rkh-btn" id="rkh-auto">⏱ Auto-Refresh: ON</button>
  137. <button class="rkh-btn" id="rkh-minihud">🎛 Mini HUD: ON</button>
  138. </div>
  139. <div class="rkh-row">
  140. <button class="rkh-btn" id="rkh-clear">🗑 Clear Box</button>
  141. <button class="rkh-btn" id="rkh-auth">🔒 Auth: ON</button>
  142. </div>
  143. <div class="rkh-row">
  144. <button class="rkh-btn" id="rkh-refresh">⟳ Refresh</button>
  145. <button class="rkh-btn rkh-danger" id="rkh-quit">⏻ Quit</button>
  146. </div>
  147. <div class="rkh-status" id="rkh-status">Connected to keyboard engine</div>
  148. </div>
  149. `;
  150. document.body.appendChild(floatingHudEl);
  151.  
  152. const $ = (id) => floatingHudEl.querySelector(id);
  153. const input = $('#rkh-input');
  154. const status = $('#rkh-status');
  155. const flashStatus = (msg) => { status.textContent = msg; setTimeout(() => status.textContent = "Connected to keyboard engine", 1200); };
  156.  
  157. const sendText = () => {
  158. if (input.value.length > 0) {
  159. fieldText += input.value;
  160. if (fieldText.length > 760) fieldText = fieldText.slice(-760);
  161. renderField();
  162. flashStatus(`Sent: "${input.value.slice(0,20)}${input.value.length>20?'...':''}"`);
  163. input.value = '';
  164. }
  165. };
  166.  
  167. input.addEventListener('keypress', (e) => { if (e.key === 'Enter') sendText(); });
  168. $('#rkh-nl').addEventListener('click', () => { processKey('NEWLINE'); flashStatus('New line inserted'); });
  169. $('#rkh-bksp').addEventListener('click', () => { processKey('BACKSPACE'); flashStatus('Backspace'); });
  170. $('#rkh-space').addEventListener('click', () => { processKey('SPACE'); flashStatus('Space added'); });
  171. $('#rkh-clear').addEventListener('click', () => { fieldText = ""; renderField(); flashStatus('Input box cleared'); });
  172.  
  173. $('#rkh-sym').addEventListener('click', () => {
  174. processKey('SYM');
  175. drawHUD();
  176. updateFloatingLabels();
  177. flashStatus(`Symbols Mode: ${symActive ? 'ON' : 'OFF'}`);
  178. });
  179.  
  180. $('#rkh-clearqueue').addEventListener('click', () => {
  181. clearQueue();
  182. flashStatus('Animation queue cleared');
  183. });
  184.  
  185. $('#rkh-auth').addEventListener('click', () => {
  186. authOnly = !authOnly;
  187. drawHUD();
  188. updateFloatingLabels();
  189. flashStatus(`Auth-Only: ${authOnly ? 'ON' : 'OFF'}`);
  190. });
  191.  
  192. $('#rkh-auto').addEventListener('click', () => {
  193. autoRefreshEnabled = !autoRefreshEnabled;
  194. drawHUD();
  195. updateFloatingLabels();
  196. flashStatus(`Auto-Refresh: ${autoRefreshEnabled ? 'ON' : 'OFF'}`);
  197. });
  198.  
  199. $('#rkh-minihud').addEventListener('click', () => {
  200. toggleMiniHud();
  201. updateFloatingLabels();
  202. flashStatus(`Mini HUD: ${miniHudVisible ? 'SHOWN' : 'HIDDEN'}`);
  203. });
  204.  
  205. $('#rkh-refresh').addEventListener('click', () => { refreshUI(); flashStatus('UI Refreshing...'); });
  206. $('#rkh-quit').addEventListener('click', () => { quitScript(); });
  207.  
  208. let popupMinimized = false;
  209. $('#rkh-min').addEventListener('click', () => {
  210. popupMinimized = !popupMinimized;
  211. $('#rkh-body').classList.toggle('rkh-hidden', popupMinimized);
  212. });
  213. $('#rkh-close').addEventListener('click', () => {
  214. floatingHudEl.style.display = 'none';
  215. });
  216.  
  217. const header = $('#rkh-header');
  218. let isDragging = false, offsetX = 0, offsetY = 0;
  219. header.addEventListener('mousedown', (e) => {
  220. isDragging = true;
  221. const rect = floatingHudEl.getBoundingClientRect();
  222. offsetX = e.clientX - rect.left;
  223. offsetY = e.clientY - rect.top;
  224. floatingHudEl.style.right = 'auto';
  225. });
  226. document.addEventListener('mousemove', (e) => {
  227. if (!isDragging) return;
  228. floatingHudEl.style.left = (e.clientX - offsetX) + 'px';
  229. floatingHudEl.style.top = (e.clientY - offsetY) + 'px';
  230. });
  231. document.addEventListener('mouseup', () => { isDragging = false; });
  232.  
  233. updateFloatingLabels();
  234.  
  235. } catch (e) {
  236. console.log("Floating HUD failed to initialize:", e);
  237. }
  238. }
  239.  
  240. function updateFloatingLabels() {
  241. if (!floatingHudEl) return;
  242. const autoBtn = floatingHudEl.querySelector('#rkh-auto');
  243. const authBtn = floatingHudEl.querySelector('#rkh-auth');
  244. const hudBtn = floatingHudEl.querySelector('#rkh-minihud');
  245. const symBtn = floatingHudEl.querySelector('#rkh-sym');
  246. if (autoBtn) autoBtn.textContent = `⏱ Auto-Refresh: ${autoRefreshEnabled ? 'ON' : 'OFF'}`;
  247. if (authBtn) authBtn.textContent = `🔒 Auth: ${authOnly ? 'ON' : 'OFF'}`;
  248. if (hudBtn) hudBtn.textContent = `🎛 Mini HUD: ${miniHudVisible ? 'ON' : 'OFF'}`;
  249. if (symBtn) symBtn.textContent = `Ω Symbols: ${symActive ? 'ON' : 'OFF'}`;
  250. }
  251.  
  252. function destroyFloatingHud() {
  253. if (floatingHudEl) { floatingHudEl.remove(); floatingHudEl = null; }
  254. if (floatingHudStyleEl) { floatingHudStyleEl.remove(); floatingHudStyleEl = null; }
  255. }
  256.  
  257. // --- IN-GAME MINI HUD LOGIC ---
  258. function registerHudButton(text, color, startX, startY, action) {
  259. drawString(text, color, startX, startY);
  260. for (let i = 0; i < text.length; i++) hudKeyMap[`${startX + i},${startY}`] = action;
  261. }
  262.  
  263. function toggleMiniHud() {
  264. miniHudVisible = !miniHudVisible;
  265. drawHUD();
  266. }
  267.  
  268. function drawHUD() {
  269. for (let x = 20; x <= 95; x++) draw(' ', CID.BLACK, x, -32);
  270. hudKeyMap = {};
  271.  
  272. if (!miniHudVisible) return;
  273.  
  274. if (hudMinimized) {
  275. registerHudButton("[+]", CID.WHITE, 22, -32, "HUD_EXPAND");
  276. } else {
  277. registerHudButton("[-]", CID.WHITE, 22, -32, "HUD_MINIMIZE");
  278. const autoText = autoRefreshEnabled ? "[Auto: ON ]" : "[Auto: OFF]";
  279. registerHudButton(autoText, autoRefreshEnabled ? CID.LIME : CID.GRAY, 26, -32, "HUD_AUTO");
  280. const authText = authOnly ? "[Auth: ON ]" : "[Auth: OFF]";
  281. registerHudButton(authText, authOnly ? CID.LIME : CID.GRAY, 38, -32, "HUD_AUTH");
  282. registerHudButton("[Clear]", CID.YELLOW, 50, -32, "HUD_CLEAR");
  283. registerHudButton("[Refresh]", CID.CYAN, 58, -32, "HUD_REFRESH");
  284. registerHudButton("[Quit]", CID.RED, 68, -32, "HUD_QUIT");
  285. const symText = symActive ? "[Sym: ON ]" : "[Sym: OFF]";
  286. registerHudButton(symText, symActive ? CID.LIME : CID.GRAY, 75, -32, "HUD_SYM");
  287. registerHudButton("[ClrQ]", CID.YELLOW, 86, -32, "HUD_CLEARQUEUE");
  288. }
  289. }
  290.  
  291. function processHudAction(action) {
  292. if (action === 'HUD_MINIMIZE') { hudMinimized = true; drawHUD(); }
  293. else if (action === 'HUD_EXPAND') { hudMinimized = false; drawHUD(); }
  294. else if (action === 'HUD_AUTO') { autoRefreshEnabled = !autoRefreshEnabled; drawHUD(); updateFloatingLabels(); }
  295. else if (action === 'HUD_AUTH') { authOnly = !authOnly; drawHUD(); updateFloatingLabels(); }
  296. else if (action === 'HUD_CLEAR') { fieldText = ""; renderField(); }
  297. else if (action === 'HUD_REFRESH') { refreshUI(); }
  298. else if (action === 'HUD_QUIT') { quitScript(); }
  299. else if (action === 'HUD_SYM') { processKey('SYM'); drawHUD(); updateFloatingLabels(); }
  300. else if (action === 'HUD_CLEARQUEUE') { clearQueue(); }
  301. }
  302.  
  303. // --- KEYBOARD LOGIC (Improved ASCII Styling) ---
  304. function getKeyboardLayout() {
  305. const layout = [];
  306. if (!symActive) {
  307. layout.push(...'1234567890'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -20 + i * 3, y: -5, color: CID.WHITE })));
  308. layout.push(...'QWERTYUIOP'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -19 + i * 3, y: -6, color: CID.CYAN })));
  309. layout.push(...'ASDFGHJKL'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -18 + i * 3, y: -7, color: CID.LIME })));
  310. layout.push(...'ZXCVBNM'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -17 + i * 3, y: -8, color: CID.YELLOW })));
  311. } else {
  312. layout.push(...'!@#$%^&*()'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -20 + i * 3, y: -5, color: CID.WHITE })));
  313. layout.push(...'_+-=[]{}\\|'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -19 + i * 3, y: -6, color: CID.CYAN })));
  314. layout.push(...";:'\",./<>?".split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -18 + i * 3, y: -7, color: CID.LIME })));
  315. layout.push(...'~`^°•○●□■'.split('').map((k, i) => ({ label: `⟦${k}⟧`, key: k, x: -17 + i * 3, y: -8, color: CID.YELLOW })));
  316. }
  317. // Special keys use lenticular brackets for visual distinction
  318. layout.push({ label: '【Shift】', key: 'SHIFT', x: -20, y: -9, color: CID.RED });
  319. layout.push({ label: '【Bksp 】', key: 'BACKSPACE', x: -13, y: -9, color: CID.RED });
  320. layout.push({ label: '【Sym 】', key: 'SYM', x: -6, y: -9, color: CID.RED });
  321. layout.push({ label: '【 x2 】', key: 'X2', x: -1, y: -9, color: CID.RED });
  322. layout.push({ label: '【NL】', key: 'NEWLINE', x: 5, y: -9, color: CID.RED });
  323. layout.push({ label: '【Space】', key: 'SPACE', x: 9, y: -9, color: CID.RED });
  324. return layout;
  325. }
  326.  
  327. function updateKeyMap() {
  328. for (let k in keyMap) delete keyMap[k];
  329. getKeyboardLayout().forEach(k => {
  330. for (let i = 0; i < k.label.length; i++) keyMap[`${k.x + i},${k.y}`] = k.key;
  331. });
  332. }
  333.  
  334. function drawKeyboard() {
  335. for (let y = -9; y <= -5; y++) for (let x = -22; x <= 22; x++) draw(' ', CID.BLACK, x, y);
  336. getKeyboardLayout().forEach(k => {
  337. for (let i = 0; i < k.label.length; i++) draw(k.label[i], k.color, k.x + i, k.y);
  338. });
  339. }
  340.  
  341. function processKey(key) {
  342. if (key === 'SHIFT') shiftActive = !shiftActive;
  343. else if (key === 'BACKSPACE') fieldText = fieldText.slice(0, -1);
  344. else if (key === 'X2') { if (lastChar) fieldText += lastChar.repeat(2); }
  345. else if (key === 'SPACE') { fieldText += ' '; lastChar = ' '; shiftActive = false; }
  346. else if (key === 'NEWLINE') { fieldText += '\n'; lastChar = '\n'; shiftActive = false; }
  347. else if (key === 'SYM') { symActive = !symActive; drawKeyboard(); updateKeyMap(); }
  348. else {
  349. let c = shiftActive ? key.toUpperCase() : key.toLowerCase();
  350. fieldText += c; lastChar = c; shiftActive = false;
  351. }
  352. if (fieldText.length > 760) fieldText = fieldText.slice(-760);
  353. renderField();
  354. }
  355.  
  356. // --- UI RENDERING ---
  357. function buildStaticChars() {
  358. const chars = [];
  359. chars.push({ c: '┌', col: CID.GRAY, x: -20, y: -10 });
  360. chars.push({ c: '┐', col: CID.GRAY, x: 19, y: -10 });
  361. for (let x = -19; x <= 18; x++) chars.push({ c: '─', col: CID.GRAY, x: x, y: -10 });
  362. chars.push({ c: '└', col: CID.GRAY, x: -20, y: -29 });
  363. chars.push({ c: '┘', col: CID.GRAY, x: 19, y: -29 });
  364. for (let x = -19; x <= 18; x++) chars.push({ c: '─', col: CID.GRAY, x: x, y: -29 });
  365. for (let y = -28; y <= -11; y++) {
  366. chars.push({ c: '│', col: CID.GRAY, x: -20, y: y });
  367. chars.push({ c: '│', col: CID.GRAY, x: 19, y: y });
  368. }
  369. getKeyboardLayout().forEach(k => {
  370. for (let i = 0; i < k.label.length; i++) chars.push({ c: k.label[i], col: k.color, x: k.x + i, y: k.y });
  371. });
  372. const desc = "This is for kiwitest, by: Ultimer";
  373. for (let i = 0; i < desc.length; i++) chars.push({ c: desc[i], col: CID.YELLOW, x: -20 + i, y: -3 });
  374. return chars;
  375. }
  376.  
  377. async function drawStaticAnimated() {
  378. const localFlag = { stop: false };
  379. animAbortFlag = localFlag;
  380. const delay = 1000 / 450;
  381. const staticChars = buildStaticChars();
  382. for (const item of staticChars) {
  383. if (!scriptRunning || localFlag.stop) break;
  384. draw(item.c, item.col, item.x, item.y);
  385. await sleep(delay);
  386. }
  387. }
  388.  
  389. // Halts any in-progress typing animation immediately
  390. function clearQueue() {
  391. animAbortFlag.stop = true;
  392. }
  393.  
  394. function renderField() {
  395. for (let y = -28; y <= -11; y++) for (let x = -19; x <= 18; x++) draw(' ', CID.BLACK, x, y);
  396. let lines = [], currentLine = "";
  397. for (let i = 0; i < fieldText.length; i++) {
  398. let char = fieldText[i];
  399. if (char === '\n') { lines.push(currentLine); currentLine = ""; }
  400. else {
  401. currentLine += char;
  402. if (currentLine.length === 38) { lines.push(currentLine); currentLine = ""; }
  403. }
  404. }
  405. lines.push(currentLine);
  406. if (lines.length > 18) lines = lines.slice(-18);
  407. let startY = -11;
  408. for (let i = 0; i < lines.length; i++) {
  409. let line = lines[i];
  410. for (let j = 0; j < line.length; j++) draw(line[j], CID.LIME, -19 + j, startY - i);
  411. }
  412. }
  413.  
  414. function drawTimer() {
  415. if (!scriptRunning) return;
  416. let elapsed = Math.floor((Date.now() - startTime) / 1000);
  417. let h = String(Math.floor(elapsed / 3600)).padStart(2, '0');
  418. let m = String(Math.floor((elapsed % 3600) / 60)).padStart(2, '0');
  419. let s = String(elapsed % 60).padStart(2, '0');
  420. for (let x = -20; x <= 10; x++) draw(' ', CID.BLACK, x, -2);
  421. drawString(`Uptime: ${h}:${m}:${s}`, CID.WHITE, -20, -2);
  422. }
  423.  
  424. async function refreshUI() {
  425. if (!scriptRunning) return;
  426. for (let y = -35; y <= 0; y++) for (let x = -25; x <= 20; x++) draw(' ', CID.BLACK, x, y);
  427. await drawStaticAnimated();
  428. renderField();
  429. drawHUD();
  430. drawTimer();
  431. }
  432.  
  433. function quitScript() {
  434. if (pollingInterval) clearInterval(pollingInterval);
  435. if (timerInterval) clearInterval(timerInterval);
  436. clearQueue();
  437. destroyFloatingHud();
  438. scriptRunning = false;
  439.  
  440. const clearArea = (x1, x2, y1, y2) => {
  441. for (let y = y1; y <= y2; y++) for (let x = x1; x <= x2; x++) writeCharAt(' ', CID.BLACK, x, -y);
  442. };
  443. clearArea(20, 95, -32, -32);
  444. clearArea(-20, 19, -29, -10);
  445. clearArea(-22, 22, -9, -5);
  446. clearArea(-20, 15, -3, -3);
  447. clearArea(-20, 10, -2, -2);
  448. }
  449.  
  450. // --- STRICT CURSOR DETECTION ---
  451. function handleCursorInput(x, y, name) {
  452. if (!scriptRunning || !name) return;
  453. const normalizedName = String(name).trim();
  454. const rx = Math.round(x), ry = Math.round(y);
  455. const posStr = `${rx},${ry}`;
  456. if (lastPositions[normalizedName] === posStr) return;
  457.  
  458. const now = Date.now();
  459. if (userCooldowns[normalizedName] && (now - userCooldowns[normalizedName] < 200)) {
  460. lastPositions[normalizedName] = posStr; return;
  461. }
  462.  
  463. const pos = `${rx},${-ry}`;
  464. const isAuth = Auth.some(a => a.toLowerCase() === normalizedName.toLowerCase());
  465. if (authOnly && !isAuth) { lastPositions[normalizedName] = posStr; return; }
  466.  
  467. const hudAction = hudKeyMap[pos];
  468. if (hudAction) {
  469. lastPositions[normalizedName] = posStr;
  470. userCooldowns[normalizedName] = now;
  471. processHudAction(hudAction);
  472. return;
  473. }
  474.  
  475. const key = keyMap[pos];
  476. if (key) {
  477. lastPositions[normalizedName] = posStr;
  478. userCooldowns[normalizedName] = now;
  479. processKey(key);
  480. } else {
  481. lastPositions[normalizedName] = posStr;
  482. }
  483. }
  484.  
  485. function setupCursorDetection() {
  486. if (typeof w !== 'undefined' && typeof w.on === 'function') {
  487. try {
  488. w.on('cursor', (data) => {
  489. if (!data) return;
  490. let name = data.n || data.name || data.username || data.id;
  491. let x = data.l ? data.l[0] : data.x;
  492. let y = data.l ? data.l[1] : data.y;
  493. if (name !== undefined && x !== undefined && y !== undefined) handleCursorInput(x, y, name);
  494. });
  495. } catch(e) {}
  496. }
  497.  
  498. pollingInterval = setInterval(() => {
  499. if (!scriptRunning) return;
  500. try {
  501. let cursors = [];
  502. if (typeof w.cursors === 'function') cursors = w.cursors();
  503. else if (typeof w.cursors !== 'undefined') cursors = w.cursors;
  504. if (!Array.isArray(cursors)) cursors = [];
  505. cursors.forEach(c => {
  506. if (!c) return;
  507. let name = c.n || c.name || c.username || c.id;
  508. let x = c.l ? c.l[0] : c.x;
  509. let y = c.l ? c.l[1] : c.y;
  510. if (name !== undefined && x !== undefined && y !== undefined) handleCursorInput(x, y, name);
  511. });
  512. } catch(e) {}
  513. }, 50);
  514. }
  515.  
  516. // --- MAIN EXECUTION ---
  517. async function main() {
  518. updateKeyMap();
  519. await drawStaticAnimated();
  520. renderField();
  521. drawHUD();
  522. drawTimer();
  523.  
  524. setupCursorDetection();
  525. createFloatingHud();
  526.  
  527. timerInterval = setInterval(() => { if (scriptRunning) drawTimer(); }, 1000);
  528.  
  529. (async () => {
  530. while (scriptRunning) {
  531. await sleep(15000);
  532. if (!scriptRunning) break;
  533. if (autoRefreshEnabled) { try { await refreshUI(); } catch (e) {} }
  534. }
  535. })();
  536. }
  537.  
  538. main();
Advertisement
Add Comment
Please, Sign In to add comment