using MessagePack; using Remotely.ScreenCast.Core.Communication; using Remotely.ScreenCast.Core.Interfaces; using Remotely.ScreenCast.Core.Models; using Remotely.Shared.Enums; using Remotely.Shared.Models.RtcDtos; using System; using System.Collections.Generic; using System.Dynamic; using System.Text; using System.Threading.Tasks; namespace Remotely.ScreenCast.Core.Services { public interface IRtcMessageHandler { Task ParseMessage(byte[] message); } public class RtcMessageHandler : IRtcMessageHandler { private Viewer Viewer { get; } public RtcMessageHandler(Viewer viewer, CasterSocket casterSocket, IKeyboardMouseInput keyboardMouseInput, IAudioCapturer audioCapturer, IClipboardService clipboardService, IFileTransferService fileDownloadService) { Viewer = viewer; CasterSocket = casterSocket; KeyboardMouseInput = keyboardMouseInput; AudioCapturer = audioCapturer; ClipboardService = clipboardService; FileDownloadService = fileDownloadService; } private CasterSocket CasterSocket { get; } private IKeyboardMouseInput KeyboardMouseInput { get; } private IAudioCapturer AudioCapturer { get; } private IClipboardService ClipboardService { get; } private IFileTransferService FileDownloadService { get; } public async Task ParseMessage(byte[] message) { try { var baseDto = MessagePackSerializer.Deserialize(message); switch (baseDto.DtoType) { case BinaryDtoType.MouseMove: case BinaryDtoType.MouseDown: case BinaryDtoType.MouseUp: case BinaryDtoType.Tap: case BinaryDtoType.MouseWheel: case BinaryDtoType.KeyDown: case BinaryDtoType.KeyUp: case BinaryDtoType.CtrlAltDel: case BinaryDtoType.ToggleBlockInput: case BinaryDtoType.ClipboardTransfer: case BinaryDtoType.KeyPress: { if (!Viewer.HasControl) { return; } } break; default: break; } switch (baseDto.DtoType) { case BinaryDtoType.SelectScreen: SelectScreen(message); break; case BinaryDtoType.MouseMove: MouseMove(message); break; case BinaryDtoType.MouseDown: MouseDown(message); break; case BinaryDtoType.MouseUp: MouseUp(message); break; case BinaryDtoType.Tap: Tap(message); break; case BinaryDtoType.MouseWheel: MouseWheel(message); break; case BinaryDtoType.KeyDown: KeyDown(message); break; case BinaryDtoType.KeyUp: KeyUp(message); break; case BinaryDtoType.CtrlAltDel: await CasterSocket.SendCtrlAltDel(); break; case BinaryDtoType.AutoQualityAdjust: SetAutoQualityAdjust(message); break; case BinaryDtoType.ToggleAudio: ToggleAudio(message); break; case BinaryDtoType.ToggleBlockInput: ToggleBlockInput(message); break; case BinaryDtoType.ClipboardTransfer: ClipboardTransfer(message); break; case BinaryDtoType.KeyPress: await KeyPress(message); break; case BinaryDtoType.QualityChange: QualityChange(message); break; case BinaryDtoType.File: await DownloadFile(message); break; default: break; } } catch (Exception ex) { Logger.Write(ex); } } private void QualityChange(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); Viewer.ImageQuality = dto.QualityLevel; } private async Task KeyPress(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendKeyDown(dto.Key, Viewer); await Task.Delay(1); KeyboardMouseInput.SendKeyUp(dto.Key, Viewer); } private void ClipboardTransfer(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); if (dto.TypeText) { KeyboardMouseInput.SendText(dto.Text, Viewer); } else { ClipboardService.SetText(dto.Text); } } private async Task DownloadFile(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); await FileDownloadService.ReceiveFile(dto.Buffer, dto.FileName, dto.MessageId, dto.EndOfFile, dto.StartOfFile); } private void ToggleBlockInput(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.ToggleBlockInput(dto.ToggleOn); } private void ToggleAudio(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); AudioCapturer.ToggleAudio(dto.ToggleOn); } private void SetAutoQualityAdjust(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); Viewer.AutoAdjustQuality = dto.IsOn; } private void KeyUp(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendKeyUp(dto.Key, Viewer); } private void KeyDown(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendKeyDown(dto.Key, Viewer); } private void MouseWheel(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendMouseWheel(-(int)dto.DeltaY, Viewer); } private void Tap(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendLeftMouseDown(dto.PercentX, dto.PercentY, Viewer); KeyboardMouseInput.SendLeftMouseUp(dto.PercentX, dto.PercentY, Viewer); } private void MouseUp(byte[] message) { 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 MouseDown(byte[] message) { 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) { var dto = MessagePackSerializer.Deserialize(message); KeyboardMouseInput.SendMouseMove(dto.PercentX, dto.PercentY, Viewer); } private void SelectScreen(byte[] message) { var dto = MessagePackSerializer.Deserialize(message); Viewer.Capturer.SetSelectedScreen(dto.DisplayName); } } }