Advertisement
Josiahiscool73

KBM AA UPDATEDDDDD OMG V100

Jun 24th, 2025
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.28 KB | None | 0 0
  1. /**
  2. * @name KBM AA (Desktop UI)
  3. * @description Emulates an Xbox controller with a modern, draggable UI.
  4. * Press PageUp to open/close the settings menu.
  5. * v3 Improvements: Complete UI overhaul to a draggable, resizable, desktop-style application window.
  6. */
  7. (function() {
  8. 'use strict';
  9.  
  10. // --- Primary Toggle ---
  11. const KBM_AA_ENABLED = true;
  12.  
  13. // --- Default Configuration ---
  14. const DEFAULT_KEY_BINDS = {
  15. FIRE: 'mouse0', ADS: 't', JUMP: ' ', SPRINT: 'shift', CROUCH: 'control',
  16. RELOAD: 'r', USE: 'e', EDIT: 'g', WALL: 'z', RAMP: 'x', FLOOR: 'c', ROOF: 'v',
  17. };
  18. const DEFAULT_SENSITIVITY = { X: 8.5, Y: 8.5, ADS_MULTIPLIER: 85 };
  19. const DEFAULT_VIRTUAL_ZEN_SETTINGS = {
  20. ENABLED: true, ACTIVATE_ON_ADS_ONLY: false, ENABLE_STRAFE_AIM_ASSIST: true,
  21. STRAFE_AIM_ASSIST_STRENGTH: 0.05, STRAFE_AIM_ASSIST_ADS_MULTIPLIER: 1.3,
  22. ENABLE_MOVEMENT_VERTICAL_AIM_ASSIST: true, FORWARD_AIM_DOWN_STRENGTH: 0.09,
  23. BACKWARD_AIM_UP_STRENGTH: 0.09, STRAFE_LOOK_STRENGTH: 0.10,
  24. };
  25.  
  26. // --- Backend ---
  27. const ADVANCED = { POLLING_RATE_MS: 16, CONNECTION_DISPATCH_RATE_MS: 100, SENS_BASE_MULTIPLIER: 0.0018 };
  28. const CONTROLLER_BUTTON_MAP = {
  29. A: 0, B: 1, X: 2, Y: 3, LB: 4, RB: 5, LT: 6, RT: 7, L_STICK: 10, R_STICK: 11,
  30. };
  31. const BIND_ACTION_TO_BUTTON = {
  32. JUMP: CONTROLLER_BUTTON_MAP.A, EDIT: CONTROLLER_BUTTON_MAP.B, RELOAD: CONTROLLER_BUTTON_MAP.X,
  33. USE: CONTROLLER_BUTTON_MAP.X, WALL: CONTROLLER_BUTTON_MAP.RT, ADS: CONTROLLER_BUTTON_MAP.LT,
  34. RAMP: CONTROLLER_BUTTON_MAP.LT, ROOF: CONTROLLER_BUTTON_MAP.LB, FLOOR: CONTROLLER_BUTTON_MAP.RB,
  35. SPRINT: CONTROLLER_BUTTON_MAP.L_STICK, CROUCH: CONTROLLER_BUTTON_MAP.R_STICK,
  36. FIRE: CONTROLLER_BUTTON_MAP.RT,
  37. };
  38.  
  39. // --- Script State ---
  40. let keyMap = {}, mouseMap = {}, currentBinds = {}, currentSens = {}, virtualZenSettings = {};
  41. const controllerState = {
  42. axes: [0.0, 0.0, 0.0, 0.0],
  43. buttons: Array(17).fill(false).map((_, i) => ({ pressed: false, touched: false, value: 0.0, index: i })),
  44. axisKeyPresses: { 0: { neg: false, pos: false }, 1: { neg: false, pos: false } },
  45. mouseDeltaX: 0, mouseDeltaY: 0, isConnected: true, timestamp: performance.now(),
  46. };
  47. let pointerLocked = false, stateIntervalId = null, connectionIntervalId = null, gameAreaElement = null;
  48. const originalGetGamepads = navigator.getGamepads?.bind(navigator);
  49. const eventListeners = [];
  50.  
  51. // --- Core Logic (Unchanged) ---
  52. function generateMappings() {
  53. keyMap = {
  54. 'w': { t: 'a', a: 1, v: -1 }, 'a': { t: 'a', a: 0, v: -1 },
  55. 's': { t: 'a', a: 1, v: 1 }, 'd': { t: 'a', a: 0, v: 1 },
  56. };
  57. mouseMap = {};
  58. for (const action in currentBinds) {
  59. const key = currentBinds[action].toLowerCase();
  60. const buttonIndex = BIND_ACTION_TO_BUTTON[action];
  61. if (buttonIndex !== undefined) {
  62. if (key.startsWith('mouse')) mouseMap[parseInt(key.replace('mouse', ''), 10)] = { t: 'b', i: buttonIndex };
  63. else keyMap[key] = { t: 'b', i: buttonIndex };
  64. }
  65. }
  66. }
  67.  
  68. function createGamepadObject() {
  69. return {
  70. axes: controllerState.axes, buttons: controllerState.buttons, connected: controllerState.isConnected,
  71. id: "Xbox Controller (XInput STANDARD GAMEPAD)", index: 0, mapping: "standard", timestamp: controllerState.timestamp,
  72. };
  73. }
  74.  
  75. function updateAndSimulateGamepad() {
  76. let scriptSensX = currentSens.X * ADVANCED.SENS_BASE_MULTIPLIER, scriptSensY = currentSens.Y * ADVANCED.SENS_BASE_MULTIPLIER;
  77. const isADS = controllerState.buttons[BIND_ACTION_TO_BUTTON.ADS]?.pressed || false;
  78. if (isADS) { const m = currentSens.ADS_MULTIPLIER / 100; scriptSensX *= m; scriptSensY *= m; }
  79. let finalTargetRX = 0, finalTargetRY = 0;
  80. if (pointerLocked) {
  81. finalTargetRX = controllerState.mouseDeltaX * scriptSensX;
  82. finalTargetRY = controllerState.mouseDeltaY * scriptSensY;
  83. const isZenActive = virtualZenSettings.ENABLED && (!virtualZenSettings.ACTIVATE_ON_ADS_ONLY || isADS);
  84. if (isZenActive) {
  85. if (virtualZenSettings.ENABLE_STRAFE_AIM_ASSIST) {
  86. const s = virtualZenSettings.STRAFE_AIM_ASSIST_STRENGTH * (isADS ? virtualZenSettings.STRAFE_AIM_ASSIST_ADS_MULTIPLIER : 1);
  87. if (controllerState.axisKeyPresses[0].neg) finalTargetRX += s;
  88. else if (controllerState.axisKeyPresses[0].pos) finalTargetRX -= s;
  89. }
  90. if (virtualZenSettings.ENABLE_MOVEMENT_VERTICAL_AIM_ASSIST) {
  91. if (controllerState.axisKeyPresses[1].neg) finalTargetRY += virtualZenSettings.FORWARD_AIM_DOWN_STRENGTH;
  92. else if (controllerState.axisKeyPresses[1].pos) finalTargetRY -= virtualZenSettings.BACKWARD_AIM_UP_STRENGTH;
  93. }
  94. if (controllerState.axisKeyPresses[0].neg) finalTargetRX += virtualZenSettings.STRAFE_LOOK_STRENGTH;
  95. else if (controllerState.axisKeyPresses[0].pos) finalTargetRX -= virtualZenSettings.STRAFE_LOOK_STRENGTH;
  96. }
  97. controllerState.mouseDeltaX = 0; controllerState.mouseDeltaY = 0;
  98. }
  99. controllerState.axes[2] = Math.max(-1, Math.min(1, finalTargetRX));
  100. controllerState.axes[3] = Math.max(-1, Math.min(1, finalTargetRY));
  101. controllerState.timestamp = performance.now();
  102. }
  103.  
  104. // --- Event Handlers (Unchanged) ---
  105. function handleKeyEvent(event, isDown) {
  106. if (event.key === 'PageUp' && isDown) { toggleUI(); return; }
  107. const gui = document.getElementById('kbm-aa-gui');
  108. if (gui && gui.style.display !== 'none') { if (event.key === 'Escape') { toggleUI(); } return; }
  109. const mappedKey = (event.key.toLowerCase().startsWith('control') ? 'control' : event.key.toLowerCase());
  110. const mapping = keyMap[mappedKey];
  111. if (mapping) {
  112. event.preventDefault(); event.stopPropagation();
  113. if (mapping.t === 'b') {
  114. const button = controllerState.buttons[mapping.i];
  115. if (button.pressed !== isDown) { button.pressed = isDown; button.touched = isDown; button.value = isDown ? 1.0 : 0.0; }
  116. } else if (mapping.t === 'a') {
  117. const axisState = controllerState.axisKeyPresses[mapping.a];
  118. if (mapping.v < 0) axisState.neg = isDown; else axisState.pos = isDown;
  119. controllerState.axes[mapping.a] = axisState.neg ? -1 : (axisState.pos ? 1 : 0);
  120. }
  121. }
  122. }
  123. function handleMouseEvent(event, isDown) {
  124. const gui = document.getElementById('kbm-aa-gui');
  125. if (gui && gui.style.display !== 'none') return;
  126. const mapping = mouseMap[event.button];
  127. if (mapping) {
  128. event.preventDefault(); event.stopPropagation();
  129. if (!pointerLocked && isDown) return;
  130. const button = controllerState.buttons[mapping.i];
  131. if (button.pressed !== isDown) { button.pressed = isDown; button.touched = isDown; button.value = isDown ? 1.0 : 0.0; }
  132. }
  133. }
  134. function handleMouseMove(event) { if (pointerLocked) { controllerState.mouseDeltaX += event.movementX || 0; controllerState.mouseDeltaY += event.movementY || 0; } }
  135. function handlePointerLockChange() {
  136. pointerLocked = (document.pointerLockElement === gameAreaElement);
  137. if (!pointerLocked) {
  138. Object.assign(controllerState, { mouseDeltaX: 0, mouseDeltaY: 0 });
  139. Object.values(mouseMap).forEach(m => { const b = controllerState.buttons[m.i]; b.pressed = b.touched = false; b.value = 0.0; });
  140. }
  141. }
  142. function requestPointerLock() { if (!pointerLocked) gameAreaElement.requestPointerLock().catch(e => {}); }
  143.  
  144. // --- New UI Functions ---
  145. function toggleUI() { const gui = document.getElementById('kbm-aa-gui'); if (gui) { gui.style.display = gui.style.display === 'block' ? 'none' : 'block'; } }
  146. function saveSettings() {
  147. for (const action in DEFAULT_KEY_BINDS) { currentBinds[action] = document.getElementById(`bind-${action}`).value; }
  148. currentSens.X = parseFloat(document.getElementById('sens-x').value);
  149. currentSens.Y = parseFloat(document.getElementById('sens-y').value);
  150. currentSens.ADS_MULTIPLIER = parseFloat(document.getElementById('sens-ads').value);
  151. virtualZenSettings.ENABLED = document.getElementById('zen-enabled').checked;
  152. virtualZenSettings.ACTIVATE_ON_ADS_ONLY = document.getElementById('zen-ads-only').checked;
  153. localStorage.setItem('kbm-aa-binds', JSON.stringify(currentBinds));
  154. localStorage.setItem('kbm-aa-sens', JSON.stringify(currentSens));
  155. localStorage.setItem('kbm-aa-zen', JSON.stringify(virtualZenSettings));
  156. generateMappings();
  157. toggleUI();
  158. }
  159. function loadSettings() {
  160. currentBinds = JSON.parse(localStorage.getItem('kbm-aa-binds')) || { ...DEFAULT_KEY_BINDS };
  161. currentSens = JSON.parse(localStorage.getItem('kbm-aa-sens')) || { ...DEFAULT_SENSITIVITY };
  162. virtualZenSettings = JSON.parse(localStorage.getItem('kbm-aa-zen')) || { ...DEFAULT_VIRTUAL_ZEN_SETTINGS };
  163. }
  164. function createConfigUI() {
  165. if (document.getElementById('kbm-aa-gui')) return;
  166. let bindsHTML = '';
  167. for (const action in DEFAULT_KEY_BINDS) { bindsHTML += `<div class="kbm-aa-row"><label>${action}</label><input type="text" id="bind-${action}" value="${currentBinds[action] || ''}"></div>`; }
  168.  
  169. const uiHTML = `
  170. <div id="kbm-aa-title-bar">
  171. <div id="kbm-aa-logo">K</div>
  172. <span class="kbm-title-text">KBM AA Settings</span>
  173. <button id="kbm-aa-close-btn">×</button>
  174. </div>
  175. <div id="kbm-aa-content">
  176. <div class="kbm-aa-panel">
  177. <h3 class="kbm-aa-panel-title">Sensitivity</h3>
  178. <div class="kbm-aa-row"><label>X Sensitivity</label><input type="range" id="sens-x" min="1" max="30" step="0.1" value="${currentSens.X}"><span class="kbm-aa-value" id="sens-x-val">${currentSens.X}</span></div>
  179. <div class="kbm-aa-row"><label>Y Sensitivity</label><input type="range" id="sens-y" min="1" max="30" step="0.1" value="${currentSens.Y}"><span class="kbm-aa-value" id="sens-y-val">${currentSens.Y}</span></div>
  180. <div class="kbm-aa-row"><label>ADS Multiplier</label><input type="range" id="sens-ads" min="10" max="100" step="1" value="${currentSens.ADS_MULTIPLIER}"><span class="kbm-aa-value" id="sens-ads-val">${currentSens.ADS_MULTIPLIER}%</span></div>
  181. </div>
  182. <div class="kbm-aa-panel">
  183. <h3 class="kbm-aa-panel-title">Virtual Aim Assist</h3>
  184. <div class="kbm-aa-row"><label for="zen-enabled">Enable Aim Assist</label><input type="checkbox" id="zen-enabled" ${virtualZenSettings.ENABLED ? 'checked' : ''}></div>
  185. <div class="kbm-aa-row"><label for="zen-ads-only">Activate on ADS Only</label><input type="checkbox" id="zen-ads-only" ${virtualZenSettings.ACTIVATE_ON_ADS_ONLY ? 'checked' : ''}></div>
  186. </div>
  187. <div class="kbm-aa-panel" id="kbm-aa-binds-panel">
  188. <h3 class="kbm-aa-panel-title">Key Binds</h3>
  189. ${bindsHTML}
  190. </div>
  191. </div>
  192. <button id="kbm-aa-save-btn">Save & Close</button>
  193. <div id="kbm-aa-resize-handle"></div>`;
  194.  
  195. const style = document.createElement('style');
  196. style.id = 'kbm-aa-style';
  197. style.textContent = `
  198. #kbm-aa-gui { display: none; position: fixed; top: 10%; left: 15%; width: 600px; min-width: 450px; min-height: 400px; background: #1a1a1a; border-radius: 12px; z-index: 99999; color: #e0e0e0; font-family: 'Segoe UI', sans-serif; box-shadow: 0 10px 30px rgba(0,0,0,0.5); border: 1px solid #333; resize: both; overflow: hidden; }
  199. #kbm-aa-title-bar { height: 40px; background: #222; display: flex; align-items: center; padding: 0 10px; cursor: move; border-top-left-radius: 12px; border-top-right-radius: 12px; user-select: none; }
  200. #kbm-aa-logo { font-weight: bold; font-size: 20px; color: #ffb700; margin-right: 10px; }
  201. .kbm-title-text { flex-grow: 1; }
  202. #kbm-aa-close-btn { background: none; border: none; color: #ccc; font-size: 24px; cursor: pointer; }
  203. #kbm-aa-content { padding: 20px; display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; height: calc(100% - 100px); overflow-y: auto; }
  204. .kbm-aa-panel { background: #252525; padding: 15px; border-radius: 8px; border: 1px solid #383838; }
  205. .kbm-aa-panel-title { margin: 0 0 15px 0; color: #ffb700; border-bottom: 1px solid #444; padding-bottom: 8px; }
  206. #kbm-aa-binds-panel { grid-column: span 2; }
  207. .kbm-aa-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; font-size: 14px; }
  208. .kbm-aa-row label { flex-basis: 50%; }
  209. .kbm-aa-row input[type="text"] { width: 80px; padding: 5px; background: #333; border: 1px solid #555; color: #fff; border-radius: 4px; }
  210. .kbm-aa-row input[type="range"] { flex-grow: 1; margin: 0 10px; accent-color: #ffb700; }
  211. .kbm-aa-row input[type="checkbox"] { width: 18px; height: 18px; accent-color: #ffb700; }
  212. .kbm-aa-value { min-width: 50px; text-align: right; }
  213. #kbm-aa-save-btn { position: absolute; bottom: 10px; right: 10px; padding: 8px 15px; background: #ffb700; border: none; color: #111; border-radius: 4px; cursor: pointer; font-size: 14px; font-weight: bold; }
  214. #kbm-aa-resize-handle { position: absolute; bottom: 0; right: 0; width: 10px; height: 10px; cursor: nwse-resize; }
  215. `;
  216. document.head.appendChild(style);
  217.  
  218. const guiContainer = document.createElement('div');
  219. guiContainer.id = 'kbm-aa-gui';
  220. guiContainer.innerHTML = uiHTML;
  221. document.body.appendChild(guiContainer);
  222.  
  223. document.getElementById('kbm-aa-close-btn').addEventListener('click', toggleUI);
  224. document.getElementById('kbm-aa-save-btn').addEventListener('click', saveSettings);
  225. document.getElementById('sens-x').addEventListener('input', (e) => { document.getElementById('sens-x-val').textContent = e.target.value; });
  226. document.getElementById('sens-y').addEventListener('input', (e) => { document.getElementById('sens-y-val').textContent = e.target.value; });
  227. document.getElementById('sens-ads').addEventListener('input', (e) => { document.getElementById('sens-ads-val').textContent = e.target.value + '%'; });
  228.  
  229. makeDraggable(guiContainer, document.getElementById('kbm-aa-title-bar'));
  230. }
  231.  
  232. function makeDraggable(element, handle) {
  233. let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  234. handle.onmousedown = dragMouseDown;
  235. function dragMouseDown(e) {
  236. e.preventDefault();
  237. pos3 = e.clientX; pos4 = e.clientY;
  238. document.onmouseup = closeDragElement;
  239. document.onmousemove = elementDrag;
  240. }
  241. function elementDrag(e) {
  242. e.preventDefault();
  243. pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY;
  244. pos3 = e.clientX; pos4 = e.clientY;
  245. element.style.top = (element.offsetTop - pos2) + "px";
  246. element.style.left = (element.offsetLeft - pos1) + "px";
  247. }
  248. function closeDragElement() {
  249. document.onmouseup = null; document.onmousemove = null;
  250. }
  251. }
  252.  
  253.  
  254. // --- Initialization & Shutdown ---
  255. function addListener(element, event, handler, options = false) {
  256. element.addEventListener(event, handler, options);
  257. eventListeners.push({ element, event, handler, options });
  258. }
  259. function removeAllListeners() {
  260. eventListeners.forEach(({ element, event, handler, options }) => element.removeEventListener(event, handler, options));
  261. eventListeners.length = 0;
  262. }
  263. function initialize() {
  264. gameAreaElement = document.getElementById('game-stream') || document.querySelector('video') || document.body;
  265. if (!gameAreaElement) { console.error("KBM AA Script: Could not find a suitable game element."); return; }
  266. loadSettings(); createConfigUI(); generateMappings();
  267. navigator.getGamepads = () => [createGamepadObject(), null, null, null];
  268. addListener(window, 'keydown', (e) => handleKeyEvent(e, true), true);
  269. addListener(window, 'keyup', (e) => handleKeyEvent(e, false), true);
  270. addListener(gameAreaElement, 'mousemove', handleMouseMove, true);
  271. addListener(gameAreaElement, 'mousedown', (e) => handleMouseEvent(e, true), true);
  272. addListener(gameAreaElement, 'mouseup', (e) => handleMouseEvent(e, false), true);
  273. addListener(document, 'pointerlockchange', handlePointerLockChange, false);
  274. addListener(gameAreaElement, 'click', requestPointerLock, false);
  275. stateIntervalId = setInterval(updateAndSimulateGamepad, ADVANCED.POLLING_RATE_MS);
  276. connectionIntervalId = setInterval(() => { window.dispatchEvent(new CustomEvent('gamepadconnected', { detail: { gamepad: createGamepadObject() } })) }, ADVANCED.CONNECTION_DISPATCH_RATE_MS);
  277. }
  278. window.stopKbmAa = function() {
  279. if (!stateIntervalId) return;
  280. clearInterval(stateIntervalId); clearInterval(connectionIntervalId);
  281. stateIntervalId = null; connectionIntervalId = null;
  282. removeAllListeners();
  283. if (originalGetGamepads) navigator.getGamepads = originalGetGamepads; else delete navigator.getGamepads;
  284. const gui = document.getElementById('kbm-aa-gui'); if (gui) gui.remove();
  285. const style = document.getElementById('kbm-aa-style'); if (style) style.remove();
  286. if (document.pointerLockElement) document.exitPointerLock();
  287. console.log("KBM AA Script stopped and cleaned up.");
  288. };
  289. if (KBM_AA_ENABLED) {
  290. if (document.readyState === 'complete' || document.readyState === 'interactive') { setTimeout(initialize, 500); }
  291. else { document.addEventListener('DOMContentLoaded', () => setTimeout(initialize, 500)); }
  292. }
  293. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement