feat: press in-game keys based on keyboard events
This commit is contained in:
@@ -17,5 +17,8 @@
|
||||
"run_at": "document_idle"
|
||||
}
|
||||
],
|
||||
"permissions": ["storage"]
|
||||
"background": {
|
||||
"service_worker": "dist/background.js"
|
||||
},
|
||||
"permissions": ["storage", "tabs", "debugger"]
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"version": "1.0.0",
|
||||
"description": "Tweaks for WoV Assassins Convention",
|
||||
"scripts": {
|
||||
"build": "esbuild src/content.ts src/popup.ts --bundle --outdir=dist --platform=browser --target=chrome120",
|
||||
"watch": "esbuild src/content.ts src/popup.ts --bundle --outdir=dist --platform=browser --target=chrome120 --watch",
|
||||
"build": "esbuild src/content.ts src/popup.ts src/background.ts --bundle --outdir=dist --platform=browser --target=chrome120",
|
||||
"watch": "esbuild src/content.ts src/popup.ts src/background.ts --bundle --outdir=dist --platform=browser --target=chrome120 --watch",
|
||||
"dev": "pnpm watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
28
src/background.ts
Normal file
28
src/background.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
type SimulateClickMessage = {
|
||||
type: "simulate-click";
|
||||
x: number;
|
||||
y: number;
|
||||
};
|
||||
|
||||
chrome.runtime.onMessage.addListener((message: SimulateClickMessage) => {
|
||||
if (message.type !== "simulate-click") return;
|
||||
|
||||
const { x, y } = message;
|
||||
|
||||
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
||||
if (!tabs[0]?.id) return;
|
||||
const target = { tabId: tabs[0].id! };
|
||||
|
||||
chrome.debugger.attach(target, "1.2", () => {
|
||||
if (chrome.runtime.lastError) return;
|
||||
|
||||
chrome.debugger.sendCommand(target, "Input.dispatchMouseEvent", { type: "mouseMoved", x, y }, () => {
|
||||
chrome.debugger.sendCommand(target, "Input.dispatchMouseEvent", { type: "mousePressed", button: "left", x, y, clickCount: 1 }, () => {
|
||||
chrome.debugger.sendCommand(target, "Input.dispatchMouseEvent", { type: "mouseReleased", button: "left", x, y, clickCount: 1 }, () => {
|
||||
chrome.debugger.detach(target);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,14 +1,13 @@
|
||||
import { State, STORAGE_KEY } from "./types";
|
||||
|
||||
const KEY_BINDINGS: Record<string, string> = {
|
||||
// TODO
|
||||
};
|
||||
|
||||
let enabled = false;
|
||||
|
||||
const clickButton = (selector: string): void => {
|
||||
const el = document.querySelector<HTMLElement>(selector);
|
||||
el?.click();
|
||||
const findButtonForKey = (key: string): HTMLElement | null => {
|
||||
if (key.length !== 1 || !/[a-zA-Z]/.test(key)) return null;
|
||||
const letter = key.toUpperCase();
|
||||
const label = Array.from(document.querySelectorAll<HTMLElement>("div[dir=\"auto\"]"))
|
||||
.find(el => el.textContent === letter);
|
||||
return label?.closest<HTMLElement>("[tabindex=\"0\"]") ?? null;
|
||||
};
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent): void => {
|
||||
@@ -21,10 +20,15 @@ const onKeyDown = (event: KeyboardEvent): void => {
|
||||
target.isContentEditable
|
||||
) return;
|
||||
|
||||
const selector = KEY_BINDINGS[event.code];
|
||||
if (selector) {
|
||||
const btn = findButtonForKey(event.key);
|
||||
if (btn) {
|
||||
event.preventDefault();
|
||||
clickButton(selector);
|
||||
const rect = btn.getBoundingClientRect();
|
||||
chrome.runtime.sendMessage({
|
||||
type: "simulate-click",
|
||||
x: rect.left + rect.width / 2,
|
||||
y: rect.top + rect.height / 2,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,7 +37,7 @@ const init = async (): Promise<void> => {
|
||||
const state = result[STORAGE_KEY] as State | undefined;
|
||||
enabled = state?.enabled ?? true;
|
||||
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
document.addEventListener("keydown", onKeyDown, { capture: true });
|
||||
|
||||
chrome.storage.onChanged.addListener((changes) => {
|
||||
if (STORAGE_KEY in changes) {
|
||||
|
||||
Reference in New Issue
Block a user