implement protocol versioning and add site specific logos

This commit is contained in:
Holly Stubbs 2024-10-13 12:41:45 +01:00
parent ac5e24c5d7
commit 0787dfda47
Signed by: tgpholly
GPG key ID: B8583C4B7D18119E
8 changed files with 76 additions and 14 deletions

View file

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name MultiProbe // @name MultiProbe
// @namespace https://*.angusnicneven.com/* // @namespace https://*.angusnicneven.com/*
// @version 20241013.0 // @version 20241013.1
// @description Probe with friends! // @description Probe with friends!
// @author tgpholly // @author tgpholly
// @match https://*.angusnicneven.com/* // @match https://*.angusnicneven.com/*
@ -49,13 +49,22 @@ const SITE_DEFAULT_HOVER_CURSOR = {
"heavenonline.xyz": "https://heavenonline.xyz/core/cursor_hover/frame1.png" "heavenonline.xyz": "https://heavenonline.xyz/core/cursor_hover/frame1.png"
}; };
const SITE_LOGOS = {
"*.angusnicneven.com": "https://eusv.net/NLuGOZGZtS3BEr",
"multiprobe.eusv.net": "https://eusv.net/NLuGOZGZtS3BEr",
"*.heavenonline.xyz": "https://eusv.net/Iu8kZfgAC8NFdU",
"*.eusv.net": "https://eusv.net/C89X3tb5mtkVI7"
};
const PROTOCOL_VERSION = 2;
console.log("[MP] MultiProbe init"); console.log("[MP] MultiProbe init");
(function() { (function() {
'use strict'; 'use strict';
// Make sure to change the userscript version too!!!!!!!!!! // Make sure to change the userscript version too!!!!!!!!!!
const USERSCRIPT_VERSION_RAW = "20241013.0"; const USERSCRIPT_VERSION_RAW = "20241013.1";
const USERSCRIPT_VERSION = parseInt(USERSCRIPT_VERSION_RAW.replace(".", "")); const USERSCRIPT_VERSION = parseInt(USERSCRIPT_VERSION_RAW.replace(".", ""));
if (!continueRunningScript) { if (!continueRunningScript) {
@ -76,7 +85,8 @@ console.log("[MP] MultiProbe init");
GroupData: 7, GroupData: 7,
HonkShoe: 8, HonkShoe: 8,
BadgeUnlock: 9, BadgeUnlock: 9,
DEBUG_UnlockAllBadges: 10 DEBUG_UnlockAllBadges: 10,
TooOutOfDate: 11
}; };
let cssCursor = ""; let cssCursor = "";
@ -148,7 +158,7 @@ html {
animation: ping 2s linear; animation: ping 2s linear;
animation-iteration-count: 1; animation-iteration-count: 1;
image-rendering: pixelated; image-rendering: pixelated;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAXVJREFUeJztm8ESwyAIRLX//8/2EjKKmhhFUeDN9NbK7kIybaPerSU0vs9PVbGwUGI4hDb/3meypumcsfDtEhsuGCsv8Pw5Us2UiwXnUvEDnaxOTrQmiXaKRRLjk7qVTRVVEKMCA7WglppX4bjusptmLCJc7uF1pIae5HDXl6ePWKqHu+s18DTMKTK7AAHTNJ5gHiDXepJ5gEzzieaBYe0nmwdePfwWijkKCd0HPnuRZB6oerJLACGx+0DRm01AhOTuA5lH9ROgPgBAw/gDiVf1E2ABcAvYAU3XP3B7Vj8BFgC3AG4sAG4B3FgA3AK4sQC4BeyCpm+D9mswxgLgFrATGu4D9qcoRn0AGMmXgT0ZakXiFNjT4a9ImoJuLxJCsD1Co5w8Bar3CqreLap6v/DSHeM7BdG9Xd4OTPQWdfzTwHZkJhGB0qdY87XmVTiu213Tjs2NfBiRBOGcnoOTmKxbdzHhR2dLVDv5xOmHp59ovVMv0/UHCfuPGCq5foYAAAAASUVORK5CYII="); background: url("https://eusv.net/MA7cm1BBelFHDP");
width: 64px; width: 64px;
height: 64px; height: 64px;
z-index: -1!important; z-index: -1!important;
@ -161,7 +171,7 @@ html {
width: 64px; width: 64px;
height: 64px; height: 64px;
image-rendering: pixelated; image-rendering: pixelated;
background: url("data:image/webp;base64,UklGRsQIAABXRUJQVlA4WAoAAAASAAAAPwAAPwAAQU5JTQYAAAD/////AABBTk1GJgAAAAUAABsAAAIAAAIAAGQAAAJWUDhMDQAAAC8CgAAQxfxHzH8gLgIAQU5NRjwAAAAFAAAUAAAHAAAOAABkAAAAVlA4TCQAAAAvB4ADEIWCtm2Y8Cfd/cMgYv6FBIl2hiAnq6TKvTP744jehwVBTk1GUgAAAAUAAA4AABAAABwAAGQAAANWUDhMOgAAAC8QAAcQBdu2jSSx/6b3vdNFF0fM/wTwsclR3zmO42gb1TKOo220jbbRNpqkSJGgvFOeL/L2kKBE+elBTk1GYgAAAAYAAAwAABUAABIAAGQAAABWUDhMSgAAAC8VgAQQhYK2baTwJ73/Wh2CiPlX4LaNMuYd/AI2UuPiqJE0KfLhClA7BDxLN2v4ZjP6TMXkpyipo+elbd4+3/47cEuNf6H37c0AQU5NRmAAAAAGAAALAAAZAAAhAABkAAACVlA4TEgAAAAvGUAIEAXjRpKcVP5J3wFr8PCMmH+EadsGNd2WfUJgwB6Owb4vdYxU3VGoY6DskAvZRXeHV07Qt46ZqmXbKqfF3+aBjLvnwAJBTk1GgAAAAAcAAAkAAB0AACUAAGQAAAJWUDhMaAAAAC8dQAkQBdu2jSSp/6Ynsle794YR86/AbRtljMf3CVyFJM1aCs45ua6diSvutUKz9ZKAjLEu0lS/NNfTp7hgzuC4SxpmRmg479ll2y2b0TO28wz/IZLE7mvcsTS0L09b76HU05Vc+g4BQU5NRpIAAAAGAAAJAAAiAAAnAABkAAADVlA4THkAAAAvIsAJEAXjNpIUVf5JHw3V8TNi/hW4baOoo2Pq7hG4GAyQbcuAmTC1zTX1dVqOJcetBXCoHP0YfV4nwQ2G18zPz7mS9u2b13dqSMo4lpQkxw+CTDzOa2RyI6a/Ey570CvHWn5VgpzFmDk5sxoes00WKrHTNINPfHkAAEFOTUaIAAAADQAACgAAFgAAJQAAZAAAAVZQOExvAAAALxZACRAF47aNHKn/pnVhZj0X3xHzr8BtG2XMh69ARJIcRXwg41y7cMxlbvPqOK65nZBmPHXnCdIRrusp317EgkmTnN5wvdF875Osxy+M/8N4Xzxx8DNpL/9ghKKI7DzwU8w3cMMItn3rRTr74KAWAEFOTUaOAAAABgAACwAAJgAAIgAAZAAAAVZQOEx1AAAALyaACBBVwG0kyZF0/jv9ZNn3Si92JCL6PwH7wo8dd/zKDDofoSOygypYjQh7lJ205xq6fouyL1T2HfaNOsGMcqxM6Jod1NFxJ1XYeey/I1POyy3PdH1LnuiI7G372HH15K+VfaGyL5TTKaHKjC7tqHK+w+xzAEFOTUaYAAAABgAACwAAJQAAIgAAZAAAAFZQOEx/AAAALyWACBBVQG4jyZG0/jutRlbv3r2TiYj+T0B+5QMLeLY1hGIEWqJyv7ZIVHbhWpAt2dW2rh3qEioLqJySu+RQB3QR2RpSgRrTtrInt2pbyEwghxPnF9FWfoj8F+CUXLdtWyO6T07KZS1UhkmywFZlQZVgSKGtEd1FJrW2mSZXAQBBTk1GmAAAAAYAAAoAACgAACQAAGQAAANWUDhMfwAAAC8oAAkQVUBy20iS1P//9CwZNZWZpzmaRkT/JyCXf3CHr7aco7NT+nzCHRKVJDiiEhl1lPc8zLpNK/Gks2wkibpglmv+qC2y2avKZjW5hZpk2xolSRxQbUVmsl2RO+WfmCugdQq6ymFtSyvHra1cqZUrtcZjWro6pDNyzpoLyWsAQU5NRpgAAAAFAAAIAAApAAAoAABkAAABVlA4TIAAAAAvKQAKEAbHjSQpUvvv9PJALtw9s+Z//vuvwI2khIsbDn8QhUKlcDmJKtUuLkCBDY1QoT4fiHkIFr0cHbcUsbuPw7O0QTIrFA3F1iZmwtjdc50IeRwUGDYqgxgZHSRk5B8P1MN6fQQgH4JJcjKIhLVxPoBFVfCXiOB3QnAhm/ZyBUFOTUaCAAAABgAABgAAIwAALAAAZAAAAVZQOExqAAAALyMACxCF40aSFCn8d3rxoPP4XhHzr8BtG0VjOoY/0IDqnJY7HKE5BiEPuAzNm7woJwnJWJlToWuRmFS+hobLZbFpWjmuHIHgACeIyh8KlOR1srmDwbu6DC6pS4vspQlpQctl8B00pNH3BEFOTUZ+AAAABwAABQAAIgAALgAAZAAAAVZQOExmAAAALyKACxAKx40kKdL57zTuQc3xvTpU8z///VeYtg2DuvvJLLJjK8v9W8lBryhIdrplEqAmtCTT7yulx88syLYQNb0QHYDtYTKgJmf+oxjSqdVGoUWU29uoSZkFWSNdi4YnVQuKiV1MQU5NRnAAAAAJAAAFAAAfAAAuAABkAAABVlA4TFcAAAAvH4ALEAXbtpEcsf+m3xvdffRRxPwrcNtGGdMxPAI8I6/R5RlD4GSfAqnbm5RASVXCuezBNerM6Owyc7TB0DNXWqqfup4oBvgX0Rqx/hUOEDm/7PT9QgAAQU5NRmYAAAALAAAEAAASAAASAABkAAABVlA4TE0AAAAvEoAEEFVAaCNJkrT8Se/eV3MQwqmI/k9A//vKI2/DLbMNlwQb/PG7/cQlv24ulY3ORHebHjI9tOmh0ZGYrjbjFpnh8NPYlEOKMoe/VQBBTk1GXAAAAA0AAAUAAA8AABAAAGQAAAFWUDhMQwAAAC8PAAQQCgdtI0nS8Sf9X2OIVfM///2fgKoHuns+cYhs8uebGYeSzSWjI9PV6Mh0tek/ov+26Yxy+TZyyWYcIpvDNwUAQU5NRlAAAAAPAAAFAAAMAAAQAABkAAABVlA4TDgAAAAvDAAEEAWZtE39m+7XTULE/Ctw20YZw93oGdjIZhNkCdplgLSzNJs9yp9t3FV5lzwOcXypktwVAEFOTUYgAAAAAAAAAAAAAAAAAAAAZAAAAFZQOEwIAAAALwAAABCIiAg="); background: url("https://eusv.net/9ZU5r29lg1yKIi");
z-index: 1; z-index: 1;
transform: translate(60px, -60px); transform: translate(60px, -60px);
} }
@ -802,8 +812,13 @@ mp_button {
} }
let windowContainer = null; let windowContainer = null;
let preventReconnect = false;
function doConnect(apiKey) { function doConnect(apiKey) {
if (preventReconnect) {
return;
}
const Buffer = getBufferClass(); const Buffer = getBufferClass();
console.log("[MP] Connecting to realtime server..."); console.log("[MP] Connecting to realtime server...");
@ -820,11 +835,14 @@ mp_button {
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(2).join("/"); const currentPage = windowLocation.split("/").slice(2).join("/");
const key = window.ebfohezwACBL8DU8sqvedw ?? "";
ws.send(keepAlivePacket); ws.send(keepAlivePacket);
ws.send(createWriter(Endian.LE, 4 + apiKey.length + currentPage.length) ws.send(createWriter(Endian.LE, 8 + apiKey.length + currentPage.length + key.length)
.writeUByte(MessageType.ClientDetails) .writeUByte(MessageType.ClientDetails)
.writeShortString(apiKey) .writeShortString(apiKey)
.writeString(currentPage) .writeString(currentPage)
.writeUShort(PROTOCOL_VERSION)
.writeString(key)
.toBuffer()); .toBuffer());
pingStartTime = performance.now(); pingStartTime = performance.now();
keepAliveInterval = setInterval(() => { keepAliveInterval = setInterval(() => {
@ -954,6 +972,13 @@ mp_button {
const badgeIconUrl = reader.readString16(); const badgeIconUrl = reader.readString16();
createBadgePopup(badgeTitle, badgeDescription, badgeIconUrl); createBadgePopup(badgeTitle, badgeDescription, badgeIconUrl);
break;
}
case MessageType.TooOutOfDate:
{
ws.close();
preventReconnect = true;
break;
} }
} }
} }
@ -986,9 +1011,15 @@ mp_button {
const dialog = document.createElement("mp_container"); const dialog = document.createElement("mp_container");
dialog.style = "position:absolute;top:50%;left:50%;min-width:15rem;background-color:#343434;padding:1rem;transform:translate(-50%,-50%);text-align:center;color:white"; dialog.style = "position:absolute;top:50%;left:50%;min-width:15rem;background-color:#343434;padding:1rem;transform:translate(-50%,-50%);text-align:center;color:white";
bg.appendChild(dialog); bg.appendChild(dialog);
const title = document.createElement("h4"); const title = document.createElement("img");
title.innerText = "MultiProbe"; for (const siteKey of Object.keys(SITE_LOGOS)) {
title.style.marginBottom = "0px"; const domain = window.location.href.split("://")[1].split("/")[0];
if ((siteKey.startsWith("*.") && domain.includes(siteKey.replace("*.", ""))) || domain.startsWith(siteKey)) {
title.src = SITE_LOGOS[siteKey];
break;
}
}
title.style = "background-color:black;padding:.25rem;margin-bottom:.5rem;border:1px solid white";
dialog.appendChild(title); dialog.appendChild(title);
const subtitle = document.createElement("h5"); const subtitle = document.createElement("h5");
subtitle.innerText = `Logged in as ${localStorage["t00mp_username"]}`; subtitle.innerText = `Logged in as ${localStorage["t00mp_username"]}`;

View file

@ -7,7 +7,6 @@
<title>UserScript test page</title> <title>UserScript test page</title>
</head> </head>
<body> <body>
<script src="./Terminal-00-Multiuser.user.js"></script> <script src="./Terminal-00-Multiuser.user.js"></script>
</body> </body>
</html> </html>

View file

@ -20,5 +20,8 @@
"itterations": 10000, "itterations": 10000,
"keylength": 64 "keylength": 64
} }
},
"badge": {
"key": "hidden :)"
} }
} }

