/// <summary> /// Process an incoming packet. /// </summary> bool ProcessPacket(Buffer buffer, IPEndPoint ip) { BinaryReader reader = buffer.BeginReading(); Packet request = (Packet)reader.ReadByte(); switch (request) { case Packet.RequestPing: { BeginSend(Packet.ResponsePing); EndSend(ip); break; } case Packet.RequestAddServer: { if (reader.ReadUInt16() != GameServer.gameID) { return(false); } ServerList.Entry ent = new ServerList.Entry(); ent.ReadFrom(reader); if (ent.externalAddress.Address.Equals(IPAddress.None) || ent.externalAddress.Address.Equals(IPAddress.IPv6None)) { ent.externalAddress = ip; } mList.Add(ent, mTime); #if STANDALONE Tools.Print(ip + " added a server (" + ent.internalAddress + ", " + ent.externalAddress + ")"); #endif return(true); } case Packet.RequestRemoveServer: { if (reader.ReadUInt16() != GameServer.gameID) { return(false); } IPEndPoint internalAddress, externalAddress; Tools.Serialize(reader, out internalAddress); Tools.Serialize(reader, out externalAddress); if (externalAddress.Address.Equals(IPAddress.None) || externalAddress.Address.Equals(IPAddress.IPv6None)) { externalAddress = ip; } RemoveServer(internalAddress, externalAddress); #if STANDALONE Tools.Print(ip + " removed a server (" + internalAddress + ", " + externalAddress + ")"); #endif return(true); } case Packet.RequestServerList: { if (reader.ReadUInt16() != GameServer.gameID) { return(false); } mList.WriteTo(BeginSend(Packet.ResponseServerList)); EndSend(ip); return(true); } } return(false); }
/// <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 || response == Packet.ResponsePing) { } #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) { if (mUpdateNeeded) { mUpdateNeeded = false; mNextPing = time + 5000; Buffer buff = Buffer.Create(); var 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(); } else if (mNextPing < time) { mNextPing = time + 5000; Buffer buff = Buffer.Create(); buff.BeginPacket(Packet.RequestPing); buff.EndPacket(); mTcp.SendTcpPacket(buff); buff.Recycle(); } } try { Thread.Sleep(10); } catch (System.Threading.ThreadInterruptedException) { return; } } }
/// <summary> /// Asset Bundle-like export, except using DataNode's deep serialization. /// </summary> static public void ExportAssets(DataNode.SaveType type, string path) { EditorUtility.DisplayCancelableProgressBar("Working", "Collecting references...", 0f); ComponentSerialization.ClearReferences(); var objects = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); var components = new System.Collections.Generic.HashSet <string>(); foreach (var obj in objects) { if (obj is MonoScript) { var s = obj.name; if (!components.Contains(s)) { components.Add(s); } continue; } var go = obj as GameObject; if (go) { go.CollectReferencedPrefabs(true); var comps = go.GetComponentsInChildren <MonoBehaviour>(true); foreach (var comp in comps) { var t = comp.GetType().ToString(); if (!components.Contains(t)) { components.Add(t); } } } else { ComponentSerialization.AddReference(obj); } } EditorUtility.DisplayCancelableProgressBar("Working", "Copying scripts...", 0f); var dir = Tools.GetDirectoryFromPath(path); // Copy the scripts foreach (var c in components) { var fn = c + ".cs"; var p = Tools.FindFile(Application.dataPath, fn); if (!string.IsNullOrEmpty(p)) { System.IO.File.Copy(p, System.IO.Path.Combine(dir, fn), true); } } EditorUtility.DisplayCancelableProgressBar("Working", "Creating a DataNode...", 0f); foreach (var pair in ComponentSerialization.referencedPrefabs) { pair.Value.CollectReferencedResources(); } var data = ComponentSerialization.SerializeBundle(); if (data != null && data.children.size > 0) { Save(data, path, type); } else { Debug.LogWarning("No assets found to serialize"); } ComponentSerialization.ClearReferences(); EditorUtility.ClearProgressBar(); }