From 902a86c3b24ee1b64af5a51b404ae4fb7c0ad95c Mon Sep 17 00:00:00 2001 From: Nyako <24845294+nyakowint@users.noreply.github.com> Date: Tue, 30 Jul 2024 17:48:11 -0400 Subject: [PATCH] XSOverlay: Update to new API (#2736) Co-authored-by: v --- src/plugins/xsOverlay.desktop/README.md | 15 --- src/plugins/xsOverlay.desktop/native.ts | 16 ---- src/plugins/xsOverlay/README.md | 14 +++ .../index.ts => xsOverlay/index.tsx} | 95 ++++++++++++++++--- 4 files changed, 94 insertions(+), 46 deletions(-) delete mode 100644 src/plugins/xsOverlay.desktop/README.md delete mode 100644 src/plugins/xsOverlay.desktop/native.ts create mode 100644 src/plugins/xsOverlay/README.md rename src/plugins/{xsOverlay.desktop/index.ts => xsOverlay/index.tsx} (83%) diff --git a/src/plugins/xsOverlay.desktop/README.md b/src/plugins/xsOverlay.desktop/README.md deleted file mode 100644 index 477e30bf..00000000 --- a/src/plugins/xsOverlay.desktop/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# XSOverlay Notifier - -Sends Discord messages to [XSOverlay](https://store.steampowered.com/app/1173510/XSOverlay/) for easier viewing while using VR. - -## Preview - -![](https://github.com/Vendicated/Vencord/assets/24845294/205d2055-bb4a-44e4-b7e3-265391bccd40) - -![](https://github.com/Vendicated/Vencord/assets/24845294/f15eff61-2d52-4620-bcab-808ecb1606d2) - -## Usage -- Enable this plugin -- Set plugin settings as desired -- Open XSOverlay -- get ping spammed diff --git a/src/plugins/xsOverlay.desktop/native.ts b/src/plugins/xsOverlay.desktop/native.ts deleted file mode 100644 index 82809383..00000000 --- a/src/plugins/xsOverlay.desktop/native.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { createSocket, Socket } from "dgram"; - -let xsoSocket: Socket; - -export function sendToOverlay(_, data: any) { - data.icon = Buffer.from(data.icon).toString("base64"); - const json = JSON.stringify(data); - xsoSocket ??= createSocket("udp4"); - xsoSocket.send(json, 42069, "127.0.0.1"); -} diff --git a/src/plugins/xsOverlay/README.md b/src/plugins/xsOverlay/README.md new file mode 100644 index 00000000..7f517c17 --- /dev/null +++ b/src/plugins/xsOverlay/README.md @@ -0,0 +1,14 @@ +# XSOverlay Notifier + +Sends Discord messages to [XSOverlay](https://store.steampowered.com/app/1173510/XSOverlay/) for easier viewing while using VR. + +## Preview + +![Resulting notification inside XSOverlay](https://github.com/Vendicated/Vencord/assets/24845294/205d2055-bb4a-44e4-b7e3-265391bccd40) + +![Test notification inside XSOverlay](https://github.com/user-attachments/assets/d3b0c387-1d67-4697-a470-d4a927e228f4) + +## Usage +- Enable this plugin +- Set port and plugin settings as desired (defaults should work fine) +- Open SteamVR and XSOverlay diff --git a/src/plugins/xsOverlay.desktop/index.ts b/src/plugins/xsOverlay/index.tsx similarity index 83% rename from src/plugins/xsOverlay.desktop/index.ts rename to src/plugins/xsOverlay/index.tsx index 8b06475c..ab76a0e7 100644 --- a/src/plugins/xsOverlay.desktop/index.ts +++ b/src/plugins/xsOverlay/index.tsx @@ -8,9 +8,9 @@ import { definePluginSettings } from "@api/Settings"; import { makeRange } from "@components/PluginSettings/components"; import { Devs } from "@utils/constants"; import { Logger } from "@utils/Logger"; -import definePlugin, { OptionType, PluginNative, ReporterTestable } from "@utils/types"; +import definePlugin, { OptionType, ReporterTestable } from "@utils/types"; import { findByCodeLazy, findLazy } from "@webpack"; -import { ChannelStore, GuildStore, UserStore } from "@webpack/common"; +import { Button, ChannelStore, GuildStore, UserStore } from "@webpack/common"; import type { Channel, Embed, GuildMember, MessageAttachment, User } from "discord-types/general"; const ChannelTypes = findLazy(m => m.ANNOUNCEMENT_THREAD === 10); @@ -68,10 +68,40 @@ interface Call { ringing: string[]; } +interface ApiObject { + sender: string, + target: string, + command: string, + jsonData: string, + rawData: string | null, +} + +interface NotificationObject { + type: number; + timeout: number; + height: number; + opacity: number; + volume: number; + audioPath: string; + title: string; + content: string; + useBase64Icon: boolean; + icon: ArrayBuffer | string; + sourceApp: string; +} + const notificationsShouldNotify = findByCodeLazy(".SUPPRESS_NOTIFICATIONS))return!1"); -const XSLog = new Logger("XSOverlay"); +const logger = new Logger("XSOverlay"); const settings = definePluginSettings({ + webSocketPort: { + type: OptionType.NUMBER, + description: "Websocket port", + default: 42070, + async onChange() { + await start(); + } + }, botNotifications: { type: OptionType.BOOLEAN, description: "Allow bot notifications", @@ -136,7 +166,17 @@ const settings = definePluginSettings({ }, }); -const Native = VencordNative.pluginHelpers.XSOverlay as PluginNative; +let socket: WebSocket; + +async function start() { + if (socket) socket.close(); + socket = new WebSocket(`ws://127.0.0.1:${settings.store.webSocketPort ?? 42070}/?client=Vencord`); + return new Promise((resolve, reject) => { + socket.onopen = resolve; + socket.onerror = reject; + setTimeout(reject, 3000); + }); +} export default definePlugin({ name: "XSOverlay", @@ -248,7 +288,21 @@ export default definePlugin({ if (shouldIgnoreForChannelType(channel)) return; sendMsgNotif(titleString, finalMsg, message); } - } + }, + + start, + + stop() { + socket.close(); + }, + + settingsAboutComponent: () => ( + <> + + + ) }); function shouldIgnoreForChannelType(channel: Channel) { @@ -259,9 +313,8 @@ function shouldIgnoreForChannelType(channel: Channel) { function sendMsgNotif(titleString: string, content: string, message: Message) { fetch(`https://cdn.discordapp.com/avatars/${message.author.id}/${message.author.avatar}.png?size=128`).then(response => response.arrayBuffer()).then(result => { - const msgData = { - messageType: 1, - index: 0, + const msgData: NotificationObject = { + type: 1, timeout: settings.store.lengthBasedTimeout ? calculateTimeout(content) : settings.store.timeout, height: calculateHeight(content), opacity: settings.store.opacity, @@ -270,17 +323,17 @@ function sendMsgNotif(titleString: string, content: string, message: Message) { title: titleString, content: content, useBase64Icon: true, - icon: result, + icon: new TextDecoder().decode(result), sourceApp: "Vencord" }; - Native.sendToOverlay(msgData); + + sendToOverlay(msgData); }); } function sendOtherNotif(content: string, titleString: string) { - const msgData = { - messageType: 1, - index: 0, + const msgData: NotificationObject = { + type: 1, timeout: settings.store.lengthBasedTimeout ? calculateTimeout(content) : settings.store.timeout, height: calculateHeight(content), opacity: settings.store.opacity, @@ -289,10 +342,22 @@ function sendOtherNotif(content: string, titleString: string) { title: titleString, content: content, useBase64Icon: false, - icon: null, + icon: "default", sourceApp: "Vencord" }; - Native.sendToOverlay(msgData); + sendToOverlay(msgData); +} + +async function sendToOverlay(notif: NotificationObject) { + const apiObject: ApiObject = { + sender: "Vencord", + target: "xsoverlay", + command: "SendNotification", + jsonData: JSON.stringify(notif), + rawData: null + }; + if (socket.readyState !== socket.OPEN) await start(); + socket.send(JSON.stringify(apiObject)); } function shouldNotify(message: Message, channel: string) {