feat: press in-game keys based on keyboard events
This commit is contained in:
@@ -17,5 +17,8 @@
|
|||||||
"run_at": "document_idle"
|
"run_at": "document_idle"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions": ["storage"]
|
"background": {
|
||||||
|
"service_worker": "dist/background.js"
|
||||||
|
},
|
||||||
|
"permissions": ["storage", "tabs", "debugger"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Tweaks for WoV Assassins Convention",
|
"description": "Tweaks for WoV Assassins Convention",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "esbuild src/content.ts src/popup.ts --bundle --outdir=dist --platform=browser --target=chrome120",
|
"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 --bundle --outdir=dist --platform=browser --target=chrome120 --watch",
|
"watch": "esbuild src/content.ts src/popup.ts src/background.ts --bundle --outdir=dist --platform=browser --target=chrome120 --watch",
|
||||||
"dev": "pnpm watch"
|
"dev": "pnpm watch"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"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";
|
import { State, STORAGE_KEY } from "./types";
|
||||||
|
|
||||||
const KEY_BINDINGS: Record<string, string> = {
|
|
||||||
// TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
let enabled = false;
|
let enabled = false;
|
||||||
|
|
||||||
const clickButton = (selector: string): void => {
|
const findButtonForKey = (key: string): HTMLElement | null => {
|
||||||
const el = document.querySelector<HTMLElement>(selector);
|
if (key.length !== 1 || !/[a-zA-Z]/.test(key)) return null;
|
||||||
el?.click();
|
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 => {
|
const onKeyDown = (event: KeyboardEvent): void => {
|
||||||
@@ -21,10 +20,15 @@ const onKeyDown = (event: KeyboardEvent): void => {
|
|||||||
target.isContentEditable
|
target.isContentEditable
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
const selector = KEY_BINDINGS[event.code];
|
const btn = findButtonForKey(event.key);
|
||||||
if (selector) {
|
if (btn) {
|
||||||
event.preventDefault();
|
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;
|
const state = result[STORAGE_KEY] as State | undefined;
|
||||||
enabled = state?.enabled ?? true;
|
enabled = state?.enabled ?? true;
|
||||||
|
|
||||||
document.addEventListener("keydown", onKeyDown);
|
document.addEventListener("keydown", onKeyDown, { capture: true });
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener((changes) => {
|
chrome.storage.onChanged.addListener((changes) => {
|
||||||
if (STORAGE_KEY in changes) {
|
if (STORAGE_KEY in changes) {
|
||||||
|
|||||||
Reference in New Issue
Block a user