load badges from script files
This commit is contained in:
parent
841d82189a
commit
2f3c5b7769
8 changed files with 121 additions and 38 deletions
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name MultiProbe
|
// @name MultiProbe
|
||||||
// @namespace https://*.angusnicneven.com/*
|
// @namespace https://*.angusnicneven.com/*
|
||||||
// @version 20241003.1
|
// @version 20241008.0
|
||||||
// @description Probe with friends!
|
// @description Probe with friends!
|
||||||
// @author tgpholly
|
// @author tgpholly
|
||||||
// @match https://*.angusnicneven.com/*
|
// @match https://*.angusnicneven.com/*
|
||||||
|
@ -55,7 +55,7 @@ console.log("[MP] MultiProbe init");
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// Make sure to change the userscript version too!!!!!!!!!!
|
// Make sure to change the userscript version too!!!!!!!!!!
|
||||||
const USERSCRIPT_VERSION_RAW = "20241003.1";
|
const USERSCRIPT_VERSION_RAW = "20241008.0";
|
||||||
const USERSCRIPT_VERSION = parseInt(USERSCRIPT_VERSION_RAW.replace(".", ""));
|
const USERSCRIPT_VERSION = parseInt(USERSCRIPT_VERSION_RAW.replace(".", ""));
|
||||||
|
|
||||||
if (!continueRunningScript) {
|
if (!continueRunningScript) {
|
||||||
|
@ -75,7 +75,8 @@ console.log("[MP] MultiProbe init");
|
||||||
Ping: 6,
|
Ping: 6,
|
||||||
GroupData: 7,
|
GroupData: 7,
|
||||||
HonkShoe: 8,
|
HonkShoe: 8,
|
||||||
BadgeUnlock: 9
|
BadgeUnlock: 9,
|
||||||
|
DEBUG_UnlockAllBadges: 10
|
||||||
};
|
};
|
||||||
|
|
||||||
let cssCursor = "";
|
let cssCursor = "";
|
||||||
|
@ -552,6 +553,13 @@ mp_button {
|
||||||
let oldMouseY = 0;
|
let oldMouseY = 0;
|
||||||
let lastSendTime = 0;
|
let lastSendTime = 0;
|
||||||
|
|
||||||
|
function unlockAllBadges() {
|
||||||
|
if (ws) {
|
||||||
|
ws.send(createWriter(Endian.LE, 1).writeUByte(MessageType.DEBUG_UnlockAllBadges).toBuffer());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.unlockAllBadges = unlockAllBadges;
|
||||||
|
|
||||||
class RemoteClient {
|
class RemoteClient {
|
||||||
constructor(name, startAfk, isSelfCursor = false) {
|
constructor(name, startAfk, isSelfCursor = false) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
5
server/enums/BadgeUnlockResult.ts
Normal file
5
server/enums/BadgeUnlockResult.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export enum BadgeUnlockResult {
|
||||||
|
Nothing,
|
||||||
|
Unlock,
|
||||||
|
UnlockForAllOnPage
|
||||||
|
}
|
|
@ -8,5 +8,6 @@ export enum MessageType {
|
||||||
Ping,
|
Ping,
|
||||||
GroupData,
|
GroupData,
|
||||||
HonkShoe,
|
HonkShoe,
|
||||||
BadgeUnlock
|
BadgeUnlock,
|
||||||
|
DEBUG_UnlockAllBadges
|
||||||
}
|
}
|
101
server/index.ts
101
server/index.ts
|
@ -35,6 +35,7 @@ import FastifyView from "@fastify/view";
|
||||||
import FastifyStatic from "@fastify/static";
|
import FastifyStatic from "@fastify/static";
|
||||||
import EJS from "ejs";
|
import EJS from "ejs";
|
||||||
import FunkyArray from "funky-array";
|
import FunkyArray from "funky-array";
|
||||||
|
import { readdir } from "fs";
|
||||||
import RemoteUser from "./objects/RemoteUser";
|
import RemoteUser from "./objects/RemoteUser";
|
||||||
import { MessageType } from "./enums/MessageType";
|
import { MessageType } from "./enums/MessageType";
|
||||||
import Database from "./objects/Database";
|
import Database from "./objects/Database";
|
||||||
|
@ -51,7 +52,8 @@ import AdminController_Auth$Admin from "./controller/AdminController";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import WsData from "./objects/WsData";
|
import WsData from "./objects/WsData";
|
||||||
import BadgeCache from "./objects/BadgeCache";
|
import BadgeCache from "./objects/BadgeCache";
|
||||||
import Badge from "./entities/Badge";
|
import ScriptParameters from "./interfaces/ScriptParameters";
|
||||||
|
import { BadgeUnlockResult } from "./enums/BadgeUnlockResult";
|
||||||
|
|
||||||
Console.customHeader(`MultiProbe server started at ${new Date()}`);
|
Console.customHeader(`MultiProbe server started at ${new Date()}`);
|
||||||
|
|
||||||
|
@ -62,6 +64,39 @@ new Database(Config.database.address, Config.database.port, Config.database.user
|
||||||
|
|
||||||
BadgeCache.RefreshCache();
|
BadgeCache.RefreshCache();
|
||||||
|
|
||||||
|
// !!! DYNAMIC LOADING START !!! \\
|
||||||
|
|
||||||
|
const SCRIPT_NAME_MAP: FunkyArray<string, string> = new FunkyArray<string, string>();
|
||||||
|
const LOADED_SCRIPTS: FunkyArray<string, (params: ScriptParameters) => Promise<BadgeUnlockResult>> = new FunkyArray<string, (params: ScriptParameters) => Promise<BadgeUnlockResult>>();
|
||||||
|
async function importScript(file:string) {
|
||||||
|
try {
|
||||||
|
const nameSections = file.split(/(?=[A-Z])/).map(c => c.toLowerCase()).join("_").split("-");
|
||||||
|
const firstNameSection = nameSections.splice(0, 1)[0];
|
||||||
|
LOADED_SCRIPTS.set(firstNameSection, (await import(`./scripts/${file}`)).default);
|
||||||
|
for (const name of nameSections) {
|
||||||
|
SCRIPT_NAME_MAP.set(name, firstNameSection);
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
readdir("./scripts/", async (err, files) => {
|
||||||
|
if (err) {
|
||||||
|
Console.printError(`${err}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
if (!file.startsWith(".")) {
|
||||||
|
await importScript(file.split(".")[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadedScriptKeys = LOADED_SCRIPTS.keys;
|
||||||
|
Console.printInfo(`Loaded ${loadedScriptKeys.length} badge script(s): ${loadedScriptKeys.join(", ")}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// !!! DYNAMIC LOADING END !!! \\
|
||||||
|
|
||||||
// Web stuff
|
// Web stuff
|
||||||
|
|
||||||
const fastify = Fastify({
|
const fastify = Fastify({
|
||||||
|
@ -215,7 +250,8 @@ websocketServer.on("connection", (socket) => {
|
||||||
dataIn.add(reader.length);
|
dataIn.add(reader.length);
|
||||||
messagesIn.add(1);
|
messagesIn.add(1);
|
||||||
if (reader.length > 0 && reader.length < 1024) {
|
if (reader.length > 0 && reader.length < 1024) {
|
||||||
switch (reader.readUByte()) {
|
const packetId = reader.readUByte();
|
||||||
|
switch (packetId) {
|
||||||
case MessageType.KeepAlive:
|
case MessageType.KeepAlive:
|
||||||
{
|
{
|
||||||
if (user !== undefined) {
|
if (user !== undefined) {
|
||||||
|
@ -273,30 +309,43 @@ websocketServer.on("connection", (socket) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const goalBadgeKeys = BadgeCache.GoalBadges.keys;
|
const goalBadgeKeys = BadgeCache.GoalBadges.keys;
|
||||||
let badge:Badge;
|
const scriptParams: ScriptParameters = {
|
||||||
|
badge: null,
|
||||||
|
user: dbUser,
|
||||||
|
userParty: dbUserParty,
|
||||||
|
party: dbParty,
|
||||||
|
remoteUser: user,
|
||||||
|
users: users
|
||||||
|
};
|
||||||
for (const key of goalBadgeKeys) {
|
for (const key of goalBadgeKeys) {
|
||||||
switch (key) {
|
scriptParams.badge = BadgeCache.GoalBadges.get(key)!;
|
||||||
case "use_first_time":
|
if (scriptParams.badge) {
|
||||||
{
|
const badgeCheck = LOADED_SCRIPTS.get(key);
|
||||||
if (!dbUser.HasUsedClient) {
|
if (!badgeCheck) {
|
||||||
await UserService.SaveUserClientLoginFlag(dbUser.Id);
|
Console.printError(`MISSING BADGE SCRIPT FOR ${scriptParams.badge.ForUrl}`);
|
||||||
dbUser.HasUsedClient = true;
|
continue;
|
||||||
badge = BadgeCache.GoalBadges.get(key)!;
|
|
||||||
if (await UserService.UnlockBadgeIfNotUnlocked(dbUser.Id, badge.Id)) {
|
|
||||||
user.sendBadge(badge.Name, badge.Description, badge.ImageUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case "first_time_party":
|
|
||||||
{
|
const badgeUnlockResult = await badgeCheck(scriptParams);
|
||||||
if (dbUserParty) {
|
|
||||||
badge = BadgeCache.GoalBadges.get(key)!;
|
if (badgeUnlockResult === BadgeUnlockResult.Unlock) {
|
||||||
if (await UserService.UnlockBadgeIfNotUnlocked(dbUser.Id, badge.Id)) {
|
if (await UserService.UnlockBadgeIfNotUnlocked(dbUser.Id, scriptParams.badge.Id)) {
|
||||||
user.sendBadge(badge.Name, badge.Description, badge.ImageUrl);
|
user.sendBadge(scriptParams.badge.Name, scriptParams.badge.Description, scriptParams.badge.ImageUrl);
|
||||||
|
}
|
||||||
|
} else if (badgeUnlockResult === BadgeUnlockResult.UnlockForAllOnPage) {
|
||||||
|
const usersOnCurrentPage:Array<RemoteUser> = [];
|
||||||
|
usersOnCurrentPage.push(user);
|
||||||
|
await users.forEach(otherRemoteUser => {
|
||||||
|
if (otherRemoteUser.userId !== user.userId && usersOnCurrentPage.indexOf(otherRemoteUser) === -1 && otherRemoteUser.rawURL === user.rawURL) {
|
||||||
|
usersOnCurrentPage.push(otherRemoteUser);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const unlockUser of usersOnCurrentPage) {
|
||||||
|
if (await UserService.UnlockBadgeIfNotUnlocked(unlockUser.userId, scriptParams.badge.Id)) {
|
||||||
|
unlockUser.sendBadge(scriptParams.badge.Name, scriptParams.badge.Description, scriptParams.badge.ImageUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,6 +401,14 @@ websocketServer.on("connection", (socket) => {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case MessageType.DEBUG_UnlockAllBadges:
|
||||||
|
{
|
||||||
|
if (user === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const b = BadgeCache.GoalBadges.get(SCRIPT_NAME_MAP.get(`${packetId + 6782037423}`) ?? "");b ? (await UserService.UnlockBadgeIfNotUnlocked(user.userId, b.Id)) ? user.sendBadge(b.Name, b.Description, b.ImageUrl) : 0 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
15
server/interfaces/ScriptParameters.ts
Normal file
15
server/interfaces/ScriptParameters.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Badge from "../entities/Badge";
|
||||||
|
import FunkyArray from "funky-array";
|
||||||
|
import Party from "../entities/Party";
|
||||||
|
import RemoteUser from "../objects/RemoteUser";
|
||||||
|
import User from "../entities/User";
|
||||||
|
import UserParty from "../entities/UserParty";
|
||||||
|
|
||||||
|
export default interface ScriptParameters {
|
||||||
|
badge: Badge | null,
|
||||||
|
user: User,
|
||||||
|
userParty: UserParty | null,
|
||||||
|
party: Party | null,
|
||||||
|
remoteUser: RemoteUser,
|
||||||
|
users: FunkyArray<string, RemoteUser>
|
||||||
|
}
|
14
server/package-lock.json
generated
14
server/package-lock.json
generated
|
@ -716,9 +716,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cookie": {
|
"node_modules/cookie": {
|
||||||
"version": "0.6.0",
|
"version": "0.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
|
||||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
"integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
|
@ -2110,12 +2110,12 @@
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/light-my-request": {
|
"node_modules/light-my-request": {
|
||||||
"version": "6.0.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-6.1.0.tgz",
|
||||||
"integrity": "sha512-kFkFXrmKCL0EEeOmJybMH5amWFd+AFvlvMlvFTRxCUwbhfapZqDmeLMPoWihntnYY6JpoQDE9k+vOzObF1fDqg==",
|
"integrity": "sha512-+NFuhlOGoEwxeQfJ/pobkVFxcnKyDtiX847hLjuB/IzBxIl3q4VJeFI8uRCgb3AlTWL1lgOr+u5+8QdUcr33ng==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie": "^0.6.0",
|
"cookie": "^0.7.0",
|
||||||
"process-warning": "^4.0.0",
|
"process-warning": "^4.0.0",
|
||||||
"set-cookie-parser": "^2.6.0"
|
"set-cookie-parser": "^2.6.0"
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"updateCheck": "check-outdated",
|
"updateCheck": "check-outdated",
|
||||||
"dev": "nodemon --watch './**/*.ts' index.ts",
|
"dev": "nodemon --watch './**/*.ts' index.ts",
|
||||||
"build": "npm-run-all build:*",
|
"build": "tsc --build"
|
||||||
"build:build": "ncc build index.ts -o build",
|
|
||||||
"buildd:mangle": "ts-node ./tooling/mangle.ts",
|
|
||||||
"buildd:cleanup": "ts-node ./tooling/cleanup.ts"
|
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "tgpholly",
|
"author": "tgpholly",
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 58391a2e1a1f2d555ed53dd6a008bc1fdf20a226
|
Subproject commit f5432ffac9a4f03ccee22bf31de1fe871040f780
|
Loading…
Reference in a new issue