From a9645599eb02260cd1179766cfb9f718d1b1ab1b Mon Sep 17 00:00:00 2001 From: soaos Date: Thu, 29 Jan 2026 20:16:57 -0500 Subject: Server url config, utility commands, better build task completion detection --- .vscode-test.mjs | 5 --- package-lock.json | 5 +-- package.json | 18 +++++++++++ src/extension.ts | 78 ++++++++++++++++++++++++++++++++-------------- src/test/extension.test.ts | 15 --------- tsconfig.json | 1 + 6 files changed, 76 insertions(+), 46 deletions(-) delete mode 100644 .vscode-test.mjs delete mode 100644 src/test/extension.test.ts diff --git a/.vscode-test.mjs b/.vscode-test.mjs deleted file mode 100644 index b62ba25..0000000 --- a/.vscode-test.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import { defineConfig } from '@vscode/test-cli'; - -export default defineConfig({ - files: 'out/test/**/*.test.js', -}); diff --git a/package-lock.json b/package-lock.json index 6c41da5..1ce67ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,13 @@ { - "name": "buttplug-io-immersive-coding", + "name": "buttplug", "version": "0.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "buttplug-io-immersive-coding", + "name": "buttplug", "version": "0.0.1", + "license": "BSD-0-Clause", "dependencies": { "buttplug": "^3.2.2" }, diff --git a/package.json b/package.json index 84ed623..77cb4ae 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,20 @@ ], "main": "./out/extension.js", "contributes": { + "commands": [ + { + "title": "Buttplug: ASS BLAST", + "command": "buttplug.assblast" + }, + { + "title": "Buttplug: Killswitch", + "command": "buttplug.killswitch" + }, + { + "title": "Buttplug: Reconnect", + "command": "buttplug.reconnect" + } + ], "configuration": { "title": "buttplug", "type": "object", @@ -52,6 +66,10 @@ "minimum": 0, "maximum": 1, "default": 0.5 + }, + "buttplug.serverAddress": { + "description": "URL for Intiface Central server websocket connection", + "default": "ws://127.0.0.1:12345" } } } diff --git a/src/extension.ts b/src/extension.ts index 17b0f53..0cfa787 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,27 +1,36 @@ -// The module 'vscode' contains the VS Code extensibility API -// Import the module and reference it with the alias vscode in your code below import * as vscode from 'vscode'; import * as buttplug from 'buttplug'; let selected_device: buttplug.ButtplugClientDevice | null = null; let timeout: NodeJS.Timeout | null = null; let config: vscode.WorkspaceConfiguration | null = null; -let taskRunning = false; +let building = false; +const client: buttplug.ButtplugClient = new buttplug.ButtplugClient("VS Code"); -export async function activate(context: vscode.ExtensionContext) { - config = vscode.workspace.getConfiguration('buttplug'); - context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(_ => config = vscode.workspace.getConfiguration('buttplug'))); - const connector = new buttplug.ButtplugNodeWebsocketClientConnector("ws://127.0.0.1:12345"); - let client = new buttplug.ButtplugClient("VS Code"); +async function connect() { + const connector = new buttplug.ButtplugNodeWebsocketClientConnector(config!.get('serverAddress') as string); + if (client.connected) { + await client.stopAllDevices(); + await client.disconnect(); + } + try { + await client.connect(connector); + vscode.window.showInformationMessage("Connected to buttplug server."); + } catch (e) { + vscode.window.showErrorMessage(`Failed to connect to buttplug server: ${e}`); + } +} + +export async function activate(context: vscode.ExtensionContext) { client.addListener("deviceadded", async (device: buttplug.ButtplugClientDevice) => { vscode.window.showInformationMessage(`Device Connected: ${device.name}`); - if (device.vibrateAttributes.length == 0) { + if (device.vibrateAttributes.length === 0) { return; } try { - await device.vibrate(0.1); - await device.stop(); + await device.vibrate((config!.get('typingStrength') as number) * (config!.get('strength') as number)); + timeout = setTimeout(async () => await device?.stop(), 100); selected_device = device; } catch (e) { vscode.window.showErrorMessage(e as string); @@ -31,12 +40,19 @@ export async function activate(context: vscode.ExtensionContext) { } }); client - .addListener("deviceremoved", (device) => console.log(`Device Removed: ${device.name}`)); + .addListener("deviceremoved", (device) => vscode.window.showInformationMessage(`Device Removed: ${device.name}`)); + config = vscode.workspace.getConfiguration('buttplug'); - await client.connect(connector); + context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(async e => { + if (!e.affectsConfiguration('buttplug')) { return; } + config = vscode.workspace.getConfiguration('buttplug'); + await connect(); + })); - const disposable = vscode.workspace.onDidChangeTextDocument(async (e) => { - if (taskRunning) return; + // Vibe on type + context.subscriptions.push(vscode.workspace.onDidChangeTextDocument(async (e) => { + if (config!.get('typingStrength') === 0) { return; } + if (config!.get('buildStrength') !== 0 && building) { return; } const activeEditor = vscode.window.activeTextEditor; if (!activeEditor) { @@ -48,24 +64,38 @@ export async function activate(context: vscode.ExtensionContext) { clearTimeout(timeout); } timeout = setTimeout(async () => await selected_device?.stop(), config!.get('typingDuration') as number * 1000); - }); - - context.subscriptions.push(disposable); + })); + // Vibrate continuously while building context.subscriptions.push(vscode.tasks.onDidStartTask(async e => { + if (config!.get('buildStrength') === 0) { return; } if (e.execution.task.group === vscode.TaskGroup.Build) { - taskRunning = true; + building = true; await selected_device?.vibrate((config!.get('buildStrength') as number) * (config!.get('strength') as number)); } })); + // Stop vibration once build tasks all finish context.subscriptions.push(vscode.tasks.onDidEndTask(async e => { - if (e.execution.task.group === vscode.TaskGroup.Build) { - taskRunning = false; + if ((await vscode.tasks.taskExecutions).every(t => t.task.group !== vscode.TaskGroup.Build)) { + building = false; await selected_device?.stop(); } })); -} -// This method is called when your extension is deactivated -export function deactivate() { } + // Asshole obliteration command + vscode.commands.registerCommand("buttplug.assblast", () => { + selected_device?.vibrate(1.0); + }); + + // Killswitch for safety purposes + vscode.commands.registerCommand("buttplug.killswitch", () => { + selected_device?.stop(); + }); + + vscode.commands.registerCommand("buttplug.reconnect", () => { + connect(); + }); + + connect(); +} diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts deleted file mode 100644 index 4ca0ab4..0000000 --- a/src/test/extension.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as assert from 'assert'; - -// You can import and use all API from the 'vscode' module -// as well as import your extension to test it -import * as vscode from 'vscode'; -// import * as myExtension from '../../extension'; - -suite('Extension Test Suite', () => { - vscode.window.showInformationMessage('Start all tests.'); - - test('Sample test', () => { - assert.strictEqual(-1, [1, 2, 3].indexOf(5)); - assert.strictEqual(-1, [1, 2, 3].indexOf(0)); - }); -}); diff --git a/tsconfig.json b/tsconfig.json index 356580f..f6685a5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ ], "sourceMap": true, "rootDir": "src", + "skipLibCheck": true, "strict": true, /* enable all strict type-checking options */ /* Additional Checks */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ -- cgit v1.2.3