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 building = false; const client: buttplug.ButtplugClient = 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) { return; } try { 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); if (e instanceof buttplug.ButtplugDeviceError) { vscode.window.showErrorMessage("got a device error!"); } } }); client .addListener("deviceremoved", (device) => vscode.window.showInformationMessage(`Device Removed: ${device.name}`)); config = vscode.workspace.getConfiguration('buttplug'); context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(async e => { if (!e.affectsConfiguration('buttplug')) { return; } config = vscode.workspace.getConfiguration('buttplug'); await connect(); })); // 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) { return; } await selected_device?.vibrate((config!.get('typingStrength') as number) * (config!.get('strength') as number)); if (timeout) { clearTimeout(timeout); } timeout = setTimeout(async () => await selected_device?.stop(), config!.get('typingDuration') as number * 1000); })); // 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) { 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 ((await vscode.tasks.taskExecutions).every(t => t.task.group !== vscode.TaskGroup.Build)) { building = false; await selected_device?.stop(); } })); // 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(); }