Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // == Xbox Cloud Gaming Keyboard/Mouse to Controller Mapper v9 ==
- // == !! EXTREMELY EXPERIMENTAL - Added SPECULATIVE Micro-Movements for Aim Assist !! ==
- // == Adds simulated ADS Sens, Basic Anti-Recoil, and EXPERIMENTAL Aim Stick Micro-Movements when ADS ==
- // == WARNING: Micro-movements are highly speculative, may not work, may worsen aim, require tuning (RADIUS/SPEED) ==
- // == WARNING: Anti-Recoil is VERY basic & requires tuning, recommended you should add inventory based recoil like ar has not that much anti recoil smg has alot based on where your smg/are normally is e.g. ==
- // == for optimal aim assist: get out of fullscreen and press exit fullscren then play the game like that or if your on Chromebook like me(idk if it works on windows so don't ask) press the fullscreen button at the top of your keyboard instead of fullscreening normally, this allows mouse movements to be turned into controller movements as Fullscreen is for kbm ==
- (function() {
- console.log("Initializing Experimental KBM Mapper v9 (Micro-Movement Prototype)...");
- console.warn(">>> EXTREME WARNING: MICRO-MOVEMENTS & ANTI-RECOIL ACTIVE. HIGH BAN RISK. TUNE VALUES. HARD REFRESH FIRST! <<<");
- console.warn(">>> Micro-movements are SPECULATIVE for aim assist interaction. May have NO benefit or NEGATIVE effects. <<<");
- // --- Configuration ---
- const MOUSE_SENSITIVITY_X = 0.0025;
- const MOUSE_SENSITIVITY_Y = 0.0025;
- const ADS_SENSITIVITY_MULTIPLIER = 0.75;
- const MOUSE_DECAY = 0.85;
- const STATE_POLLING_RATE_MS = 16; // ~60Hz. Affects micro-movement smoothness & anti-recoil.
- const CONNECTION_DISPATCH_RATE_MS = 100;
- const AXIS_DEADZONE = 0.05;
- // --- Anti-Recoil Configuration ---
- const FIRE_BUTTON_INDEX = 7; // RT (Right Trigger)
- const ENABLE_ANTI_RECOIL = true; // Set to false to disable anti-recoil
- const ANTI_RECOIL_STRENGTH = 0.015; // Tune this! Positive = Pull Down.
- // --- Micro-Movement Configuration (for potential Aim Assist interaction) ---
- const ADS_BUTTON_INDEX = 6; // LT (Left Trigger)
- const ENABLE_MICRO_MOVEMENTS = true; // Set to false to disable micro-movements
- const MICRO_MOVEMENT_RADIUS = 0.02; // <<< TUNE THIS! Size of the circle. Start VERY SMALL (0.01 - 0.05).
- const MICRO_MOVEMENT_SPEED = 0.1; // <<< TUNE THIS! How fast to trace the circle (radians per update). (0.05 - 0.3) might be reasonable range to test.
- // --- Key Mapping (Simplified - Add more as needed) ---
- const keyMap = { /* ... Same as V8 ... */
- 'w': { t: 'a', a: 1, v: -1 }, 'a': { t: 'a', a: 0, v: -1 }, 's': { t: 'a', a: 1, v: 1 }, 'd': { t: 'a', a: 0, v: 1 },
- ' ': { t: 'b', i: 0 }, 'shift': { t: 'b', i: 10 }, 'control': { t: 'b', i: 11 },
- 'r': { t: 'b', i: 2 }, 'e': { t: 'b', i: 3 }, 'escape': { t: 'b', i: 9 }, 'tab': { t: 'b', i: 8 },
- 'q': { t: 'b', i: ADS_BUTTON_INDEX }, // ADS (LT)
- 'z': { t: 'b', i: FIRE_BUTTON_INDEX }, // Fire (RT)
- 'f': { t: 'b', i: 5 }, 'c': { t: 'b', i: 4 }, 'g': { t: 'b', i: 1 },
- };
- const mouseMap = { /* ... Same as V8 ... */
- 0: { t: 'b', i: FIRE_BUTTON_INDEX }, // Left Mouse -> Fire (RT)
- 2: { t: 'b', i: ADS_BUTTON_INDEX } // Right Mouse -> ADS (LT)
- };
- // --- State Tracking ---
- const controllerState = {
- axes: [0.0, 0.0, 0.0, 0.0],
- buttons: Array(17).fill(false).map((_, i) => ({ pressed: false, touched: false, value: 0.0, index: i })),
- axisKeyPresses: { 0: { neg: false, pos: false }, 1: { neg: false, pos: false } },
- mouseDeltaX: 0, mouseDeltaY: 0, isConnected: true, timestamp: performance.now(),
- microMovementAngle: 0 // Angle for circular micro-movement pattern
- };
- let pointerLocked = false;
- let stateIntervalId = null;
- let connectionIntervalId = null;
- let gameAreaElement = null;
- // --- Gamepad Object Construction --- (Same as V8)
- function createGamepadObject() { /* ... Same as V8 ... */
- const axes = controllerState.axes.map(val => Math.abs(val) < AXIS_DEADZONE ? 0.0 : val);
- return {
- axes: axes, buttons: controllerState.buttons, connected: controllerState.isConnected,
- id: "KBM Emulated Xbox Controller v9 (AR+MM)", index: 0, mapping: "standard", timestamp: controllerState.timestamp,
- };
- }
- // --- Core Simulation Function (Updates State) ---
- function updateAndSimulateGamepad() {
- let currentSensX = MOUSE_SENSITIVITY_X;
- let currentSensY = MOUSE_SENSITIVITY_Y;
- const isADS = controllerState.buttons[ADS_BUTTON_INDEX].pressed;
- const isFiring = controllerState.buttons[FIRE_BUTTON_INDEX].pressed;
- // Apply ADS sensitivity multiplier
- if (isADS) {
- currentSensX *= ADS_SENSITIVITY_MULTIPLIER;
- currentSensY *= ADS_SENSITIVITY_MULTIPLIER;
- }
- let targetRX = controllerState.axes[2]; // Target Right Stick X
- let targetRY = controllerState.axes[3]; // Target Right Stick Y
- if (pointerLocked) {
- // Apply decay to existing stick values
- targetRX *= MOUSE_DECAY;
- targetRY *= MOUSE_DECAY;
- // Add user mouse input (respecting ADS sensitivity)
- targetRX += controllerState.mouseDeltaX * currentSensX;
- targetRY += controllerState.mouseDeltaY * currentSensY;
- // *** MICRO-MOVEMENT LOGIC (Experimental Aim Assist Interaction) ***
- if (ENABLE_MICRO_MOVEMENTS && isADS) {
- // Calculate offsets for a circular pattern
- const angle = controllerState.microMovementAngle;
- const microX = Math.cos(angle) * MICRO_MOVEMENT_RADIUS;
- const microY = Math.sin(angle) * MICRO_MOVEMENT_RADIUS;
- targetRX += microX;
- targetRY += microY;
- // Increment angle for next frame, wrapping around 2*PI
- controllerState.microMovementAngle = (angle + MICRO_MOVEMENT_SPEED) % (2 * Math.PI);
- // console.log(`MicroMove: Angle=${angle.toFixed(2)}, X=${microX.toFixed(3)}, Y=${microY.toFixed(3)}`); // DEBUG
- }
- // *** END MICRO-MOVEMENT LOGIC ***
- // *** ANTI-RECOIL LOGIC ***
- if (ENABLE_ANTI_RECOIL && isFiring) {
- targetRY += ANTI_RECOIL_STRENGTH; // Add downward pull
- }
- // *** END ANTI-RECOIL LOGIC ***
- // Reset accumulated mouse deltas for next frame
- controllerState.mouseDeltaX = 0;
- controllerState.mouseDeltaY = 0;
- } else {
- // Reset right stick, deltas, and micro-movement angle if pointer isn't locked
- targetRX = 0; targetRY = 0;
- controllerState.mouseDeltaX = 0; controllerState.mouseDeltaY = 0;
- controllerState.microMovementAngle = 0; // Reset angle when lock lost
- }
- // Update axes values, clamping them to the [-1, 1] range
- controllerState.axes[0] = Math.max(-1, Math.min(1, controllerState.axes[0])); // Left Stick X
- controllerState.axes[1] = Math.max(-1, Math.min(1, controllerState.axes[1])); // Left Stick Y
- controllerState.axes[2] = Math.max(-1, Math.min(1, targetRX)); // Right Stick X
- controllerState.axes[3] = Math.max(-1, Math.min(1, targetRY)); // Right Stick Y (includes micro-move & recoil comp)
- controllerState.timestamp = performance.now();
- navigator.getGamepads = function() { return [createGamepadObject(), null, null, null]; }; // Override critical step
- }
- // --- Event Handlers --- (Same as V8 - No changes needed here) ---
- function handleKeyDown(event) { /* ... Same as V8 ... */ const key = event.key.toLowerCase(); const mappedKey = (key === 'controlleft' || key === 'controlright') ? 'control' : key; const mapping = keyMap[mappedKey]; if (!mapping) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (!button.pressed) { button.pressed = true; button.touched = true; button.value = 1.0; } } else if (mapping.t === 'a') { const axisState = controllerState.axisKeyPresses[mapping.a]; if (mapping.v < 0) axisState.neg = true; else axisState.pos = true; if (axisState.neg && axisState.pos) { controllerState.axes[mapping.a] = 0; } else { controllerState.axes[mapping.a] = axisState.neg ? -1 : 1; } } }
- function handleKeyUp(event) { /* ... Same as V8 ... */ const key = event.key.toLowerCase(); const mappedKey = (key === 'controlleft' || key === 'controlright') ? 'control' : key; const mapping = keyMap[mappedKey]; if (!mapping) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (button.pressed) { button.pressed = false; button.touched = false; button.value = 0.0; } } else if (mapping.t === 'a') { const axisState = controllerState.axisKeyPresses[mapping.a]; if (mapping.v < 0) axisState.neg = false; else axisState.pos = false; if (axisState.neg) { controllerState.axes[mapping.a] = -1; } else if (axisState.pos) { controllerState.axes[mapping.a] = 1; } else { controllerState.axes[mapping.a] = 0; } } }
- function handleMouseDown(event) { /* ... Same as V8 ... */ const mapping = mouseMap[event.button]; if (!mapping || (!pointerLocked && event.target !== gameAreaElement)) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (!button.pressed) { button.pressed = true; button.touched = true; button.value = 1.0; } } }
- function handleMouseUp(event) { /* ... Same as V8 ... */ const mapping = mouseMap[event.button]; if (!mapping) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (button.pressed) { button.pressed = false; button.touched = false; button.value = 0.0; } } }
- function handleMouseMove(event) { /* ... Same as V8 ... */ if (!pointerLocked) return; event.preventDefault(); event.stopPropagation(); const movementX = event.movementX || 0; const movementY = event.movementY || 0; controllerState.mouseDeltaX += movementX; controllerState.mouseDeltaY += movementY; }
- function handlePointerLockChange() { /* ... Same as V8 ... */ const lockedElement = document.pointerLockElement; if (lockedElement === gameAreaElement) { console.log('%cPointer Locked', 'color: lightgreen; font-weight: bold;'); pointerLocked = true; } else { console.warn(`Pointer Unlocked. Was locked to: ${gameAreaElement?.id || gameAreaElement?.tagName}`); pointerLocked = false; controllerState.axes[2] = 0; controllerState.axes[3] = 0; controllerState.mouseDeltaX = 0; controllerState.mouseDeltaY = 0; controllerState.microMovementAngle = 0; Object.values(mouseMap).forEach(mapping => { if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; button.pressed = false; button.touched = false; button.value = 0.0; } }); } }
- function requestPointerLock() { /* ... Same as V8 ... */ if (!gameAreaElement) { console.error("Cannot request pointer lock: Game area element not found."); return; } if (document.pointerLockElement !== gameAreaElement) { console.log("Requesting pointer lock on:", gameAreaElement); gameAreaElement.requestPointerLock().catch(e => { console.error("Pointer lock request failed:", e); }); } }
- function dispatchConnectionEvent() { /* ... Same as V8 ... */ try { const gamepad = createGamepadObject(); const gamepadConnectedEvent = new CustomEvent('gamepadconnected', { detail: { gamepad: gamepad } }); gamepadConnectedEvent.gamepad = gamepad; window.dispatchEvent(gamepadConnectedEvent); } catch (e) { console.error("Error dispatching periodic connection event:", e); } }
- // --- Initialization --- (Same as V8)
- console.log("Attempting to find game area element...");
- gameAreaElement = document.getElementById('game-stream') || document.querySelector('video[playsinline]') || document.querySelector('video') || document.body;
- if (!gameAreaElement || gameAreaElement === document.body) { console.warn("Could not find specific game stream element, using document.body."); gameAreaElement = document.body; } else { console.log("Found game area element:", gameAreaElement); }
- navigator.getGamepads = function() { return [createGamepadObject(), null, null, null]; };
- console.log("Initial navigator.getGamepads override set.");
- window.addEventListener('keydown', handleKeyDown, { capture: true }); window.addEventListener('keyup', handleKeyUp, { capture: true });
- const mouseEventTarget = gameAreaElement; mouseEventTarget.addEventListener('mousemove', handleMouseMove, { capture: true }); mouseEventTarget.addEventListener('mousedown', handleMouseDown, { capture: true }); mouseEventTarget.addEventListener('mouseup', handleMouseUp, { capture: true });
- document.addEventListener('pointerlockchange', handlePointerLockChange, false);
- if (gameAreaElement && gameAreaElement !== document.body) { gameAreaElement.addEventListener('click', requestPointerLock); console.log(">>> CLICK THE GAME AREA TO ENABLE MOUSE AIM <<<"); } else { console.warn("Game area is body or not found. Click anywhere on the page body to attempt pointer lock."); document.body.addEventListener('click', requestPointerLock); }
- try { dispatchConnectionEvent(); console.log("Dispatched initial gamepadconnected event."); } catch (e) { console.error("Error dispatching initial connection event:", e); }
- stateIntervalId = setInterval(updateAndSimulateGamepad, STATE_POLLING_RATE_MS);
- connectionIntervalId = setInterval(dispatchConnectionEvent, CONNECTION_DISPATCH_RATE_MS);
- console.log(`%cKBM Mapper V9 Active! State polling ID: ${stateIntervalId}, Connection dispatch ID: ${connectionIntervalId}.`, "color: yellow;");
- if (ENABLE_ANTI_RECOIL) console.log(`Basic Anti-Recoil ACTIVE. Strength: ${ANTI_RECOIL_STRENGTH}. TUNE THIS!`); else console.log("Anti-Recoil DISABLED.");
- if (ENABLE_MICRO_MOVEMENTS) console.log(`Micro-Movements ACTIVE when ADS. Radius: ${MICRO_MOVEMENT_RADIUS}, Speed: ${MICRO_MOVEMENT_SPEED}. TUNE THESE!`); else console.log("Micro-Movements DISABLED.");
- console.warn(">>> REMEMBER: HIGH BAN RISK with these features enabled. Use responsibly! <<<");
- console.log("To disable, refresh page or type: stopKbmMapper();");
- // --- Cleanup Function --- (Same as V8)
- window.stopKbmMapper = function() { /* ... Same as V8 ... */ console.log("Stopping KBM Mapper V9..."); if (stateIntervalId) clearInterval(stateIntervalId); if (connectionIntervalId) clearInterval(connectionIntervalId); stateIntervalId = null; connectionIntervalId = null; window.removeEventListener('keydown', handleKeyDown, { capture: true }); window.removeEventListener('keyup', handleKeyUp, { capture: true }); mouseEventTarget.removeEventListener('mousemove', handleMouseMove, { capture: true }); mouseEventTarget.removeEventListener('mousedown', handleMouseDown, { capture: true }); mouseEventTarget.removeEventListener('mouseup', handleMouseUp, { capture: true }); document.removeEventListener('pointerlockchange', handlePointerLockChange, false); if (gameAreaElement) gameAreaElement.removeEventListener('click', requestPointerLock); if (document.body && gameAreaElement === document.body) document.body.removeEventListener('click', requestPointerLock); if (document.pointerLockElement) { document.exitPointerLock(); } navigator.getGamepads = function() { return [null, null, null, null]; }; console.log("KBM Mapper stopped. Event listeners removed. Gamepad override disabled. Refresh recommended."); };
- })(); // End of IIFE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement