using MessagePack; using Remotely.Desktop.Core.Interfaces; using Remotely.Shared.Enums; using Remotely.Shared.Models.RemoteControlDtos; using Remotely.Shared.Utilities; using System; using System.Threading.Tasks; namespace Remotely.Desktop.Core.Services { public interface IDtoMessageHandler { Task ParseMessage(Services.Viewer viewer, byte[] message); } public class DtoMessageHandler : IDtoMessageHandler { public DtoMessageHandler(IKeyboardMouseInput keyboardMouseInput, IAudioCapturer audioCapturer, IClipboardService clipboardService, IFileTransferService fileTransferService) { KeyboardMouseInput = keyboardMouseInput; AudioCapturer = audioCapturer; ClipboardService = clipboardService; FileTransferService = fileTransferService; } private IAudioCapturer AudioCapturer { get; } private IClipboardService ClipboardService { get; } private IFileTransferService FileTransferService { get; } private IKeyboardMouseInput KeyboardMouseInput { get; } public async Task ParseMessage(Services.Viewer viewer, byte[] message) { try { var baseDto = MessagePackSerializer.Deserialize(message); switch (baseDto.DtoType) { case BaseDtoType.MouseMove: case BaseDtoType.MouseDown: case BaseDtoType.MouseUp: case BaseDtoType.Tap: case BaseDtoType.MouseWheel: case BaseDtoType.KeyDown: case BaseDtoType.KeyUp: case BaseDtoType.CtrlAltDel: case BaseDtoType.ToggleBlockInput: case BaseDtoType.ClipboardTransfer: case BaseDtoType.KeyPress: case BaseDtoType.SetKeyStatesUp: { if (!viewer.HasControl) { return; } } break; default: break; } switch (baseDto.DtoType) { case BaseDtoType.SelectScreen: SelectScreen(message, viewer); break; case BaseDtoType.MouseMove: MouseMove(message, viewer); break; case BaseDtoType.MouseDown: MouseDown(message, viewer); break; case BaseDtoType.MouseUp: MouseUp(message, viewer); break; case BaseDtoType.Tap: Tap(message, viewer); break; case BaseDtoType.MouseWheel: MouseWheel(message); break; case BaseDtoType.KeyDown: KeyDown(message); break; case BaseDtoType.KeyUp: KeyUp(message); break; case BaseDtoType.CtrlAltDel: await viewer.SendCtrlAltDel(); break; case BaseDtoType.AutoQualityAdjust: SetAutoQualityAdjust(message, viewer); break; case BaseDtoType.ToggleAudio: ToggleAudio(message); break; case BaseDtoType.ToggleBlockInput: ToggleBlockInput(message); break; case BaseDtoType.ToggleWebRtcVideo: ToggleWebRtcVideo(message, viewer); break; case BaseDtoType.ClipboardTransfer: await ClipboardTransfer(message); break; case BaseDtoType.KeyPress: await KeyPress(message); break; case BaseDtoType.QualityChange: QualityChange(message, viewer); break; case BaseDtoType.File: await DownloadFile(message); break; case BaseDtoType.WindowsSessions: await GetWindowsSessions(viewer); break; case BaseDtoType.SetKeyStatesUp: SetKeyStatesUp(); break; case BaseDtoType.FrameReceived: HandleFrameReceived(viewer); break; case BaseDtoType.OpenFileTransferWindow: OpenFileTransferWindow(viewer); break; default: break; } } catch (Exception ex) { Logger.Write(ex); } } private async Task ClipboardTransfer(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); if (dto.TypeText) { KeyboardMouseInput.SendText(dto.Text); } else { await ClipboardService.SetText(dto.Text); } } private async Task DownloadFile(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); await FileTransferService.ReceiveFile(dto.Buffer, dto.FileName, dto.MessageId, dto.EndOfFile, dto.StartOfFile); } private async Task GetWindowsSessions(Services.Viewer viewer) { await viewer.SendWindowsSessions(); } private void HandleFrameReceived(Services.Viewer viewer) { for (int i = 0; i < 5; i++) { if (viewer.PendingSentFrames.TryDequeue(out _)) { break; } } } private void KeyDown(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendKeyDown(dto.Key); } private async Task KeyPress(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendKeyDown(dto.Key); await Task.Delay(1); KeyboardMouseInput.SendKeyUp(dto.Key); } private void KeyUp(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendKeyUp(dto.Key); } private void MouseDown(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); if (dto.Button == 0) { KeyboardMouseInput.SendLeftMouseDown(dto.PercentX, dto.PercentY, viewer); } else if (dto.Button == 2) { KeyboardMouseInput.SendRightMouseDown(dto.PercentX, dto.PercentY, viewer); } } private void MouseMove(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendMouseMove(dto.PercentX, dto.PercentY, viewer); } private void MouseUp(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); if (dto.Button == 0) { KeyboardMouseInput.SendLeftMouseUp(dto.PercentX, dto.PercentY, viewer); } else if (dto.Button == 2) { KeyboardMouseInput.SendRightMouseUp(dto.PercentX, dto.PercentY, viewer); } } private void MouseWheel(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendMouseWheel(-(int)dto.DeltaY); } private void OpenFileTransferWindow(Services.Viewer viewer) { FileTransferService.OpenFileTransferWindow(viewer); } private void QualityChange(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); viewer.ImageQuality = dto.QualityLevel; } private void SelectScreen(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); viewer.Capturer.SetSelectedScreen(dto.DisplayName); } private void SetAutoQualityAdjust(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); viewer.AutoAdjustQuality = dto.IsOn; } private void SetKeyStatesUp() { KeyboardMouseInput.SetKeyStatesUp(); } private void Tap(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendLeftMouseDown(dto.PercentX, dto.PercentY, viewer); KeyboardMouseInput.SendLeftMouseUp(dto.PercentX, dto.PercentY, viewer); } private void ToggleAudio(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); AudioCapturer.ToggleAudio(dto.ToggleOn); } private void ToggleBlockInput(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.ToggleBlockInput(dto.ToggleOn); } private void ToggleWebRtcVideo(byte[] message, Services.Viewer viewer) { var dto = MessagePackSerializer.Deserialize(message); viewer.ToggleWebRtcVideo(dto.ToggleOn); } } }