using System; using System.Net.Sockets; using MinecraftClient.Crypto; namespace MinecraftClient.Protocol.Handlers { /// /// Wrapper for handling unencrypted & encrypted socket /// class SocketWrapper { TcpClient c; IAesStream s; bool encrypted = false; /// /// Initialize a new SocketWrapper /// /// TcpClient connected to the server public SocketWrapper(TcpClient client) { this.c = client; } /// /// Check if the socket is still connected /// /// TRUE if still connected /// Silently dropped connection can only be detected by attempting to read/write data public bool IsConnected() { return c.Client != null && c.Connected; } /// /// Check if the socket has data available to read /// /// TRUE if data is available to read public bool HasDataAvailable() { return c.Client.Available > 0; } /// /// Switch network reading/writing to an encrypted stream /// /// AES secret key public void SwitchToEncrypted(byte[] secretKey) { if (encrypted) throw new InvalidOperationException("Stream is already encrypted!?"); this.s = CryptoHandler.getAesStream(c.GetStream(), secretKey); this.encrypted = true; } /// /// Network reading method. Read bytes from the socket or encrypted socket. /// private void Receive(byte[] buffer, int start, int offset, SocketFlags f) { int read = 0; while (read < offset) { if (encrypted) { read += s.Read(buffer, start + read, offset - read); } else read += c.Client.Receive(buffer, start + read, offset - read, f); } } /// /// Read some data from the server. /// /// Amount of bytes to read /// The data read from the network as an array public byte[] ReadDataRAW(int length) { if (length > 0) { byte[] cache = new byte[length]; Receive(cache, 0, length, SocketFlags.None); return cache; } return Array.Empty(); } /// /// Send raw data to the server. /// /// data to send public void SendDataRAW(byte[] buffer) { if (encrypted) { s.Write(buffer, 0, buffer.Length); } else c.Client.Send(buffer); } /// /// Disconnect from the server /// public void Disconnect() { try { c.Close(); } catch (SocketException) { } catch (System.IO.IOException) { } catch (NullReferenceException) { } catch (ObjectDisposedException) { } } } }