/// <summary> /// Keep receiving incoming packets. /// </summary> void Update() { Buffer buffer; bool changed = false; long time = System.DateTime.UtcNow.Ticks / 10000; // Automatically try to connect and reconnect if not connected if (mRemoteAddress != null && mTcp.stage == TcpProtocol.Stage.NotConnected && mNextConnect < time) { mNextConnect = time + 5000; mTcp.Connect(mRemoteAddress); } // TCP-based lobby while (mTcp.ReceivePacket(out buffer)) { if (buffer.size > 0) { try { BinaryReader reader = buffer.BeginReading(); Packet response = (Packet)reader.ReadByte(); if (response == Packet.ResponseID) { if (mTcp.VerifyResponseID(response, reader)) { isActive = true; // Request the server list -- with TCP this only needs to be done once mTcp.BeginSend(Packet.RequestServerList).Write(GameServer.gameID); mTcp.EndSend(); } } else if (response == Packet.Disconnect) { knownServers.Clear(); isActive = false; changed = true; errorString = ""; } else if (response == Packet.ResponseServerList) { lock (knownServers.list) knownServers.list.Clear(); knownServers.ReadFrom(reader, time); changed = true; errorString = ""; } else if (response == Packet.Error) { errorString = reader.ReadString(); Debug.LogWarning(errorString); changed = true; } } catch (System.Exception ex) { errorString = ex.Message; Debug.LogWarning(ex.Message); mTcp.Close(false); } } buffer.Recycle(); } // Trigger the listener callback if (changed && onChange != null) { onChange(); } }
/// <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; break; } Buffer buffer; // Try to establish a connection if (mGameServer != null && !mTcp.isConnected && mNextConnect < time) { 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; } else { #if STANDALONE Console.WriteLine("TcpLobbyLink: Protocol version mismatch"); #endif mThread = null; return; } } else if (response == Packet.Error) { // Automatically try to re-establish a connection on disconnect mNextConnect = mWasConnected ? 0 : time + 30000; #if STANDALONE Console.WriteLine("TcpLobbyLink: " + reader.ReadString()); #endif } #if STANDALONE else { Console.WriteLine("TcpLobbyLink can't handle this packet: " + response); } #endif buffer.Recycle(); } if (mGameServer != null && mTcp.isConnected) { BinaryWriter writer = mTcp.BeginSend(Packet.RequestAddServer); writer.Write(GameServer.gameID); writer.Write(mGameServer.name); writer.Write((short)mGameServer.playerCount); Tools.Serialize(writer, mInternal); Tools.Serialize(writer, mExternal); mTcp.EndSend(); mGameServer = null; } Thread.Sleep(10); } }