upd
This commit is contained in:
parent
c64c17d86e
commit
8d528f294a
@ -1,10 +1,9 @@
|
|||||||
import { WebSocketServer } from "ws";
|
|
||||||
import child_process from "child_process";
|
import child_process from "child_process";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { send_notification } from "./notifications.mjs";
|
import { Server } from "socket.io";
|
||||||
|
|
||||||
async function spawnPromise(program, args) {
|
async function spawnPromise(program, args) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, _reject) => {
|
||||||
let output = "";
|
let output = "";
|
||||||
const process = child_process.spawn(program, args);
|
const process = child_process.spawn(program, args);
|
||||||
process.stdout.on("data", (data) => {
|
process.stdout.on("data", (data) => {
|
||||||
@ -19,58 +18,111 @@ async function spawnPromise(program, args) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const wss = new WebSocketServer({ port: 3000 });
|
let io = new Server();
|
||||||
|
|
||||||
|
async function send_private_data() {
|
||||||
|
let adid = fs.readFileSync("/adid").toString();
|
||||||
|
let gps_coords = await spawnPromise("bash", ["/conf/get_location.sh"])
|
||||||
|
gps_coords = gps_coords.output;
|
||||||
|
gps_coords = gps_coords.trim().split(',');
|
||||||
|
io.emit("private_info", {adid, latitude: gps_coords[0], longitude: gps_coords[1]})
|
||||||
|
}
|
||||||
|
|
||||||
|
function send_notification(socket, is_ok, context, message) {
|
||||||
|
socket.emit("notification", {
|
||||||
|
is_ok,
|
||||||
|
context,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let screenshot_in_flight = false;
|
||||||
//maybe check output of child processes and send errors in some way
|
//maybe check output of child processes and send errors in some way
|
||||||
wss.on("connection", (ws) => {
|
io.on("connection", (socket) => {
|
||||||
ws.on("message", async (dataBuf) => {
|
socket.onAny((ev, ...args) => {
|
||||||
let data = dataBuf.toString();
|
console.log("server got: ", ev, ...args);
|
||||||
if (data === "screenshot") {
|
});
|
||||||
await spawnPromise("bash", ["/conf/screenshot.sh"]);
|
socket.on("screenshot", async () => {
|
||||||
ws.send(fs.readFileSync("/screenshot.png"));
|
if (screenshot_in_flight)
|
||||||
} else if (data.includes("touch")) {
|
return;
|
||||||
const dataSplit = data.split(" ");
|
screenshot_in_flight = true;
|
||||||
await spawnPromise("bash", [
|
let screen = await fetch("http://localhost:9987/v2/uiDevice/screenshot");
|
||||||
"/conf/touch.sh",
|
let body = await screen.bytes();
|
||||||
dataSplit[1],
|
socket.emit("screenshot_data", body);
|
||||||
dataSplit[2],
|
screenshot_in_flight = false;
|
||||||
]);
|
});
|
||||||
} else if (data === "back") {
|
|
||||||
|
socket.on("private_info_req", async () => {
|
||||||
|
await send_private_data();
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on("reset_adid", async () => {
|
||||||
|
await spawnPromise("bash", ["/conf/reset_adid.sh"]);
|
||||||
|
await send_private_data();
|
||||||
|
})
|
||||||
|
|
||||||
|
socket.on("back", async () => {
|
||||||
await spawnPromise("bash", ["/conf/back.sh"]);
|
await spawnPromise("bash", ["/conf/back.sh"]);
|
||||||
} else if (data === "home") {
|
});
|
||||||
|
|
||||||
|
socket.on("home", async () => {
|
||||||
await spawnPromise("bash", ["/conf/home.sh"]);
|
await spawnPromise("bash", ["/conf/home.sh"]);
|
||||||
} else if (data === "install") {
|
});
|
||||||
|
|
||||||
|
socket.on("install", async () => {
|
||||||
const res = await spawnPromise("bash", ["/conf/install.sh"]);
|
const res = await spawnPromise("bash", ["/conf/install.sh"]);
|
||||||
send_notification(
|
send_notification(
|
||||||
|
socket,
|
||||||
res.code === 0,
|
res.code === 0,
|
||||||
"Installing the application",
|
"Installing the application",
|
||||||
res.output
|
res.output
|
||||||
);
|
);
|
||||||
} else if (data.includes("drag")) {
|
});
|
||||||
const dataSplit = data.split(" ");
|
|
||||||
|
|
||||||
|
// drag handles both drag and click
|
||||||
|
socket.on("motionevent", async (data) => {
|
||||||
|
await spawnPromise("bash", [
|
||||||
|
"/conf/motionevent.sh",
|
||||||
|
data.motionType,
|
||||||
|
data.x + "",
|
||||||
|
data.y + ""
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
// drag handles both drag and click
|
||||||
|
socket.on("drag", async (data) => {
|
||||||
await spawnPromise("bash", [
|
await spawnPromise("bash", [
|
||||||
"/conf/drag.sh",
|
"/conf/drag.sh",
|
||||||
dataSplit[1],
|
data.startX + "",
|
||||||
dataSplit[2],
|
data.startY + "",
|
||||||
dataSplit[3],
|
data.endX + "",
|
||||||
dataSplit[4],
|
data.endY + "",
|
||||||
|
data.dragTime + "",
|
||||||
]);
|
]);
|
||||||
} else if (data.startsWith("setcoord")) {
|
});
|
||||||
const dataSplit = data.split(" ");
|
|
||||||
|
socket.on("key", async (data) => {
|
||||||
|
await spawnPromise("bash", [
|
||||||
|
"/conf/press_key.sh",
|
||||||
|
data.key
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("setcoord", async (data) => {
|
||||||
const res = await spawnPromise("bash", [
|
const res = await spawnPromise("bash", [
|
||||||
"/conf/set_geo.sh",
|
"/conf/set_geo.sh",
|
||||||
dataSplit[1],
|
data.lon + "",
|
||||||
dataSplit[2],
|
data.lat + "",
|
||||||
]);
|
]);
|
||||||
send_notification(
|
send_notification(
|
||||||
|
socket,
|
||||||
res.code === 0,
|
res.code === 0,
|
||||||
"Setting the moch location",
|
"Setting the moch location",
|
||||||
res.output
|
res.output
|
||||||
);
|
);
|
||||||
}
|
await send_private_data();
|
||||||
});
|
|
||||||
ws.on("close", (_) => {
|
|
||||||
ws.close();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
io.listen(3000);
|
||||||
|
console.log("listening on port 3000");
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
import { WebSocket } from "ws";
|
|
||||||
import { WebSocketServer } from "ws";
|
|
||||||
|
|
||||||
const notification_proxy = new WebSocketServer({ port: 3001 });
|
|
||||||
let notification_subs = [];
|
|
||||||
|
|
||||||
notification_proxy.on("connection", (ws) => {
|
|
||||||
notification_subs.push(ws);
|
|
||||||
});
|
|
||||||
|
|
||||||
export function send_notification(is_ok, context, message) {
|
|
||||||
let updated_subs = [];
|
|
||||||
|
|
||||||
if (notification_subs.length === 0) {
|
|
||||||
console.log("WARNING: Got a notification, but nobody is subscribed");
|
|
||||||
}
|
|
||||||
for (const sub of notification_subs) {
|
|
||||||
if (sub.readyState == WebSocket.CONNECTING) {
|
|
||||||
console.log(
|
|
||||||
"WARNING: Unable to forward a notification to client that is still connecting"
|
|
||||||
);
|
|
||||||
updated_subs.push(sub);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
sub.send(
|
|
||||||
JSON.stringify({
|
|
||||||
is_ok,
|
|
||||||
context,
|
|
||||||
message,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
updated_subs.push(sub);
|
|
||||||
} catch {
|
|
||||||
sub.close();
|
|
||||||
console.log(
|
|
||||||
"WARNING: Fail to send a notification, closing the connection"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
notification_subs = updated_subs;
|
|
||||||
}
|
|
422
android/code/package-lock.json
generated
422
android/code/package-lock.json
generated
@ -5,9 +5,267 @@
|
|||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"socket.io": "^4.8.1",
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@socket.io/component-emitter": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/cors": {
|
||||||
|
"version": "2.8.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.18.tgz",
|
||||||
|
"integrity": "sha512-nX3d0sxJW41CqQvfOzVG1NCTXfFDrDWIghCZncpHeWlVFd81zxB/DLhg7avFg6eHLCRX7ckBmoIIcqa++upvJA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "22.15.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz",
|
||||||
|
"integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/accepts": {
|
||||||
|
"version": "1.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
|
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-types": "~2.1.34",
|
||||||
|
"negotiator": "0.6.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/base64id": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^4.5.0 || >= 5.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cors": "^2.8.12",
|
||||||
|
"@types/node": ">=10.0.0",
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "2.0.0",
|
||||||
|
"cookie": "~0.7.2",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~5.2.1",
|
||||||
|
"ws": "~8.17.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-parser": {
|
||||||
|
"version": "5.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||||
|
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io/node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/negotiator": {
|
||||||
|
"version": "0.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io": {
|
||||||
|
"version": "4.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
|
||||||
|
"integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "~2.0.0",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.2",
|
||||||
|
"engine.io": "~6.6.0",
|
||||||
|
"socket.io-adapter": "~2.5.2",
|
||||||
|
"socket.io-parser": "~4.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-adapter": {
|
||||||
|
"version": "2.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
|
||||||
|
"integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "~4.3.4",
|
||||||
|
"ws": "~8.17.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-adapter/node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.18.0",
|
"version": "8.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||||
@ -30,6 +288,170 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="
|
||||||
|
},
|
||||||
|
"@types/cors": {
|
||||||
|
"version": "2.8.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.18.tgz",
|
||||||
|
"integrity": "sha512-nX3d0sxJW41CqQvfOzVG1NCTXfFDrDWIghCZncpHeWlVFd81zxB/DLhg7avFg6eHLCRX7ckBmoIIcqa++upvJA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "22.15.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz",
|
||||||
|
"integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==",
|
||||||
|
"requires": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
|
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "~2.1.34",
|
||||||
|
"negotiator": "0.6.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"base64id": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||||
|
},
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="
|
||||||
|
},
|
||||||
|
"cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
|
||||||
|
"requires": {
|
||||||
|
"@types/cors": "^2.8.12",
|
||||||
|
"@types/node": ">=10.0.0",
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "2.0.0",
|
||||||
|
"cookie": "~0.7.2",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~5.2.1",
|
||||||
|
"ws": "~8.17.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"requires": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-parser": {
|
||||||
|
"version": "5.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||||
|
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q=="
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.52.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||||
|
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.35",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||||
|
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "1.52.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
},
|
||||||
|
"negotiator": {
|
||||||
|
"version": "0.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
|
||||||
|
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
|
||||||
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
|
||||||
|
},
|
||||||
|
"socket.io": {
|
||||||
|
"version": "4.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
|
||||||
|
"integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "~2.0.0",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.2",
|
||||||
|
"engine.io": "~6.6.0",
|
||||||
|
"socket.io-adapter": "~2.5.2",
|
||||||
|
"socket.io-parser": "~4.2.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-adapter": {
|
||||||
|
"version": "2.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
|
||||||
|
"integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "~4.3.4",
|
||||||
|
"ws": "~8.17.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"requires": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-parser": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||||
|
"requires": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
|
||||||
|
},
|
||||||
|
"vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
|
||||||
|
},
|
||||||
"ws": {
|
"ws": {
|
||||||
"version": "8.18.0",
|
"version": "8.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"socket.io": "^4.8.1",
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
/opt/android-sdk-linux/platform-tools/adb shell input swipe $1 $2 $3 $4 1000
|
/opt/android-sdk-linux/platform-tools/adb shell input swipe $1 $2 $3 $4 $5
|
||||||
|
2
android/conf/get_location.sh
Normal file
2
android/conf/get_location.sh
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
adb shell dumpsys location | grep 'last location=' | head -n 1 | awk -F' ' '{ print $3 }'
|
1
android/conf/motionevent.sh
Normal file
1
android/conf/motionevent.sh
Normal file
@ -0,0 +1 @@
|
|||||||
|
/opt/android-sdk-linux/platform-tools/adb shell input motionevent $1 $2 $3
|
9
android/conf/press_key.sh
Normal file
9
android/conf/press_key.sh
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# https://stackoverflow.com/questions/7789826/adb-shell-input-events
|
||||||
|
if [ "$1" = "Enter" ]; then
|
||||||
|
/opt/android-sdk-linux/platform-tools/adb shell input keyevent 66
|
||||||
|
elif [ "$1" = "Backspace" ]; then
|
||||||
|
/opt/android-sdk-linux/platform-tools/adb shell input keyevent 67
|
||||||
|
else
|
||||||
|
/opt/android-sdk-linux/platform-tools/adb shell input text "'$1'"
|
||||||
|
fi
|
13
android/conf/reset_adid.sh
Normal file
13
android/conf/reset_adid.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
# Change the file slightly
|
||||||
|
echo | adb shell su root "tee /data/data/com.google.android.gms/shared_prefs/adid_settings.xml"
|
||||||
|
|
||||||
|
# Ask android for the ADID. Android detects the changed file (somewhere), and regenerates it
|
||||||
|
adb shell su root am start -W -n com.example.adidreader/com.example.adidreader.MainActivity
|
||||||
|
|
||||||
|
sleep 0.1
|
||||||
|
|
||||||
|
# Get the new ADID
|
||||||
|
adb shell su root cat /data/data/com.google.android.gms/shared_prefs/adid_settings.xml | xmllint --xpath 'string(//map/string[@name="adid_key"])' - > /adid
|
@ -1 +0,0 @@
|
|||||||
curl http://localhost:9987/v2/uiDevice/screenshot -o /screenshot.png
|
|
@ -3,9 +3,17 @@ ko=$((
|
|||||||
echo "auth $(cat ~/.emulator_console_auth_token)"
|
echo "auth $(cat ~/.emulator_console_auth_token)"
|
||||||
echo "geo fix $1 $2 0.0"
|
echo "geo fix $1 $2 0.0"
|
||||||
sleep 0.2
|
sleep 0.2
|
||||||
) | telnet localhost 5554 | grep KO: );
|
) | telnet localhost 5554 2> /dev/null | grep KO: );
|
||||||
|
|
||||||
if [ -z "${ko}" ]; then
|
if [ -z "${ko}" ]; then
|
||||||
|
# Check if the location was actually set, for some reason the location moching doesn't work,
|
||||||
|
# unless google maps is launched first, and is given access to the phone location
|
||||||
|
adb shell dumpsys location | grep 'last location=Location\[gps' > /dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo Failed to actually set the location, probably need to launch google maps first
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo Succesfully set the coordinates to: $(. /conf/get_location.sh)
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo "$ko"
|
echo "$ko"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
set -xe
|
||||||
rm -f /opt/android-sdk-linux/.android/avd/virtual_dev.avd/*.lock
|
rm -f /opt/android-sdk-linux/.android/avd/virtual_dev.avd/*.lock
|
||||||
adb start-server
|
adb start-server
|
||||||
cat > /simple.gpx << EOF
|
cat > /simple.gpx << EOF
|
||||||
@ -9,8 +10,11 @@ cat > /simple.gpx << EOF
|
|||||||
</gpx>
|
</gpx>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
emulator -grpc 5556 -avd virtual_dev -snapshot configured -no-window -no-audio -debug all,-adb,-gles1emu,-gles,-mtport,-metrics,-memory,-car,-tvremote &
|
emulator -avd virtual_dev -writable-system -no-window -no-audio &
|
||||||
adb wait-for-device
|
adb wait-for-device
|
||||||
|
adb emu avd snapshot load configured
|
||||||
|
# emulator -grpc 5556 -avd virtual_dev -snapshot configured -no-window -no-audio -no-metrics -debug-no > /dev/null &
|
||||||
|
# adb wait-for-device
|
||||||
|
|
||||||
export PATH=$PATH:/root/culebraDependencies
|
export PATH=$PATH:/root/culebraDependencies
|
||||||
cd /root/culebra
|
cd /root/culebra
|
||||||
|
@ -6,6 +6,6 @@ WORKDIR /code
|
|||||||
|
|
||||||
RUN mkdir /images
|
RUN mkdir /images
|
||||||
|
|
||||||
ENV screenshotDelayMs 500
|
ENV screenshotDelayMs 100
|
||||||
|
|
||||||
CMD sh /code/docker-entrypoint.sh
|
CMD sh /code/docker-entrypoint.sh
|
@ -2,7 +2,5 @@
|
|||||||
|
|
||||||
npm i
|
npm i
|
||||||
npm run build
|
npm run build
|
||||||
node waitSocket.mjs
|
|
||||||
node --watch index.mjs
|
node --watch index.mjs
|
||||||
|
|
||||||
#tail -f /dev/null
|
#tail -f /dev/null
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head style="height: 100vh">
|
<head style="height: 100vh">
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
@ -43,7 +43,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#clicks-log {
|
#clicks-log {
|
||||||
font-family: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
|
font-family:
|
||||||
|
Menlo,
|
||||||
|
Consolas,
|
||||||
|
Monaco,
|
||||||
|
Liberation Mono,
|
||||||
|
Lucida Console,
|
||||||
monospace;
|
monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +79,7 @@
|
|||||||
}
|
}
|
||||||
.tabcontent.active {
|
.tabcontent.active {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,14 +91,15 @@
|
|||||||
border-top: none;
|
border-top: none;
|
||||||
}
|
}
|
||||||
html,
|
html,
|
||||||
body, main{
|
body,
|
||||||
|
main {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
main {
|
main {
|
||||||
display:flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
@ -104,28 +111,35 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.screen-section #screen, .screen-section.screen_buttons {
|
.screen-section #screen,
|
||||||
|
.screen-section.screen_buttons {
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
.tab-section {
|
#screen {
|
||||||
display: flex; flex-direction: column; flex-grow: 1;
|
user-select: none;
|
||||||
|
}
|
||||||
|
.tab-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
<!-- TODO: A notification system -->
|
|
||||||
#resp {
|
#resp {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#upload_form {
|
#upload_form {
|
||||||
display:flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
#upload_form button, #upload_form label {
|
#upload_form button,
|
||||||
|
#upload_form label {
|
||||||
border: 2px solid #ccc;
|
border: 2px solid #ccc;
|
||||||
background-color: #f1f1f1;
|
background-color: #f1f1f1;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
transition: 0.3s;
|
transition: 0.3s;
|
||||||
}
|
}
|
||||||
#upload_form button:hover, #upload_form label:hover {
|
#upload_form button:hover,
|
||||||
|
#upload_form label:hover {
|
||||||
background-color: #ddd;
|
background-color: #ddd;
|
||||||
}
|
}
|
||||||
#notifications {
|
#notifications {
|
||||||
@ -137,9 +151,9 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="notifications"></div>
|
<div id="notifications"></div>
|
||||||
<div id="resp" style="display: none;"></div>
|
<div id="resp" style="display: none"></div>
|
||||||
<main>
|
<main>
|
||||||
<section class="screen-section" >
|
<section class="screen-section">
|
||||||
<img
|
<img
|
||||||
id="screen"
|
id="screen"
|
||||||
alt="android screen"
|
alt="android screen"
|
||||||
@ -147,42 +161,113 @@
|
|||||||
draggable="false"
|
draggable="false"
|
||||||
class="screen"
|
class="screen"
|
||||||
style="flex-grow: 0"
|
style="flex-grow: 0"
|
||||||
|
tabindex="0"
|
||||||
/>
|
/>
|
||||||
<div class="screen-buttons" style="flex-grow: 0">
|
<div class="screen-buttons" style="flex-grow: 0">
|
||||||
<button class="screen-buttons-home">home</button>
|
<button class="screen-buttons-home">home</button>
|
||||||
<button class="screen-buttons-back">back</button>
|
<button class="screen-buttons-back">back</button>
|
||||||
</div>
|
</div>
|
||||||
<form id="upload_form" hx-post="/upload_apk" enctype="multipart/form-data" hx-target="#resp">
|
<form
|
||||||
<label id="upload_input" for="app">Select file
|
id="upload_form"
|
||||||
<input type="file" id="app" name="app" accept=".apk" required multiple/>
|
hx-post="/upload_apk"
|
||||||
|
enctype="multipart/form-data"
|
||||||
|
hx-target="#resp"
|
||||||
|
>
|
||||||
|
<label id="upload_input" for="app"
|
||||||
|
>Select file
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
id="app"
|
||||||
|
name="app"
|
||||||
|
accept=".apk"
|
||||||
|
required
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
<button type="submit">Install the app</button>
|
<button type="submit">Install the app</button>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="tab-section" >
|
<div class="tab-section">
|
||||||
<form id="set_coords" hx-post="/setcoord" hx-target="#resp">
|
|
||||||
<input type="text" name="lon"/>
|
|
||||||
<input type="text" name="lat"/>
|
|
||||||
<button type="submit">Submit coords</button>
|
|
||||||
</form>
|
|
||||||
<div class="tab">
|
<div class="tab">
|
||||||
<button class="tablinks active" onclick="open_tab(event, 'httptoolkit-tab')">HttpToolkit UI</button>
|
<button
|
||||||
<button class="tablinks" onclick="open_tab(event, 'logs-tab')">Logs</button>
|
class="tablinks active"
|
||||||
|
onclick="open_tab(event, 'httptoolkit-tab')"
|
||||||
|
>
|
||||||
|
HttpToolkit UI
|
||||||
|
</button>
|
||||||
|
<button class="tablinks" onclick="open_tab(event, 'logs-tab')">
|
||||||
|
Logs
|
||||||
|
</button>
|
||||||
|
<button class="tablinks" onclick="open_tab(event, 'controls-tab')">
|
||||||
|
Device Controls
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tabcontent" id="logs-tab">
|
<div class="tabcontent" id="logs-tab">
|
||||||
<p id="clicks-log" class="log-section" ></p>
|
<p id="clicks-log" class="log-section"></p>
|
||||||
<p id="traffic-log" class="log-section"></p>
|
<p id="traffic-log" class="log-section"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tabcontent active" id="httptoolkit-tab">
|
<div class="tabcontent active" id="httptoolkit-tab">
|
||||||
<iframe id="httptoolkit-frame" style="flex-grow: 1;" src="http://localhost:9080/" title="httptoolkit"></iframe>
|
<iframe
|
||||||
|
id="httptoolkit-frame"
|
||||||
|
style="flex-grow: 1"
|
||||||
|
src="http://localhost:9080/"
|
||||||
|
title="httptoolkit"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="tabcontent" id="controls-tab">
|
||||||
|
<form id="set_coords" onsubmit="coords_handler(event)">
|
||||||
|
<label>
|
||||||
|
Latitude:
|
||||||
|
<input type="text" name="lat" />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
Longitude:
|
||||||
|
<input type="text" name="lon" />
|
||||||
|
</label>
|
||||||
|
<button type="submit">Submit coords</button>
|
||||||
|
</form>
|
||||||
|
<button id="reset_adid_btn" onclick="reset_adid_handler(event)">Reset ADID</button>
|
||||||
|
<table>
|
||||||
|
<thead></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>ADID:</td>
|
||||||
|
<td id="adid_priv_info_table">UNKNOWN</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Longitude:</td>
|
||||||
|
<td id="lon_priv_info_table">UNKNOWN</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Latitude:</td>
|
||||||
|
<td id="lat_priv_info_table">UNKNOWN</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
<script src="/socket.io.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
var socket = io();
|
||||||
|
|
||||||
|
function reset_adid_handler(e) {
|
||||||
|
socket.emit("reset_adid");
|
||||||
|
}
|
||||||
|
|
||||||
|
function coords_handler(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const form_data = new FormData(e.target);
|
||||||
|
console.log(form_data);
|
||||||
|
socket.emit("setcoord", {
|
||||||
|
lon: Number.parseFloat(form_data.get("lon")),
|
||||||
|
lat: Number.parseFloat(form_data.get("lat")),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function open_tab(evt, tab_name) {
|
function open_tab(evt, tab_name) {
|
||||||
let i, tabcontent, tablinks;
|
let i, tabcontent, tablinks;
|
||||||
|
|
||||||
@ -199,14 +284,12 @@
|
|||||||
// Get all elements with class="tablinks" and remove the class "active"
|
// Get all elements with class="tablinks" and remove the class "active"
|
||||||
tablinks = document.getElementsByClassName("tablinks");
|
tablinks = document.getElementsByClassName("tablinks");
|
||||||
for (i = 0; i < tablinks.length; i++) {
|
for (i = 0; i < tablinks.length; i++) {
|
||||||
tablinks[i].classList.remove("active")
|
tablinks[i].classList.remove("active");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the current tab, and add an "active" class to the button that opened the tab
|
// Show the current tab, and add an "active" class to the button that opened the tab
|
||||||
evt.currentTarget.classList.add("active");
|
evt.currentTarget.classList.add("active");
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
var screen = document.getElementById("screen");
|
var screen = document.getElementById("screen");
|
||||||
var clicksLog = document.getElementById("clicks-log");
|
var clicksLog = document.getElementById("clicks-log");
|
||||||
const homeButton = document.querySelector(".screen-buttons-home");
|
const homeButton = document.querySelector(".screen-buttons-home");
|
||||||
@ -238,14 +321,7 @@
|
|||||||
const span = document.createElement("span");
|
const span = document.createElement("span");
|
||||||
|
|
||||||
waitToLog(logText);
|
waitToLog(logText);
|
||||||
|
socket.emit(path, body ? body : {});
|
||||||
fetch(path, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
},
|
|
||||||
...(body ? { body } : {}),
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
homeButton.addEventListener("click", () =>
|
homeButton.addEventListener("click", () =>
|
||||||
@ -256,57 +332,118 @@
|
|||||||
registerClick({ path: "back", logText: "await backButton();" })
|
registerClick({ path: "back", logText: "await backButton();" })
|
||||||
);
|
);
|
||||||
|
|
||||||
async function displayImage() {
|
socket.on("screenshot_data", (data) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("screen");
|
const blob = new Blob([data]);
|
||||||
const blob = await response.blob();
|
|
||||||
screen.src = URL.createObjectURL(blob);
|
screen.src = URL.createObjectURL(blob);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching image: ", 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;
|
let isDragging = false;
|
||||||
let startDraggingPosX = 0;
|
|
||||||
let endDraggingPosX = 0;
|
|
||||||
let startDraggingPosY = 0;
|
|
||||||
let endDraggingPosY = 0;
|
|
||||||
|
|
||||||
const screenSize = [320, 640];
|
const screenSize = [320, 640];
|
||||||
|
|
||||||
const handleDraggStart = (e) => {
|
function calcMousePos(event) {
|
||||||
e.preventDefault();
|
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(window.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
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDraggStart = (event) => {
|
||||||
isDragging = true;
|
isDragging = true;
|
||||||
startDraggingPosX = e.offsetX;
|
let pos = calcMousePos(event);
|
||||||
startDraggingPosY = e.offsetY;
|
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);
|
screen.addEventListener("mousedown", handleDraggStart);
|
||||||
|
|
||||||
document.addEventListener("mouseup", (e) => {
|
document.addEventListener("mouseup", (e) => {
|
||||||
endDraggingPosX = e.offsetX;
|
if (!isDragging) return;
|
||||||
endDraggingPosY = e.offsetY;
|
isDragging = false;
|
||||||
if (
|
let pos = calcMousePos(e);
|
||||||
isDragging &&
|
|
||||||
(Math.abs(endDraggingPosY - startDraggingPosY) > 10 ||
|
|
||||||
Math.abs(endDraggingPosX - startDraggingPosX) > 10)
|
|
||||||
) {
|
|
||||||
registerClick({
|
registerClick({
|
||||||
path: "drag",
|
path: "motionevent",
|
||||||
logText: `await drag({x:${startDraggingPosX},y:${startDraggingPosY}},{x:${e.offsetX},y:${e.offsetY}});`,
|
logText: `await motionevent({motionType: "MOVE", x:${pos.x},y:${pos.y}}});`,
|
||||||
body: `startX=${startDraggingPosX}&startY=${startDraggingPosY}&endX=${e.offsetX}&endY=${e.offsetY}`,
|
body: {
|
||||||
|
motionType: "MOVE",
|
||||||
|
x: pos.x,
|
||||||
|
y: pos.y,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} else if (e.target === screen) {
|
|
||||||
const phoneX = event.offsetX;
|
|
||||||
const phoneY = event.offsetY;
|
|
||||||
if (phoneX <= screenSize[0] && phoneY <= screenSize[1])
|
|
||||||
registerClick({
|
registerClick({
|
||||||
path: "touch",
|
path: "motionevent",
|
||||||
logText: `await click(${phoneX}, ${phoneY});`,
|
logText: `await motionevent({motionType: "UP", x:${pos.x},y:${pos.y}}});`,
|
||||||
body: `x=${phoneX}&y=${phoneY}`,
|
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 (document.getElementById("screen").matches(":hover")) {
|
||||||
|
registerClick({
|
||||||
|
path: "key",
|
||||||
|
logText: `await key(${event.key});`,
|
||||||
|
body: { key },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
isDragging = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function sleep(time) {
|
async function sleep(time) {
|
||||||
@ -323,7 +460,6 @@
|
|||||||
await sleep(50);
|
await sleep(50);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screenshot_loop();
|
screenshot_loop();
|
||||||
</script>
|
</script>
|
||||||
<script src="/trafficLog.js"></script>
|
<script src="/trafficLog.js"></script>
|
||||||
|
@ -1,27 +1,34 @@
|
|||||||
import express from "express";
|
import express from "express";
|
||||||
import { readFile } from "node:fs/promises";
|
import { readFile } from "node:fs/promises";
|
||||||
import {
|
|
||||||
guardedScreenshot,
|
|
||||||
android_websocket,
|
|
||||||
waitFullBoot,
|
|
||||||
} from "./screenshot.mjs";
|
|
||||||
|
|
||||||
import { execSync } from "node:child_process";
|
import { execSync } from "node:child_process";
|
||||||
|
import { Server } from "socket.io";
|
||||||
|
|
||||||
|
import { io } from "socket.io-client";
|
||||||
|
|
||||||
import fileUpload from "express-fileupload";
|
import fileUpload from "express-fileupload";
|
||||||
|
|
||||||
const device_size_x = 320;
|
|
||||||
const device_size_y = 640;
|
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
|
async function sleep(time) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, time));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Waiting for full boot...");
|
||||||
|
// bidirectional forwarding
|
||||||
|
// Wait untill the connection
|
||||||
|
const back = io("ws://android:3000", {
|
||||||
|
reconnectionAttempts: 1000000,
|
||||||
|
reconnectionDelay: 100,
|
||||||
|
});
|
||||||
|
while (!back.connected) {
|
||||||
|
await sleep(100);
|
||||||
|
}
|
||||||
|
console.log("Boot detected! activating endpoints");
|
||||||
|
|
||||||
app.use(express.urlencoded({ extended: false }));
|
app.use(express.urlencoded({ extended: false }));
|
||||||
|
|
||||||
app.use(express.static("/code/dist"));
|
app.use(express.static("/code/dist"));
|
||||||
|
|
||||||
console.log("Waiting for full boot...");
|
|
||||||
await waitFullBoot();
|
|
||||||
console.log("Boot detected! activating endpoints");
|
|
||||||
|
|
||||||
//GET
|
//GET
|
||||||
app.get("/favicon.ico", function (req, res) {
|
app.get("/favicon.ico", function (req, res) {
|
||||||
res.sendFile("/code/favicon.ico");
|
res.sendFile("/code/favicon.ico");
|
||||||
@ -31,13 +38,8 @@ app.get("/htmx.js", function (req, res) {
|
|||||||
res.sendFile("/code/node_modules/htmx.org/dist/htmx.min.js");
|
res.sendFile("/code/node_modules/htmx.org/dist/htmx.min.js");
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/trafficLog", async function (req, res) {
|
app.get("/socket.io.js", function (_req, res) {
|
||||||
res.sendFile("/log/trafficLog");
|
res.sendFile("/code/node_modules/socket.io/client-dist/socket.io.js");
|
||||||
});
|
|
||||||
|
|
||||||
app.get("/screen", async function (req, res) {
|
|
||||||
await guardedScreenshot();
|
|
||||||
res.sendFile("/code/screenshot.png");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/", async function (req, res) {
|
app.get("/", async function (req, res) {
|
||||||
@ -55,12 +57,6 @@ app.get("/", async function (req, res) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//POST
|
//POST
|
||||||
app.post("/back", function (req, res) {
|
|
||||||
android_websocket.send(`back`);
|
|
||||||
res.sendStatus(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
// default options
|
|
||||||
app.use(fileUpload());
|
app.use(fileUpload());
|
||||||
app.post("/upload_apk", async function (req, res) {
|
app.post("/upload_apk", async function (req, res) {
|
||||||
if (!req.files || Object.keys(req.files).length === 0) {
|
if (!req.files || Object.keys(req.files).length === 0) {
|
||||||
@ -76,48 +72,25 @@ app.post("/upload_apk", async function (req, res) {
|
|||||||
let uploadPath = "/shared_buffer/app" + 0 + ".apk";
|
let uploadPath = "/shared_buffer/app" + 0 + ".apk";
|
||||||
await req.files.app.mv(uploadPath);
|
await req.files.app.mv(uploadPath);
|
||||||
}
|
}
|
||||||
android_websocket.send(`install`);
|
back.emit("install");
|
||||||
res.send("Files uploaded!");
|
res.send("Files uploaded!");
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/home", function (req, res) {
|
let server = app.listen(8080, () => console.log("Listening in port 8080"));
|
||||||
android_websocket.send(`home`);
|
|
||||||
res.sendStatus(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.post("/touch", function (req, res) {
|
const front = new Server(server);
|
||||||
const x = parseInt(req.body.x);
|
|
||||||
const y = parseInt(req.body.y);
|
|
||||||
|
|
||||||
if (isNaN(x) || isNaN(y) || x > device_size_x || y > device_size_y) {
|
// forwarding the messages
|
||||||
res.send(
|
front.on("connection", (socket) => {
|
||||||
`the query params must be x <= ${device_size_x}, y <= ${device_size_y}\n`
|
socket.onAny((event, ...args) => {
|
||||||
);
|
if (back.connected) {
|
||||||
|
back.emit(event, ...args);
|
||||||
} else {
|
} else {
|
||||||
android_websocket.send(`touch ${x} ${y}`);
|
console.log("Front tried to send: ", event, ...args);
|
||||||
res.sendStatus(200);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/drag", function (req, res) {
|
back.onAny((event, ...args) => {
|
||||||
const body = req.body;
|
front.emit(event, ...args);
|
||||||
const startX = Number(body.startX);
|
|
||||||
const startY = Number(body.startY);
|
|
||||||
const endX = Number(body.endX);
|
|
||||||
const endY = Number(body.endY);
|
|
||||||
android_websocket.send(`drag ${startX} ${startY} ${endX} ${endY}`);
|
|
||||||
res.sendStatus(200);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/setcoord", function (req, res) {
|
|
||||||
console.log(req.body);
|
|
||||||
console.log(req.body.lat);
|
|
||||||
console.log(req.body.lon);
|
|
||||||
const lat = Number(req.body.lat);
|
|
||||||
const lon = Number(req.body.lon);
|
|
||||||
console.log(lat, lon);
|
|
||||||
android_websocket.send(`setcoord ${lat} ${lon}`);
|
|
||||||
res.sendStatus(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
app.listen(8080, () => console.log("Listening in port 8080"));
|
|
||||||
|
379
http_server/code/package-lock.json
generated
379
http_server/code/package-lock.json
generated
@ -9,6 +9,8 @@
|
|||||||
"express-fileupload": "^1.5.1",
|
"express-fileupload": "^1.5.1",
|
||||||
"htmx.org": "^1.9.12",
|
"htmx.org": "^1.9.12",
|
||||||
"preact": "^10.18.1",
|
"preact": "^10.18.1",
|
||||||
|
"socket.io": "^4.8.1",
|
||||||
|
"socket.io-client": "^4.8.1",
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -367,6 +369,30 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@socket.io/component-emitter": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/cors": {
|
||||||
|
"version": "2.8.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.18.tgz",
|
||||||
|
"integrity": "sha512-nX3d0sxJW41CqQvfOzVG1NCTXfFDrDWIghCZncpHeWlVFd81zxB/DLhg7avFg6eHLCRX7ckBmoIIcqa++upvJA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "22.15.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz",
|
||||||
|
"integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
@ -384,6 +410,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/base64id": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^4.5.0 || >= 5.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/body-parser": {
|
"node_modules/body-parser": {
|
||||||
"version": "1.20.1",
|
"version": "1.20.1",
|
||||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
|
||||||
@ -470,6 +505,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "2.6.9",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
@ -508,6 +556,145 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/engine.io": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cors": "^2.8.12",
|
||||||
|
"@types/node": ">=10.0.0",
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "2.0.0",
|
||||||
|
"cookie": "~0.7.2",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~5.2.1",
|
||||||
|
"ws": "~8.17.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-client": {
|
||||||
|
"version": "6.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz",
|
||||||
|
"integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~5.2.1",
|
||||||
|
"ws": "~8.17.1",
|
||||||
|
"xmlhttprequest-ssl": "~2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-client/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-client/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-client/node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-parser": {
|
||||||
|
"version": "5.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||||
|
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io/node_modules/cookie": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/engine.io/node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/esbuild": {
|
"node_modules/esbuild": {
|
||||||
"version": "0.19.5",
|
"version": "0.19.5",
|
||||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
|
||||||
@ -805,6 +992,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.12.3",
|
"version": "1.12.3",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||||
@ -978,6 +1174,175 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/socket.io": {
|
||||||
|
"version": "4.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
|
||||||
|
"integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "~2.0.0",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.3.2",
|
||||||
|
"engine.io": "~6.6.0",
|
||||||
|
"socket.io-adapter": "~2.5.2",
|
||||||
|
"socket.io-parser": "~4.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-adapter": {
|
||||||
|
"version": "2.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
|
||||||
|
"integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "~4.3.4",
|
||||||
|
"ws": "~8.17.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-adapter/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-adapter/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-adapter/node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-client": {
|
||||||
|
"version": "4.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
|
||||||
|
"integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.2",
|
||||||
|
"engine.io-client": "~6.6.1",
|
||||||
|
"socket.io-parser": "~4.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-client/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-client/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/socket.io/node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io/node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/statuses": {
|
"node_modules/statuses": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||||
@ -1014,6 +1379,12 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/unpipe": {
|
"node_modules/unpipe": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
@ -1057,6 +1428,14 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xmlhttprequest-ssl": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
"express-fileupload": "^1.5.1",
|
"express-fileupload": "^1.5.1",
|
||||||
"htmx.org": "^1.9.12",
|
"htmx.org": "^1.9.12",
|
||||||
"preact": "^10.18.1",
|
"preact": "^10.18.1",
|
||||||
|
"socket.io": "^4.8.1",
|
||||||
|
"socket.io-client": "^4.8.1",
|
||||||
"ws": "^8.18.0"
|
"ws": "^8.18.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { render, Component } from "preact";
|
import { render, Component } from "preact";
|
||||||
|
import { io } from "socket.io-client";
|
||||||
|
|
||||||
function rand_num() {
|
function rand_num() {
|
||||||
return Math.floor(Math.random() * Number.MAX_VALUE);
|
return Math.floor(Math.random() * Number.MAX_VALUE);
|
||||||
@ -19,13 +20,12 @@ class Notifications extends Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// This should also be dynamic
|
// This should also be dynamic
|
||||||
this.connection = new WebSocket("ws://127.0.0.1:3001");
|
|
||||||
|
|
||||||
this.connection.onmessage = (msg) => {
|
io().on("notification", (data) => {
|
||||||
let new_id = rand_num();
|
let new_id = rand_num();
|
||||||
this.setState({
|
this.setState({
|
||||||
notifications: [
|
notifications: [
|
||||||
{ id: new_id, notification: JSON.parse(msg.data) },
|
{ id: new_id, notification: data },
|
||||||
...this.state.notifications,
|
...this.state.notifications,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -33,7 +33,7 @@ class Notifications extends Component {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.remove_notification(new_id);
|
this.remove_notification(new_id);
|
||||||
}, 10000);
|
}, 10000);
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
import { exit } from "process";
|
|
||||||
import { WebSocket } from "ws";
|
|
||||||
|
|
||||||
async function sleep(time) {
|
|
||||||
return new Promise((resolve) => setTimeout(resolve, time));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
let socket = new WebSocket("ws://android:3000");
|
|
||||||
|
|
||||||
socket.on("open", () => {
|
|
||||||
exit(0);
|
|
||||||
});
|
|
||||||
socket.on("error", () => {});
|
|
||||||
await sleep(200);
|
|
||||||
}
|
|
120
package-lock.json
generated
120
package-lock.json
generated
@ -6,6 +6,9 @@
|
|||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zx": "^7.2.2"
|
"zx": "^7.2.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"socket.io-client": "^4.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
"node_modules/@nodelib/fs.scandir": {
|
||||||
@ -43,6 +46,13 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@socket.io/component-emitter": {
|
||||||
|
"version": "3.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
|
||||||
|
"integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/fs-extra": {
|
"node_modules/@types/fs-extra": {
|
||||||
"version": "11.0.4",
|
"version": "11.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
|
||||||
@ -122,6 +132,24 @@
|
|||||||
"node": ">= 12"
|
"node": ">= 12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
|
||||||
|
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@ -140,6 +168,30 @@
|
|||||||
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
|
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/engine.io-client": {
|
||||||
|
"version": "6.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz",
|
||||||
|
"integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1",
|
||||||
|
"engine.io-parser": "~5.2.1",
|
||||||
|
"ws": "~8.17.1",
|
||||||
|
"xmlhttprequest-ssl": "~2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/engine.io-parser": {
|
||||||
|
"version": "5.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz",
|
||||||
|
"integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/event-stream": {
|
"node_modules/event-stream": {
|
||||||
"version": "3.3.4",
|
"version": "3.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
|
||||||
@ -386,6 +438,13 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/node-domexception": {
|
"node_modules/node-domexception": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||||
@ -536,6 +595,36 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/socket.io-client": {
|
||||||
|
"version": "4.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz",
|
||||||
|
"integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.2",
|
||||||
|
"engine.io-client": "~6.6.1",
|
||||||
|
"socket.io-parser": "~4.2.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/socket.io-parser": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@socket.io/component-emitter": "~3.1.0",
|
||||||
|
"debug": "~4.3.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/split": {
|
"node_modules/split": {
|
||||||
"version": "0.3.3",
|
"version": "0.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
|
||||||
@ -623,6 +712,37 @@
|
|||||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.17.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xmlhttprequest-ssl": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/yaml": {
|
"node_modules/yaml": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
"start": "zx start.mjs up",
|
"start": "zx start.mjs up",
|
||||||
"stop": "zx start.mjs down"
|
"stop": "zx start.mjs down"
|
||||||
},
|
},
|
||||||
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"zx": "^7.2.2"
|
"zx": "^7.2.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"socket.io-client": "^4.8.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ FROM runmymind/docker-android-sdk:ubuntu-standalone-20230511
|
|||||||
|
|
||||||
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/android-sdk-linux/cmdline-tools/latest/bin:/opt/android-sdk-linux/cmdline-tools/tools/bin:/opt/android-sdk-linux/tools/bin:/opt/android-sdk-linux/build-tools/32.0.0:/opt/android-sdk-linux/platform-tools:/opt/android-sdk-linux/emulator:/opt/android-sdk-linux/bin
|
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/android-sdk-linux/cmdline-tools/latest/bin:/opt/android-sdk-linux/cmdline-tools/tools/bin:/opt/android-sdk-linux/tools/bin:/opt/android-sdk-linux/build-tools/32.0.0:/opt/android-sdk-linux/platform-tools:/opt/android-sdk-linux/emulator:/opt/android-sdk-linux/bin
|
||||||
|
|
||||||
RUN sdkmanager --channel=2 "system-images;android-30;google_apis;x86_64" \
|
RUN sdkmanager --channel=2 "system-images;android-35;google_apis;x86_64" \
|
||||||
&& echo no | avdmanager create avd -n virtual_dev -b google_apis/x86_64 -k "system-images;android-30;google_apis;x86_64" \
|
&& echo no | avdmanager create avd -n virtual_dev -b google_apis/x86_64 -k "system-images;android-35;google_apis;x86_64" \
|
||||||
&& apt-get update && apt-get install -y iproute2 iputils-ping npm git libxml2-utils telnet
|
&& apt-get update && apt-get install -y iproute2 iputils-ping npm git libxml2-utils telnet
|
||||||
|
|
||||||
CMD bash /preconf/docker-entrypoint.sh
|
CMD bash /preconf/docker-entrypoint.sh
|
||||||
|
Loading…
x
Reference in New Issue
Block a user