Andrii Dokhniak e23cac512e upd
2025-08-05 11:27:44 +02:00

233 lines
5.6 KiB
TypeScript

// make the export accessible from inline js
import * as main from "./main";
// for some reason doing the same with the window object doesn't work
(globalThis as any).main = main;
import {
backButton,
clicksLog,
homeButton,
socket,
screen,
adid_priv_info_table,
lat_priv_info_table,
lon_priv_info_table,
recentButton,
} from "./shared";
import { start_notifications } from "./notifications";
import { start_traffic_log } from "./traffic_log";
export { download_har, inspect_har } from "./traffic_log";
export function reset_adid_handler(_: Event) {
socket.emit("reset_adid");
}
export function coords_handler(e: FormDataEvent) {
e.preventDefault();
const form_data = new FormData(e.target as HTMLFormElement);
socket.emit("setcoord", {
lon: Number.parseFloat(form_data.get("lon") as string),
lat: Number.parseFloat(form_data.get("lat") as string),
});
}
export function open_tab(evt: Event, tab_name: string) {
let i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
if (tabcontent[i].id != tab_name) {
tabcontent[i].classList.remove("active");
} else {
tabcontent[i].classList.add("active");
}
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("active");
}
// Show the current tab, and add an "active" class to the button that opened the tab
(evt.currentTarget as HTMLElement).classList.add("active");
}
let lastTouch = new Date().getTime();
export const calculateElapsedTime = () => {
const currentTouch = new Date().getTime();
const elapsedTime = currentTouch - lastTouch;
const elapsedSec = Math.round(elapsedTime / 1000);
lastTouch = currentTouch;
return elapsedSec;
};
export const waitToLog = (clickInfoText: string) => {
const clickInfo = document.createElement("span");
const waitInfo = document.createElement("span");
waitInfo.textContent = `await wait(${calculateElapsedTime()});`;
clicksLog.appendChild(waitInfo);
clickInfo.textContent = clickInfoText;
clicksLog.appendChild(clickInfo);
};
export const registerClick = ({
path,
logText,
body,
}: {
path: string;
logText: string;
body?: any;
}) => {
waitToLog(logText);
socket.emit(path, body ? body : {});
};
homeButton.addEventListener("click", () =>
registerClick({ path: "home", logText: "await homeButton();" })
);
backButton.addEventListener("click", () =>
registerClick({ path: "back", logText: "await backButton();" })
);
recentButton.addEventListener("click", () =>
registerClick({ path: "recent", logText: "await recentButton();" })
);
socket.on("screenshot_data", (data) => {
try {
const blob = new Blob([data]);
screen.src = URL.createObjectURL(blob);
} catch (error) {
console.error("Error fetching image: ", error);
}
});
socket.on("private_info", (data) => {
console.log("private_info");
adid_priv_info_table.textContent = data.adid;
lat_priv_info_table.textContent = data.latitude;
lon_priv_info_table.textContent = data.longitude;
});
socket.emit("private_info_req");
socket.onAny((ev, ...args) => {
console.log("ev: ", ev, args);
});
async function displayImage() {
socket.emit("screenshot");
}
let isDragging = false;
const screenSize = [320, 640];
export function calcMousePos(event: MouseEvent) {
let rect = screen.getBoundingClientRect();
let x = ((event.clientX - rect.left) / rect.width) * screenSize[0];
let y = ((event.clientY - rect.top) / rect.height) * screenSize[1];
x = Math.min(Math.max(x, 0), screenSize[0]);
y = Math.min(Math.max(y, 0), screenSize[1]);
return { x, y };
}
screen.addEventListener(
"mousemove",
(event) => {
if (!isDragging) return;
let pos = calcMousePos(event);
if (isDragging) {
registerClick({
path: "motionevent",
logText: `await motionevent({motionType: "MOVE", x:${pos.x},y:${pos.y}}});`,
body: {
motionType: "MOVE",
x: pos.x,
y: pos.y,
},
});
}
},
false
);
export const handleDraggStart = (event: MouseEvent) => {
isDragging = true;
let pos = calcMousePos(event);
registerClick({
path: "motionevent",
logText: `await motionevent({motionType: "DOWN", x:${pos.x},y:${pos.y}}});`,
body: {
motionType: "DOWN",
x: pos.x,
y: pos.y,
},
});
};
screen.addEventListener("mousedown", handleDraggStart);
document.addEventListener("mouseup", (e) => {
if (!isDragging) return;
isDragging = false;
let pos = calcMousePos(e);
registerClick({
path: "motionevent",
logText: `await motionevent({motionType: "MOVE", x:${pos.x},y:${pos.y}}});`,
body: {
motionType: "MOVE",
x: pos.x,
y: pos.y,
},
});
registerClick({
path: "motionevent",
logText: `await motionevent({motionType: "UP", x:${pos.x},y:${pos.y}}});`,
body: {
motionType: "UP",
x: pos.x,
y: pos.y,
},
});
});
window.addEventListener("keydown", (event) => {
let key = event.key;
if (key === "Space") key = " ";
else if (key !== "Enter" && key !== "Backspace" && key.length !== 1) return;
console.log(event.key, key);
if (screen.matches(":hover")) {
registerClick({
path: "key",
logText: `await key(${event.key});`,
body: { key },
});
}
});
export async function sleep(time: number) {
return new Promise((resolve) => setTimeout(resolve, time));
}
async function screenshot_loop() {
var before;
while (true) {
before = performance.now();
await displayImage();
// TODO: Make this dynamic again
while (performance.now() - before < 100) await sleep(50);
}
}
screenshot_loop();
start_notifications();
start_traffic_log();