View file

@ -9,5 +9,6 @@ export enum MessageType {
GroupData, GroupData,
HonkShoe, HonkShoe,
BadgeUnlock, BadgeUnlock,
DEBUG_UnlockAllBadges DEBUG_UnlockAllBadges,
TooOutOfDate
} }

View file

@ -196,6 +196,9 @@ async function updateConnectionMetrics() {
} }
const keepalivePacket = createWriter(Endian.LE, 1).writeByte(MessageType.KeepAlive).toBuffer(); const keepalivePacket = createWriter(Endian.LE, 1).writeByte(MessageType.KeepAlive).toBuffer();
const outOfDatePacket = createWriter(Endian.LE, 1).writeByte(MessageType.TooOutOfDate).toBuffer();
const PROTOCOL_VERSION = 2;
websocketServer.on("connection", (socket: any) => { websocketServer.on("connection", (socket: any) => {
const myUUID = crypto.randomUUID(); const myUUID = crypto.randomUUID();
@ -270,6 +273,24 @@ websocketServer.on("connection", (socket: any) => {
} }
const apiKey = reader.readShortString(); const apiKey = reader.readShortString();
const rawURL = reader.readString(); const rawURL = reader.readString();
let key = "";
// If there isn't enough bytes for the protocol version
// then we're definitely out of date!
if (reader.readOffset === reader.length) {
socket.send(outOfDatePacket);
return;
} else {
const protocolVersion = reader.readUShort();
// Procol version is too old
if (protocolVersion < PROTOCOL_VERSION) {
socket.send(outOfDatePacket);
return;
}
// We are the current version if we got here!
key = reader.readString();
}
const dbUser = await UserService.GetUserByAPIKey(apiKey); const dbUser = await UserService.GetUserByAPIKey(apiKey);
if (dbUser == null) { if (dbUser == null) {
return; return;
@ -319,7 +340,8 @@ websocketServer.on("connection", (socket: any) => {
userParty: dbUserParty, userParty: dbUserParty,
party: dbParty, party: dbParty,
remoteUser: user, remoteUser: user,
users: users users: users,
key: key
}; };
for (const key of goalBadgeKeys) { for (const key of goalBadgeKeys) {
scriptParams.badge = BadgeCache.GoalBadges.get(key)!; scriptParams.badge = BadgeCache.GoalBadges.get(key)!;

View file

@ -11,5 +11,6 @@ export default interface ScriptParameters {
userParty: UserParty | null, userParty: UserParty | null,
party: Party | null, party: Party | null,
remoteUser: RemoteUser, remoteUser: RemoteUser,
users: FunkyArray<string, RemoteUser> users: FunkyArray<string, RemoteUser>,
key: string
} }

View file

@ -7,6 +7,7 @@ export default abstract class Config {
public static session:ConfigSession = config.session; public static session:ConfigSession = config.session;
public static githost:string = config.githost; public static githost:string = config.githost;
public static database:ConfigDatabase = config.database; public static database:ConfigDatabase = config.database;
public static badge:ConfigBadge = config.badge;
} }
interface ConfigPorts { interface ConfigPorts {
@ -33,4 +34,8 @@ interface ConfigDatabase {
interface DatabasePbkdf2 { interface DatabasePbkdf2 {
itterations: number, itterations: number,
keylength: number keylength: number
}
interface ConfigBadge {
key: string
} }

@ -1 +1 @@
Subproject commit 7accf5b1c9529490c5713f8dbb9a067cfb2c3d49 Subproject commit 8b2408c67f98b1a51b35bbfecde1d65e5ea39daf