Editor/Tools/WorkflowTools.AudioAndChat.cs

Editor MCP assistant tools for audio and chat testing. It exposes three editor-only MCP tools that call AudioAndChatDriver to inject synthesized or WAV audio into the client voice stream, probe spatial audio settings, and simulate chat messages or announcements.

File Access
#nullable enable
using System;
using System.ComponentModel;

namespace Editor.Mcp
{
	public static partial class SboxMcpAssistant
	{
		/// <summary>
		/// Injects synthesized voice audio tones or PCM audio from WAV files directly into the client's
		/// microphone voice stream (Sandbox.SoundStream) for testing voice transmission, mute toggles,
		/// volume levels, and channel isolation (Team, Party, Proximity).
		/// </summary>
		[McpTool( "pocketknife_voice_stream_inject" )]
		public static string VoiceStreamInject(
			[Description( "Audio generation mode: 'tone' (synthesized sine wave), 'wav_file', 'silence'" )] string mode = "tone",
			[Description( "Playback duration in seconds (0.1 to 10.0, default 1.0)" )] float durationSeconds = 1.0f,
			[Description( "Audio sample rate (8000-48000, default 44100)" )] int sampleRate = 44100,
			[Description( "Tone frequency in Hz (20-10000, default 440 for A4)" )] float frequencyHz = 440f,
			[Description( "Path to WAV audio file on disk (for wav_file mode)" )] string? filePath = null,
			[Description( "Audio volume scale (0.0 to 2.0, default 1.0)" )] float volume = 1.0f,
			[Description( "Audio pitch scale (0.1 to 2.0, default 1.0)" )] float pitch = 1.0f,
			[Description( "Voice channel tag: 'all', 'team', 'party', 'traitor'" )] string channel = "all",
			[Description( "Whether client microphone is muted" )] bool mute = false )
		{
			try
			{
				var result = AudioAndChatDriver.InjectVoiceStream(
					mode,
					durationSeconds,
					sampleRate,
					frequencyHz,
					filePath,
					volume,
					pitch,
					channel,
					mute
				);
				return McpJson.Write( result );
			}
			catch ( Exception ex )
			{
				return McpJson.Write( ToolOutcome<object>.Failure( null, ToolStatus.Failed, "voice.inject_failed", "Voice stream injection failed.", ex ) );
			}
		}

		/// <summary>
		/// Probes 3D spatial audio acoustics, room occlusion, distance falloff curves, and facial morph
		/// lip-sync visemes from a sound emitter attached to a character's mouth/head bone.
		/// </summary>
		[McpTool( "pocketknife_spatial_audio_probe" )]
		public static string SpatialAudioProbe(
			[Description( "Target sound emitter GameObject name or GUID" )] string target,
			[Description( "SoundEvent or sound file to trigger (optional)" )] string? soundEventOrFile = null,
			[Description( "Volume multiplier (0.0 to 2.0, default 1.0)" )] float volume = 1.0f,
			[Description( "Maximum audible distance in units (default 1000)" )] float maxDistance = 1000f,
			[Description( "Whether to test intervening geometry wall occlusion" )] bool testOcclusion = true,
			[Description( "Listener GameObject name (defaults to main camera if omitted)" )] string? listenerTarget = null )
		{
			try
			{
				var result = AudioAndChatDriver.ProbeSpatialAudio(
					target,
					soundEventOrFile,
					volume,
					maxDistance,
					testOcclusion,
					listenerTarget
				);
				return McpJson.Write( result );
			}
			catch ( Exception ex )
			{
				return McpJson.Write( ToolOutcome<object>.Failure( null, ToolStatus.Failed, "audio.probe_failed", "Spatial audio probe failed.", ex ) );
			}
		}

		/// <summary>
		/// Simulates text chat: injects player chat messages (Chat.Say), broadcasts server/system announcements
		/// (Chat.AddText), tests channel isolation, and validates moderation/profanity suppression filters.
		/// </summary>
		[McpTool( "pocketknife_chat_simulate" )]
		public static string ChatSimulate(
			[Description( "Action: 'say' (player chat), 'announcement' (system text), 'test_filter' (moderation)" )] string action = "say",
			[Description( "Message text content" )] string message = "Hello from MCP test harness",
			[Description( "Chat channel: 'all', 'team', 'party', 'whisper'" )] string channel = "all",
			[Description( "Custom filter word to test for suppression" )] string? filterWord = null )
		{
			try
			{
				var result = AudioAndChatDriver.SimulateChat( action, message, channel, filterWord );
				return McpJson.Write( result );
			}
			catch ( Exception ex )
			{
				return McpJson.Write( ToolOutcome<object>.Failure( null, ToolStatus.Failed, "chat.simulate_failed", "Chat simulation failed.", ex ) );
			}
		}
	}
}