private void HandleMessage(DiscordLinkConnection dlc) { if (dlc.messageType == DiscordClientMessageType.REGISTER) { //Don't allow servers to change their link key on the same connection. if (dlc.linkKey == 0) { using (MessageReader mr = new MessageReader(dlc.buffer)) { dlc.linkKey = mr.Read <ulong>(); Console.WriteLine("Registered " + dlc.linkKey + " from " + dlc.tcpClient.Client.RemoteEndPoint); SendRegisterOK(dlc); } } else { SendDisconnect(dlc); } } if (dlc.messageType == DiscordClientMessageType.MESSAGE) { using (MessageReader mr = new MessageReader(dlc.buffer)) { string message = mr.Read <string>(); sendToDiscord(dlc.linkKey, message); Console.WriteLine("[DMP->Discord:" + dlc.linkKey + "] " + message); } } }
private void HandleAccept(IAsyncResult ar) { if (!running) { return; } long timeNow = DateTime.UtcNow.Ticks; TcpListener tcpServer = (TcpListener)ar.AsyncState; try { TcpClient tcpClient = tcpServer.EndAcceptTcpClient(ar); DiscordLinkConnection newDlc = new DiscordLinkConnection(); newDlc.tcpClient = tcpClient; newDlc.lastSend = timeNow; newDlc.lastReceive = timeNow; lock (clients) { clients.Add(newDlc); } Console.WriteLine("Accepted new client: " + tcpClient.Client.RemoteEndPoint); } catch (Exception e) { Console.WriteLine("Error accepting client: " + e.Message); } BeginAccept(tcpServer); }
private void SendMessage(DiscordLinkConnection dlc, string message) { using (MessageWriter mw = new MessageWriter()) { mw.Write <string>(message); SendToDLC(dlc, DiscordServerMessageType.MESSAGE, mw.GetMessageBytes()); } }
private void SendDisconnect(DiscordLinkConnection dlc) { SendToDLC(dlc, DiscordServerMessageType.DISCONNECT, null); try { dlc.tcpClient.Close(); } catch { Console.WriteLine("Disconnected " + dlc.linkKey); } lock (clients) { clients.Remove(dlc); } }
private void SendToDLC(DiscordLinkConnection dlc, DiscordServerMessageType type, byte[] data) { dlc.lastSend = DateTime.UtcNow.Ticks; if (!dlc.tcpClient.Connected) { lock (clients) { Console.WriteLine(dlc.linkKey + " disconnected."); clients.Remove(dlc); } return; } if (dlc.linkKey == 0) { return; } try { byte[] sendData; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)type); if (data == null || data.Length == 0) { mw.Write <int>(0); } else { mw.Write <byte[]>(data); } sendData = mw.GetMessageBytes(); } dlc.tcpClient.GetStream().Write(sendData, 0, sendData.Length); } catch { if (type != DiscordServerMessageType.DISCONNECT) { Console.WriteLine("Error sending, disconnecting " + dlc.linkKey); SendDisconnect(dlc); } } }
public void ReceiveMain() { while (running) { long timeNow = DateTime.UtcNow.Ticks; Thread.Sleep(100); lock (clients) { for (int i = clients.Count - 1; i >= 0; i--) { DiscordLinkConnection dlc = clients[i]; if (!dlc.tcpClient.Connected) { try { dlc.tcpClient.Close(); } catch { Console.WriteLine("Removed " + dlc.linkKey + " from clients."); } clients.RemoveAt(i); continue; } if (timeNow > dlc.lastSend + HEARTBEAT) { SendHeartbeat(dlc); } if (timeNow > dlc.lastReceive + TIMEOUT) { SendDisconnect(dlc); clients.RemoveAt(i); continue; } try { if (dlc.tcpClient.Connected && dlc.tcpClient.Available > 0) { dlc.lastReceive = timeNow; int bytesToRead = dlc.bufferSize - dlc.bufferPos; if (bytesToRead > dlc.tcpClient.Available) { bytesToRead = dlc.tcpClient.Available; } int bytesRead = dlc.tcpClient.GetStream().Read(dlc.buffer, dlc.bufferPos, bytesToRead); dlc.bufferPos += bytesRead; if (dlc.bufferPos == dlc.bufferSize) { if (dlc.readingHeader) { using (MessageReader mr = new MessageReader(dlc.buffer)) { dlc.messageType = (DiscordClientMessageType)mr.Read <int>(); int length = mr.Read <int>(); if (length == 0) { HandleMessage(dlc); dlc.bufferPos = 0; dlc.bufferSize = 8; dlc.readingHeader = true; } else { dlc.bufferPos = 0; dlc.bufferSize = length; dlc.readingHeader = false; continue; } } } else { HandleMessage(dlc); dlc.bufferPos = 0; dlc.bufferSize = 8; dlc.readingHeader = true; } } } } catch (Exception e) { Console.WriteLine("Error receiving from " + dlc.linkKey + ", error: " + e.Message); } } } } }
private void SendRegisterOK(DiscordLinkConnection dlc) { SendToDLC(dlc, DiscordServerMessageType.REGISTER_RESPONSE, null); }
private void SendHeartbeat(DiscordLinkConnection dlc) { SendToDLC(dlc, DiscordServerMessageType.HEARTBEAT, null); }