add support for other sites & add afk
This commit is contained in:
parent
70f23d750b
commit
6893d27560
4 changed files with 131 additions and 30 deletions
|
@ -1,10 +1,11 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name MultiProbe
|
// @name MultiProbe
|
||||||
// @namespace https://*.angusnicneven.com/*
|
// @namespace https://*.angusnicneven.com/*
|
||||||
// @version 20240508.1
|
// @version 20240527.1
|
||||||
// @description Probe with friends!
|
// @description Probe with friends!
|
||||||
// @author tgpholly
|
// @author tgpholly
|
||||||
// @match https://*.angusnicneven.com/*
|
// @match https://*.angusnicneven.com/*
|
||||||
|
// @match https://*.heavenonline.xyz/*
|
||||||
// @icon https://www.google.com/s2/favicons?sz=64&domain=angusnicneven.com
|
// @icon https://www.google.com/s2/favicons?sz=64&domain=angusnicneven.com
|
||||||
// @grant none
|
// @grant none
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
@ -35,6 +36,12 @@ if (!window.TE_ACTIVE) {
|
||||||
const windowLocation = window.location.href;
|
const windowLocation = window.location.href;
|
||||||
window.multiprobe_debug = false;
|
window.multiprobe_debug = false;
|
||||||
|
|
||||||
|
const SITE_DEFAULT_CURSOR = {
|
||||||
|
"localhost": "https://angusnicneven.com/cursor/rrw.png",
|
||||||
|
"angusnicneven.com": "https://angusnicneven.com/cursor/rrw.png",
|
||||||
|
"heavenonline.xyz": "https://heavenonline.xyz/core/cursor/frame1.png"
|
||||||
|
};
|
||||||
|
|
||||||
console.log("[MP] MultiProbe init");
|
console.log("[MP] MultiProbe init");
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
@ -59,15 +66,17 @@ console.log("[MP] MultiProbe init");
|
||||||
Clients: 4,
|
Clients: 4,
|
||||||
ClientLeft: 5,
|
ClientLeft: 5,
|
||||||
Ping: 6,
|
Ping: 6,
|
||||||
GroupData: 7
|
GroupData: 7,
|
||||||
|
HonkShoe: 8
|
||||||
};
|
};
|
||||||
|
|
||||||
let cursorImageI = window.getComputedStyle(document.body).cursor;
|
let cursorImageI = window.getComputedStyle(document.body).cursor;
|
||||||
|
const cssCursor = `${cursorImageI === "auto" || !cursorImageI.includes("url") ? `url(${SITE_DEFAULT_CURSOR[window.location.href.split("//")[1].split("/")[0].split(":")[0]]}) 11 11, auto` : cursorImageI}`;
|
||||||
console.log("[MP] Injecting custom styles...");
|
console.log("[MP] Injecting custom styles...");
|
||||||
const styles = document.createElement("style");
|
const styles = document.createElement("style");
|
||||||
styles.innerHTML = `
|
styles.innerHTML = `
|
||||||
html {
|
html {
|
||||||
cursor: ${cursorImageI};
|
cursor: ${cssCursor};
|
||||||
}
|
}
|
||||||
|
|
||||||
#otherCursors {
|
#otherCursors {
|
||||||
|
@ -111,6 +120,18 @@ html {
|
||||||
z-index: -1!important;
|
z-index: -1!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.eepy {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
image-rendering: pixelated;
|
||||||
|
background: url("data:image/webp;base64,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");
|
||||||
|
z-index: 1;
|
||||||
|
transform: translate(60px, -60px);
|
||||||
|
}
|
||||||
|
|
||||||
.grouphidden {
|
.grouphidden {
|
||||||
right: -12rem!important;
|
right: -12rem!important;
|
||||||
}
|
}
|
||||||
|
@ -284,9 +305,9 @@ kbd {
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (document.body.scrollHeight > window.innerHeight) {
|
if (document.body.scrollHeight > window.innerHeight) {
|
||||||
otherCursors.style = `width:${clientWidth = (document.body.getBoundingClientRect().width + bodyMarginRight + bodyMarginLeft)}px;height:${document.body.scrollHeight}px;top:-${((window.scrollY + document.body.getBoundingClientRect().top) - bodyMarginTop)}px;cursor: ${cursorImageI};`;
|
otherCursors.style = `width:${clientWidth = (document.body.getBoundingClientRect().width + bodyMarginRight + bodyMarginLeft)}px;height:${document.body.scrollHeight}px;top:-${((window.scrollY + document.body.getBoundingClientRect().top) - bodyMarginTop)}px;cursor: ${cssCursor};`;
|
||||||
} else {
|
} else {
|
||||||
otherCursors.style = `width:${clientWidth = (document.body.getBoundingClientRect().width + bodyMarginRight + bodyMarginLeft)}px;height:${window.innerHeight}px;top:-${((window.scrollY + document.body.getBoundingClientRect().top) - bodyMarginTop)}px;cursor: ${cursorImageI};`;
|
otherCursors.style = `width:${clientWidth = (document.body.getBoundingClientRect().width + bodyMarginRight + bodyMarginLeft)}px;height:${window.innerHeight}px;top:-${((window.scrollY + document.body.getBoundingClientRect().top) - bodyMarginTop)}px;cursor: ${cssCursor};`;
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
@ -307,7 +328,7 @@ kbd {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const keepAlivePacket = createWriter(Endian.LE, 1).writeByte(MessageType.KeepAlive).toBuffer();
|
const keepAlivePacket = createWriter(Endian.LE, 1).writeUByte(MessageType.KeepAlive).toBuffer();
|
||||||
|
|
||||||
let remoteClients = new FunkyArray();
|
let remoteClients = new FunkyArray();
|
||||||
|
|
||||||
|
@ -320,7 +341,7 @@ kbd {
|
||||||
let lastSendTime = 0;
|
let lastSendTime = 0;
|
||||||
|
|
||||||
class RemoteClient {
|
class RemoteClient {
|
||||||
constructor(name) {
|
constructor(name, startAfk, isSelfCursor = false) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.element = document.createElement("div");
|
this.element = document.createElement("div");
|
||||||
this.element.style.position = "absolute";
|
this.element.style.position = "absolute";
|
||||||
|
@ -337,6 +358,12 @@ kbd {
|
||||||
clientName.style = "position:absolute;left:100%;top:100%;background-color:black;padding:4px 8px;color:white;font-size:12px;font-family:Arial,sans-serif;";
|
clientName.style = "position:absolute;left:100%;top:100%;background-color:black;padding:4px 8px;color:white;font-size:12px;font-family:Arial,sans-serif;";
|
||||||
clientName.innerText = name;
|
clientName.innerText = name;
|
||||||
this.element.appendChild(clientName);
|
this.element.appendChild(clientName);
|
||||||
|
if (!isSelfCursor) {
|
||||||
|
this.eepy = document.createElement("div");
|
||||||
|
this.eepy.className = "eepy";
|
||||||
|
this.eepy.style = startAfk ? "" : "display:none";
|
||||||
|
this.element.appendChild(this.eepy);
|
||||||
|
}
|
||||||
otherCursors.appendChild(this.element);
|
otherCursors.appendChild(this.element);
|
||||||
this.targetX = 0;
|
this.targetX = 0;
|
||||||
this.targetY = 0;
|
this.targetY = 0;
|
||||||
|
@ -348,6 +375,10 @@ kbd {
|
||||||
this.element.visibility = "hidden";
|
this.element.visibility = "hidden";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAfk(afkState) {
|
||||||
|
this.eepy.style = afkState ? "" : "display:none";
|
||||||
|
}
|
||||||
|
|
||||||
rawSetPos(x, y) {
|
rawSetPos(x, y) {
|
||||||
if (!this.hasBeenMoved) {
|
if (!this.hasBeenMoved) {
|
||||||
this.element.visibility = "";
|
this.element.visibility = "";
|
||||||
|
@ -401,6 +432,17 @@ kbd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isAfkLocal = false;
|
||||||
|
let lastSendAfkState = false
|
||||||
|
|
||||||
|
window.onfocus = (e) => {
|
||||||
|
isAfkLocal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onblur = (e) => {
|
||||||
|
isAfkLocal = true;
|
||||||
|
}
|
||||||
|
|
||||||
let rawMouseX = 0;
|
let rawMouseX = 0;
|
||||||
let rawMouseY = 0;
|
let rawMouseY = 0;
|
||||||
|
|
||||||
|
@ -422,10 +464,10 @@ kbd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function log(type, text) {
|
function log(type, text) {
|
||||||
const d = new Date();
|
const d = new Date();
|
||||||
console.log(`[hNET] [${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}:${String(d.getSeconds()).padStart(2, "0")}.${String(d.getMilliseconds()).padStart(4, "0")}] [${type}] ${text}`);
|
console.log(`[hNET] [${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}:${String(d.getSeconds()).padStart(2, "0")}.${String(d.getMilliseconds()).padStart(4, "0")}] [${type}] ${text}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowedPings = 10;
|
let allowedPings = 10;
|
||||||
window.onkeypress = (e) => {
|
window.onkeypress = (e) => {
|
||||||
|
@ -433,7 +475,7 @@ kbd {
|
||||||
if (ws && ready) {
|
if (ws && ready) {
|
||||||
if (allowedPings > 0) {
|
if (allowedPings > 0) {
|
||||||
allowedPings--;
|
allowedPings--;
|
||||||
ws.send(createWriter(Endian.LE, 9).writeByte(MessageType.Ping).writeFloat((rawMouseX + window.scrollX - 32) / clientWidth).writeInt(rawMouseY + window.scrollY - 32).toBuffer());
|
ws.send(createWriter(Endian.LE, 9).writeUByte(MessageType.Ping).writeFloat((rawMouseX + window.scrollX - 32) / clientWidth).writeInt(rawMouseY + window.scrollY - 32).toBuffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (e.key === "n") {
|
} else if (e.key === "n") {
|
||||||
|
@ -471,9 +513,13 @@ kbd {
|
||||||
lastSendTime = performance.now();
|
lastSendTime = performance.now();
|
||||||
oldMouseX = currentMouseX;
|
oldMouseX = currentMouseX;
|
||||||
oldMouseY = currentMouseY;
|
oldMouseY = currentMouseY;
|
||||||
ws.send(createWriter(Endian.LE, 9).writeByte(MessageType.CursorPos).writeFloat(oldMouseX / clientWidth).writeInt(currentMouseY).toBuffer());
|
ws.send(createWriter(Endian.LE, 9).writeUByte(MessageType.CursorPos).writeFloat(oldMouseX / clientWidth).writeInt(currentMouseY).toBuffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isAfkLocal !== lastSendAfkState) {
|
||||||
|
lastSendAfkState = isAfkLocal;
|
||||||
|
ws.send(createWriter(Endian.LE, 2).writeUByte(MessageType.HonkShoe).writeBool(isAfkLocal).toBuffer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((performance.now() - timeSinceLastPingReset) >= 1000) {
|
if ((performance.now() - timeSinceLastPingReset) >= 1000) {
|
||||||
|
@ -506,13 +552,13 @@ kbd {
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
console.log("[MP] Connected! Authenticating...");
|
console.log("[MP] Connected! Authenticating...");
|
||||||
otherCursors.innerHTML = "";
|
otherCursors.innerHTML = "";
|
||||||
selfCursor = new RemoteClient(localStorage["t00mp_username"]);
|
selfCursor = new RemoteClient(localStorage["t00mp_username"], false, true);
|
||||||
selfCursor.probeImage.style.visibility = "hidden";
|
selfCursor.probeImage.style.visibility = "hidden";
|
||||||
selfCursor.element.style.visibility = localStorage["t00mp_cursorStyle"] ?? "hidden";
|
selfCursor.element.style.visibility = localStorage["t00mp_cursorStyle"] ?? "hidden";
|
||||||
selfCursor.hasBeenMoved = true;
|
selfCursor.hasBeenMoved = true;
|
||||||
const currentPage = windowLocation.split("/").slice(3).join("/");
|
const currentPage = windowLocation.split("/").slice(2).join("/");
|
||||||
ws.send(createWriter(Endian.LE, 4 + apiKey.length + currentPage.length)
|
ws.send(createWriter(Endian.LE, 4 + apiKey.length + currentPage.length)
|
||||||
.writeByte(MessageType.ClientDetails)
|
.writeUByte(MessageType.ClientDetails)
|
||||||
.writeShortString(apiKey)
|
.writeShortString(apiKey)
|
||||||
.writeString(currentPage)
|
.writeString(currentPage)
|
||||||
.toBuffer());
|
.toBuffer());
|
||||||
|
@ -532,7 +578,8 @@ kbd {
|
||||||
const clientName = reader.readShortString();
|
const clientName = reader.readShortString();
|
||||||
const clientX = reader.readFloat();
|
const clientX = reader.readFloat();
|
||||||
const clientY = reader.readInt();
|
const clientY = reader.readInt();
|
||||||
remoteClients.set(clientId, new RemoteClient(clientName)).rawSetPosInit(clientX, clientY);
|
const isAfk = reader.readBool();
|
||||||
|
remoteClients.set(clientId, new RemoteClient(clientName, isAfk)).rawSetPosInit(clientX, clientY);
|
||||||
}
|
}
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `Initial client packet, got ${clientCount} clients.`);
|
log("RECV", `Initial client packet, got ${clientCount} clients.`);
|
||||||
|
@ -552,9 +599,9 @@ kbd {
|
||||||
{
|
{
|
||||||
const clientId = reader.readUInt();
|
const clientId = reader.readUInt();
|
||||||
const clientName = reader.readShortString();
|
const clientName = reader.readShortString();
|
||||||
remoteClients.set(clientId, new RemoteClient(clientName));
|
remoteClients.set(clientId, new RemoteClient(clientName, false));
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `New client joined page: ${clientName} ID=${clientId}`);
|
log("RECV", `New client joined page: ${clientName} ID=${clientId}`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -566,7 +613,7 @@ kbd {
|
||||||
const cursorY = reader.readInt();
|
const cursorY = reader.readInt();
|
||||||
remoteClients.get(clientId).rawSetPos(cursorX, cursorY);
|
remoteClients.get(clientId).rawSetPos(cursorX, cursorY);
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `Cursor position update for ${clientId}, X=${cursorX}, Y=${cursorY}`);
|
log("RECV", `Cursor position update for ${clientId}, X=${cursorX}, Y=${cursorY}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -576,7 +623,7 @@ kbd {
|
||||||
const clientId = reader.readUInt();
|
const clientId = reader.readUInt();
|
||||||
removeClient(clientId);
|
removeClient(clientId);
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `Client ${clientId} left or switched pages`);
|
log("RECV", `Client ${clientId} left or switched pages`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -586,7 +633,7 @@ kbd {
|
||||||
const cursorY = reader.readInt();
|
const cursorY = reader.readInt();
|
||||||
createPing(cursorX * clientWidth, cursorY);
|
createPing(cursorX * clientWidth, cursorY);
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `Got a ping, X=${cursorX}, Y=${cursorY}`);
|
log("RECV", `Got a ping, X=${cursorX}, Y=${cursorY}`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -595,20 +642,38 @@ kbd {
|
||||||
groupUIBase.style = "";
|
groupUIBase.style = "";
|
||||||
groupUsers.innerHTML = "";
|
groupUsers.innerHTML = "";
|
||||||
groupTitle.innerText = reader.readShortString();
|
groupTitle.innerText = reader.readShortString();
|
||||||
const groupUserCount = reader.readUShort();
|
const groupUserCount = reader.readUShort();
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `Server sent group information for "${groupTitle.innerText}" (${groupUserCount} clients)`);
|
log("RECV", `Server sent group information for "${groupTitle.innerText}" (${groupUserCount} clients)`);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < groupUserCount; i++) {
|
for (let i = 0; i < groupUserCount; i++) {
|
||||||
const groupUsername = reader.readShortString();
|
const groupUsername = reader.readShortString();
|
||||||
const groupUserLocation = reader.readString();
|
const groupUserLocation = reader.readString();
|
||||||
if (window.multiprobe_debug) {
|
if (window.multiprobe_debug) {
|
||||||
log("RECV", `[GROUP USER] USERNAME=${groupUsername}, LOCATION=${groupUserLocation}`);
|
log("RECV", `[GROUP USER] USERNAME=${groupUsername}, LOCATION=${groupUserLocation}`);
|
||||||
}
|
}
|
||||||
createGroupUser(groupUsername, groupUserLocation);
|
createGroupUser(groupUsername, groupUserLocation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageType.HonkShoe:
|
||||||
|
{
|
||||||
|
const clientId = reader.readUInt();
|
||||||
|
const isAfk = reader.readBool();
|
||||||
|
|
||||||
|
if (remoteClients.has(clientId)) {
|
||||||
|
remoteClients.get(clientId).setAfk(isAfk);
|
||||||
|
if (window.multiprobe_debug) {
|
||||||
|
if (isAfk) {
|
||||||
|
log("RECV", `Client ${clientId} went afk`);
|
||||||
|
} else {
|
||||||
|
log("RECV", `Client ${clientId} is no longer afk`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,5 +6,6 @@ export enum MessageType {
|
||||||
Clients,
|
Clients,
|
||||||
ClientLeft,
|
ClientLeft,
|
||||||
Ping,
|
Ping,
|
||||||
GroupData
|
GroupData,
|
||||||
|
HonkShoe
|
||||||
}
|
}
|
|
@ -94,7 +94,7 @@ fastify.get("/", async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.get("/account", async (req, res) => {
|
fastify.get("/account", async (req, res) => {
|
||||||
return "TODO";
|
return res.redirect(302, "/");
|
||||||
});
|
});
|
||||||
|
|
||||||
fastify.get("/account/login", async (req, res) => {
|
fastify.get("/account/login", async (req, res) => {
|
||||||
|
@ -359,6 +359,16 @@ function sendToAllInGroup(user:RemoteUser, data:Buffer) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const afkInterval = setInterval(() => {
|
||||||
|
users.forEach(otherUser => {
|
||||||
|
if (Date.now() - otherUser.timeLastMovedCursor >= 30000 && !otherUser.isAfk) {
|
||||||
|
otherUser.isAfk = true;
|
||||||
|
const afkPacket = createWriter(Endian.LE, 6).writeByte(MessageType.HonkShoe).writeUInt(otherUser.id).writeBool(otherUser.isAfk).toBuffer();
|
||||||
|
sendToAllButSelf(otherUser, afkPacket);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
websocketServer.on("connection", (socket) => {
|
websocketServer.on("connection", (socket) => {
|
||||||
const myUUID = crypto.randomUUID();
|
const myUUID = crypto.randomUUID();
|
||||||
let user:RemoteUser;
|
let user:RemoteUser;
|
||||||
|
@ -412,7 +422,7 @@ websocketServer.on("connection", (socket) => {
|
||||||
socket.on("message", async (data) => {
|
socket.on("message", async (data) => {
|
||||||
const reader = createReader(Endian.LE, data as Buffer);
|
const reader = createReader(Endian.LE, data as Buffer);
|
||||||
if (reader.length > 0 && reader.length < 1024) {
|
if (reader.length > 0 && reader.length < 1024) {
|
||||||
switch (reader.readByte()) {
|
switch (reader.readUByte()) {
|
||||||
case MessageType.KeepAlive:
|
case MessageType.KeepAlive:
|
||||||
{
|
{
|
||||||
user.lastKeepAliveTime = Date.now();
|
user.lastKeepAliveTime = Date.now();
|
||||||
|
@ -447,9 +457,9 @@ websocketServer.on("connection", (socket) => {
|
||||||
lengthOfUsernames += otherUser.username.length + 1; // + 1 for length byte
|
lengthOfUsernames += otherUser.username.length + 1; // + 1 for length byte
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const usersToSend = createWriter(Endian.LE, 3 + (usersOnPage.length * 12) + lengthOfUsernames).writeByte(MessageType.Clients).writeUShort(usersOnPage.length);
|
const usersToSend = createWriter(Endian.LE, 3 + (usersOnPage.length * 13) + lengthOfUsernames).writeByte(MessageType.Clients).writeUShort(usersOnPage.length);
|
||||||
for (const otherUser of usersOnPage) {
|
for (const otherUser of usersOnPage) {
|
||||||
usersToSend.writeUInt(otherUser.id).writeShortString(otherUser.username).writeFloat(otherUser.cursorX).writeInt(otherUser.cursorY);
|
usersToSend.writeUInt(otherUser.id).writeShortString(otherUser.username).writeFloat(otherUser.cursorX).writeInt(otherUser.cursorY).writeBool(otherUser.isAfk);
|
||||||
}
|
}
|
||||||
if (dbParty) {
|
if (dbParty) {
|
||||||
user = users.set(myUUID, new RemoteUser(socket, myUUID, dbUser.Username, page, rawURL, dbUser.Id, dbParty.Id, dbParty.Name));
|
user = users.set(myUUID, new RemoteUser(socket, myUUID, dbUser.Username, page, rawURL, dbUser.Id, dbParty.Id, dbParty.Name));
|
||||||
|
@ -469,6 +479,13 @@ websocketServer.on("connection", (socket) => {
|
||||||
user.cursorX = reader.readFloat();
|
user.cursorX = reader.readFloat();
|
||||||
user.cursorY = reader.readInt();
|
user.cursorY = reader.readInt();
|
||||||
sendToAllButSelf(user, createWriter(Endian.LE, 13).writeByte(MessageType.CursorPos).writeUInt(user.id).writeFloat(user.cursorX).writeInt(user.cursorY).toBuffer());
|
sendToAllButSelf(user, createWriter(Endian.LE, 13).writeByte(MessageType.CursorPos).writeUInt(user.id).writeFloat(user.cursorX).writeInt(user.cursorY).toBuffer());
|
||||||
|
|
||||||
|
user.timeLastMovedCursor = Date.now();
|
||||||
|
if (user.isAfk) {
|
||||||
|
user.isAfk = false;
|
||||||
|
const afkPacket = createWriter(Endian.LE, 6).writeByte(MessageType.HonkShoe).writeUInt(user.id).writeBool(user.isAfk).toBuffer();
|
||||||
|
sendToAllButSelf(user, afkPacket);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MessageType.Ping:
|
case MessageType.Ping:
|
||||||
|
@ -491,6 +508,19 @@ websocketServer.on("connection", (socket) => {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageType.HonkShoe:
|
||||||
|
{
|
||||||
|
if (user === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.isAfk = reader.readBool();
|
||||||
|
|
||||||
|
const afkPacket = createWriter(Endian.LE, 6).writeByte(MessageType.HonkShoe).writeUInt(user.id).writeBool(user.isAfk).toBuffer();
|
||||||
|
sendToAllButSelf(user, afkPacket);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -507,6 +537,7 @@ function shutdown() {
|
||||||
websocketServer.close(async () => {
|
websocketServer.close(async () => {
|
||||||
await fastify.close();
|
await fastify.close();
|
||||||
clearInterval(sessionExpiryInterval);
|
clearInterval(sessionExpiryInterval);
|
||||||
|
clearInterval(afkInterval);
|
||||||
|
|
||||||
Console.cleanup();
|
Console.cleanup();
|
||||||
console.log("Goodbye!");
|
console.log("Goodbye!");
|
||||||
|
|
|
@ -17,6 +17,8 @@ export default class RemoteUser {
|
||||||
public groupId:number = Number.MIN_VALUE;
|
public groupId:number = Number.MIN_VALUE;
|
||||||
public groupName:string;
|
public groupName:string;
|
||||||
public lastKeepAliveTime:number;
|
public lastKeepAliveTime:number;
|
||||||
|
public isAfk:boolean;
|
||||||
|
public timeLastMovedCursor: number;
|
||||||
|
|
||||||
constructor(socket:WebSocket, connectionUUID:string, username:string, currentURL:string, rawURL:string, userId:number, groupId:number, groupName:string) {
|
constructor(socket:WebSocket, connectionUUID:string, username:string, currentURL:string, rawURL:string, userId:number, groupId:number, groupName:string) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
|
@ -31,6 +33,8 @@ export default class RemoteUser {
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
this.groupName = groupName;
|
this.groupName = groupName;
|
||||||
this.lastKeepAliveTime = Date.now();
|
this.lastKeepAliveTime = Date.now();
|
||||||
|
this.isAfk = false;
|
||||||
|
this.timeLastMovedCursor = Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
send(data:Buffer) {
|
send(data:Buffer) {
|
||||||
|
|
Loading…
Reference in a new issue