/// <summary> /// Send the outgoing buffer. /// </summary> public void EndSend() { mBuffer.EndPacket(); mTcp.SendTcpPacket(mBuffer); mBuffer.Recycle(); mBuffer = null; }
/// <summary> /// Send the outgoing buffer. /// </summary> public void EndSend() { if (mBuffer != null) { mBuffer.EndPacket(); if (mCanSend) { mTcp.SendTcpPacket(mBuffer); } mBuffer.Recycle(); mBuffer = null; } }
/// <summary> /// Send the outgoing buffer. /// </summary> public void EndSend(bool forced = false) { if (mBuffer != null) { mBuffer.EndPacket(); if (isActive || forced) { mTcp.SendTcpPacket(mBuffer); } mBuffer.Recycle(); mBuffer = null; } }
/// <summary> /// Thread that will be processing incoming data. /// </summary> void ThreadFunction() { for (; ; ) { mTime = DateTime.Now.Ticks / 10000; // Accept incoming connections while (mListener != null && mListener.Pending()) { TcpProtocol tc = new TcpProtocol(); tc.data = (long)(-1); tc.StartReceiving(mListener.AcceptSocket()); mTcp.Add(tc); } Buffer buffer = null; // Process incoming TCP packets for (int i = 0; i < mTcp.size; ++i) { TcpProtocol tc = mTcp[i]; while (tc.ReceivePacket(out buffer)) { try { if (!ProcessPacket(buffer, tc)) { RemoveServer(tc); tc.Disconnect(); } } #if STANDALONE catch (System.Exception ex) { Console.WriteLine("ERROR: " + ex.Message); RemoveServer(tc); tc.Disconnect(); } #else catch (System.Exception) { RemoveServer(tc); tc.Disconnect(); } #endif if (buffer != null) { buffer.Recycle(); buffer = null; } } } // We only want to send instant updates if the number of players is under a specific threshold if (mTcp.size > instantUpdatesClientLimit) mInstantUpdates = false; // Send the server list to all connected clients for (int i = 0; i < mTcp.size; ++i) { TcpProtocol tc = mTcp[i]; long customTimestamp = (long)tc.data; // Timestamp of -1 means we don't want updates to be sent if (tc.stage != TcpProtocol.Stage.Connected || customTimestamp == -1) continue; // If timestamp was set then the list was already sent previously if (customTimestamp != 0) { // List hasn't changed -- do nothing if (customTimestamp >= mLastChange) continue; // Too many clients: we want the updates to be infrequent if (!mInstantUpdates && customTimestamp + 4000 > mTime) continue; } // Create the server list packet if (buffer == null) { buffer = Buffer.Create(); BinaryWriter writer = buffer.BeginPacket(Packet.ResponseServerList); mList.WriteTo(writer); buffer.EndPacket(); } tc.SendTcpPacket(buffer); tc.data = mTime; } if (buffer != null) { buffer.Recycle(); buffer = null; } Thread.Sleep(1); } }
/// <summary> /// Send the outgoing buffer to the specified player. /// </summary> void EndSend(TcpProtocol tc) { mBuffer.EndPacket(); tc.SendTcpPacket(mBuffer); mBuffer.Recycle(); mBuffer = null; }
/// <summary> /// Send periodic updates. /// </summary> void ThreadFunction() { mInternal = new IPEndPoint(Tools.localAddress, mGameServer.tcpPort); mExternal = new IPEndPoint(Tools.externalAddress, mGameServer.tcpPort); for (; ;) { long time = DateTime.UtcNow.Ticks / 10000; if (mShutdown) { mTcp.Disconnect(); mThread = null; #if STANDALONE Tools.Print("TcpLobbyLink shut down"); #endif break; } #if !STANDALONE if (TNManager.isPaused) { Thread.Sleep(500); continue; } #endif Buffer buffer; // Try to establish a connection if (mGameServer != null && !mTcp.isConnected && !mTcp.isTryingToConnect && mNextConnect < time) { #if STANDALONE Tools.Print("TcpLobbyLink is connecting to " + mRemoteAddress + "..."); #endif mUpdateNeeded = true; mNextConnect = time + 15000; mTcp.Connect(mRemoteAddress); } while (mTcp.ReceivePacket(out buffer)) { BinaryReader reader = buffer.BeginReading(); Packet response = (Packet)reader.ReadByte(); if (mTcp.stage == TcpProtocol.Stage.Verifying) { if (mTcp.VerifyResponseID(response, reader)) { mTimeDifference = reader.ReadInt64() - (System.DateTime.UtcNow.Ticks / 10000); mWasConnected = true; #if STANDALONE Tools.Print("TcpLobbyLink connection established"); #endif } else { #if STANDALONE Tools.Print("TcpLobbyLink Error: Protocol version mismatch"); #endif mThread = null; return; } } else if (response == Packet.RequestPing) { } #if STANDALONE else if (response == Packet.Error) { Tools.Print("TcpLobbyLink Error: " + reader.ReadString()); } else if (response == Packet.Disconnect) { Tools.Print("TcpLobbyLink disconnected"); } else { Tools.Print("TcpLobbyLink can't handle this packet: " + response); } #endif buffer.Recycle(); } // Automatically try to re-establish a connection on disconnect if (mWasConnected && !mTcp.isConnected && !mTcp.isTryingToConnect) { mNextConnect = time + 5000; mWasConnected = false; } else if (mGameServer != null && mTcp.isConnected && (mUpdateNeeded || mNextSend < time)) { mUpdateNeeded = false; mNextSend = time + 5000; Buffer buff = Buffer.Create(); BinaryWriter writer = buff.BeginPacket(Packet.RequestAddServer); writer.Write(GameServer.gameID); writer.Write(mGameServer.name); writer.Write((short)mGameServer.playerCount); Tools.Serialize(writer, mInternal); Tools.Serialize(writer, mExternal); buff.EndPacket(); mTcp.SendTcpPacket(buff); buff.Recycle(); } try { Thread.Sleep(10); } catch (System.Threading.ThreadInterruptedException) { return; } } }