public static List <Packet> GenerateScenePackets() { //Will generate all the packets required to sync scenes for users. Useful for right when the server begins. //Only generates packets for NetworkObject's that are included inside of NetworkData's prefab domains. List <Packet> objPackets = new List <Packet>(); foreach (NetworkObject netObj in NetworkObject.allNetObjs) { if (netObj.prefabID == -1 || netObj.prefabDomainID == -1) { continue; //It isn't registered. } GameObjectInstantiateData gOID = new GameObjectInstantiateData(); gOID.netObjID = netObj.networkID; gOID.position = new SerializableVector(netObj.transform.position); gOID.rotation = new SerializableQuaternion(netObj.transform.rotation); gOID.prefabID = netObj.prefabID; gOID.prefabDomainID = netObj.prefabDomainID; Packet p = new Packet(Packet.pType.gOInstantiate, Packet.sendType.nonbuffered, gOID); objPackets.Add(p); } return(objPackets); }
public static GameObjectInstantiateData DeserializeGOID(byte[] givenBytes) { List <byte> gOIDBytes = new List <byte>(); gOIDBytes.AddRange(givenBytes); GameObjectInstantiateData gOID = new GameObjectInstantiateData(); int intIndex = 0; //Prefab info gOID.prefabDomainID = System.BitConverter.ToInt32(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; gOID.prefabID = System.BitConverter.ToInt32(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; //Vector3 position SerializableVector vec = new SerializableVector(0, 0, 0); vec.x = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; vec.y = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; vec.z = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; gOID.position = vec; //Quaternion rotation SerializableQuaternion rot = new SerializableQuaternion(0, 0, 0, 0); rot.x = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; rot.y = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; rot.z = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; rot.w = System.BitConverter.ToSingle(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; gOID.rotation = rot; //NetObjID gOID.netObjID = System.BitConverter.ToInt32(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; //isShared/doImmediate booleans gOID.isShared = System.BitConverter.ToBoolean(gOIDBytes.GetRange(intIndex, 1).ToArray(), 0); intIndex += 1; gOID.doImmediate = System.BitConverter.ToBoolean(gOIDBytes.GetRange(intIndex, 1).ToArray(), 0); intIndex += 1; //NetworkFieldDefaults List List <NetworkFieldPacket> nFPs = new List <NetworkFieldPacket>(); int nFPCount = System.BitConverter.ToInt32(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; for (int i = 0; i < nFPCount; i++) { int serializeLength = System.BitConverter.ToInt32(gOIDBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4; NetworkFieldPacket netFieldPacket = DeserializeNetworkFieldPacket(gOIDBytes.GetRange(intIndex, serializeLength).ToArray()); intIndex += serializeLength; } return(gOID); }
//GOID Serialization Data - Total Minimum Bytes: 42 bytes // - PrefabDomainID int32, 4 bytes // - PrefabID int32, 4 bytes // - Position sVec, 12 bytes // - Rotation sQuat, 16 bytes // - NetObjID int32, 4 bytes - consider just using relatedNetObjID instead // - isShared bool, 1 byte // - doImmediate bool, 1 byte // - NetFieldDefaults List // - List Element Count int32, 4 bytes // - Byte array length of element int32, 4 bytes // - NetFieldPacket BinaryFormattered, ? bytes public static byte[] SerializeGOID(GameObjectInstantiateData gOID) { List <byte> objectAsBytes = new List <byte>(); //Basic Fields byte[] prefabDomainID = System.BitConverter.GetBytes(gOID.prefabDomainID); objectAsBytes.AddRange(prefabDomainID); byte[] prefabID = System.BitConverter.GetBytes(gOID.prefabID); objectAsBytes.AddRange(prefabID); List <byte> positionBytes = new List <byte>(); positionBytes.AddRange(System.BitConverter.GetBytes(gOID.position.x)); positionBytes.AddRange(System.BitConverter.GetBytes(gOID.position.y)); positionBytes.AddRange(System.BitConverter.GetBytes(gOID.position.z)); objectAsBytes.AddRange(positionBytes); List <byte> rotationBytes = new List <byte>(); rotationBytes.AddRange(System.BitConverter.GetBytes(gOID.rotation.x)); rotationBytes.AddRange(System.BitConverter.GetBytes(gOID.rotation.y)); rotationBytes.AddRange(System.BitConverter.GetBytes(gOID.rotation.z)); rotationBytes.AddRange(System.BitConverter.GetBytes(gOID.rotation.w)); objectAsBytes.AddRange(rotationBytes); byte[] netObjID = System.BitConverter.GetBytes(gOID.netObjID); objectAsBytes.AddRange(netObjID); objectAsBytes.AddRange(System.BitConverter.GetBytes(gOID.isShared)); objectAsBytes.AddRange(System.BitConverter.GetBytes(gOID.doImmediate)); //networkFieldPacket List //Amount of field defaults. if (gOID.fieldDefaults == null) { gOID.fieldDefaults = new List <NetworkFieldPacket>(); } objectAsBytes.AddRange(System.BitConverter.GetBytes(gOID.fieldDefaults.Count)); foreach (NetworkFieldPacket nFP in gOID.fieldDefaults) { byte[] serializedField = SerializeNetworkFieldPacket(nFP); objectAsBytes.AddRange(System.BitConverter.GetBytes(serializedField.Length)); //Length of serialized Network Field Packet objectAsBytes.AddRange(serializedField); } return(objectAsBytes.ToArray()); }
public static GameObject NetInstantiate(int prefabDomain, int prefabID, Vector3 position, Quaternion rotation, Packet.sendType sT = Packet.sendType.buffered, bool isSharedObject = false, List <NetworkFieldPacket> fieldDefaults = null) { int netObjID = GenerateNetworkObjectID(); if (NetTools.IsMultiplayerGame()) { if (!NetTools.isServer && NetworkData.instance.networkPrefabList[prefabDomain].prefabList[prefabID].serverInstantiateOnly) { #if UNITY_EDITOR Debug.LogWarning("Tried to make server authority only object: domain: " + prefabDomain + ", id: " + prefabID); #endif return(null); //If it is server only, and you aren't the server, don't do it. } SerializableVector finalVector = new SerializableVector(position); SerializableQuaternion finalQuat = new SerializableQuaternion(rotation); GameObjectInstantiateData gOID = new GameObjectInstantiateData(); gOID.position = finalVector; gOID.rotation = finalQuat; gOID.prefabDomainID = prefabDomain; gOID.prefabID = prefabID; gOID.isShared = isSharedObject; gOID.netObjID = netObjID; gOID.fieldDefaults = fieldDefaults; Packet p = new Packet(Packet.pType.gOInstantiate, Packet.sendType.buffered, ENSSerialization.SerializeGOID(gOID)); p.tag = NetworkData.instance.TagIDToTagName(NetworkData.instance.networkPrefabList[prefabDomain].defaultPacketTagID); //if(sT == Packet.sendType.buffered && isServer) //{ // NetServer.serverInstance.bufferedPackets.Add(p); //} NetClient.instanceClient.SendPacket(p); } //Try to get a pooled one first. GameObject g = NetworkData.instance.RequestPooledObject(prefabDomain, prefabID); if (g == null) //If there is no pooled remaining make a new one. { g = Instantiate(NetworkData.instance.networkPrefabList[prefabDomain].prefabList[prefabID].prefab, position, rotation); } else { //If pooled apply required position/rotation g.transform.position = position; g.transform.rotation = rotation; } NetworkObject nObj = g.GetComponent <NetworkObject>(); if (nObj == null) { nObj = g.AddComponent <NetworkObject>(); } nObj.ownerID = NetTools.clientID; nObj.prefabDomainID = prefabDomain; nObj.prefabID = prefabID; nObj.networkID = netObjID; nObj.sharedObject = isSharedObject; nObj.detectNetworkStarts = NetworkData.instance.networkPrefabList[prefabDomain].detectNetworkStarts; nObj.Initialize(); //nObj.DoRpcFieldInitialization(); if (nObj.onNetworkStart != null) { nObj.onNetworkStart.Invoke(); } //nObj.initialized = true; if (fieldDefaults != null) { foreach (NetworkFieldPacket nFP in fieldDefaults) { nFP.networkObjID = netObjID; nObj.SetFieldLocal(nFP.fieldName, nFP.data.ToObject()); //Instead just update it in UnityPacketHandler for everyone else, preventing extra packets and data from being send and lagging. //nObj.UpdateField(nFP.fieldName, nFP.data.ToObject(), nFP.immediateOnSelf); } } return(g); }
public void ExecutePacket(Packet curPacket) { if (curPacket.packetType == Packet.pType.gOInstantiate) //It gets instantiated NetTools. { NetworkObject nObj = null; GameObjectInstantiateData gOID = ENSSerialization.DeserializeGOID(curPacket.packetData); //Debug.Log(NetTools.clientID + ", " + curPacket.packetOwnerID); if (NetTools.clientID != curPacket.packetOwnerID || NetworkObject.NetObjFromNetID(gOID.netObjID) == null) { if (!curPacket.serverAuthority && NetworkData.instance.networkPrefabList[gOID.prefabDomainID].prefabList[gOID.prefabID].serverInstantiateOnly) { return; //If it is server only, and you aren't the server, don't do it. } GameObject g = NetworkData.instance.RequestPooledObject(gOID.prefabDomainID, gOID.prefabID); if (g == null) //If a pooled object couldn't be found, make a new one. { try { g = Instantiate(NetworkData.instance.networkPrefabList[gOID.prefabDomainID].prefabList[gOID.prefabID].prefab, gOID.position.ToVec3(), gOID.rotation.ToQuaternion()); } catch (System.Exception e) { Debug.Log("Error NetInstantiating: domainID: " + gOID.prefabDomainID + ", prefabID: " + gOID.prefabID + e); return; } } else { //If pooled apply required position/rotation/etc. g.transform.position = gOID.position.ToVec3(); g.transform.rotation = gOID.rotation.ToQuaternion(); } nObj = g.GetComponent <NetworkObject>(); if (nObj == null) { nObj = g.AddComponent <NetworkObject>(); } foreach (NetworkField defaultField in NetworkData.instance.networkPrefabList[gOID.prefabDomainID].defaultFields) { nObj.fields.Add(defaultField.Clone()); } foreach (RPC defaultRPC in NetworkData.instance.networkPrefabList[gOID.prefabDomainID].defaultRpcs) { nObj.rpcs.Add(defaultRPC.Clone()); } nObj.ownerID = curPacket.packetOwnerID; nObj.prefabDomainID = gOID.prefabDomainID; nObj.prefabID = gOID.prefabID; nObj.networkID = gOID.netObjID; nObj.sharedObject = gOID.isShared; nObj.Initialize(); //nObj.DoRpcFieldInitialization(); if (nObj.onNetworkStart != null) { nObj.onNetworkStart.Invoke(); } if (gOID.fieldDefaults != null) { foreach (NetworkFieldPacket nFP in gOID.fieldDefaults) { nFP.networkObjID = gOID.netObjID; //Debug.Log(nFP.data); nObj.SetFieldLocal(nFP.fieldName, nFP.data.ToObject()); } } } } else if (curPacket.packetType == Packet.pType.gODestroy) { //Debug.Log(curPacket.jsonData); //Debug.Log(curPacket.GetPacketData()); //int netID = ENSSerialization.DeserializeInt(curPacket.packetData); NetworkObject found = NetworkObject.NetObjFromNetID(curPacket.relatesToNetObjID); if (found != null && (found.ownerID == curPacket.packetOwnerID || curPacket.serverAuthority || found.sharedObject)) { if (disableBeforeDestroy) { if (NetworkData.instance.ResetPooledObject(found) == false) { destroyQueue.Add(found.gameObject); } } else { if (NetworkData.instance.ResetPooledObject(found) == false) { Destroy(found.gameObject); } } if (NetTools.isServer && System.BitConverter.ToBoolean(curPacket.packetData, 0)) //Check NetTools.NetDestroy but basically it is cullRelatedPackets. { NetTools.CullPacketsByNetworkID(curPacket.relatesToNetObjID); } } else if (found == null) { Debug.LogWarning("Couldn't find NetworkObject of ID: " + curPacket.relatesToNetObjID); } } else if (curPacket.packetType == Packet.pType.multiPacket) { //Debug.Log("Recieved buffered packets."); List <byte[]> packetByteInfo = curPacket.GetPacketData <PacketListPacket>().packets; lock (packetQueue) { foreach (byte[] packetByte in packetByteInfo) { packetQueue.Add(ENSSerialization.DeserializePacket(packetByte)); } } syncingBuffered = true; } else if (curPacket.packetType == Packet.pType.loginInfo) { //Debug.Log("Login Info Packet Recieved."); PlayerLoginData pLD = curPacket.GetPacketData <PlayerLoginData>(); NetTools.clientID = pLD.clientID;//System.BitConverter.ToInt16(curPacket.packetData,0); NetClient.instanceClient.clientID = NetTools.clientID; NetClient.instanceClient.serversSteamID = pLD.serverSteamID; if (NetTools.isServer) { NetServer.serverInstance.myConnection = NetServer.serverInstance.GetPlayerByID(NetTools.clientID); } NetTools.onJoinServer.Invoke(); //print("Test"); } else if (curPacket.packetType == Packet.pType.netVarEdit) { NetworkFieldPacket nFP = ENSSerialization.DeserializeNetworkFieldPacket(curPacket.packetData); NetworkObject netObj = NetworkObject.NetObjFromNetID(nFP.networkObjID); if (netObj == null) { return; } if (netObj.initialized == false) { //netObj.queuedNetworkPackets.Add(curPacket); return; } if ((netObj.ownerID != curPacket.packetOwnerID && !curPacket.serverAuthority && !netObj.sharedObject) || (curPacket.packetOwnerID == NetTools.clientID && nFP.immediateOnSelf)) { return; } //Debug.Log("Seting NetVarEdit."); try { netObj.SetFieldLocal(nFP.fieldName, nFP.data.ToObject()); } catch (System.Exception e) { Debug.LogError(e); } } else if (curPacket.packetType == Packet.pType.rpc) { //Debug.Log(curPacket.jsonData); RPCPacketData rPD = ENSSerialization.DeserializeRPCPacketData(curPacket.packetData); NetworkObject nObj = NetworkObject.NetObjFromNetID(rPD.networkObjectID); if (nObj == null || (nObj.rpcs[rPD.rpcIndex].serverAuthorityRequired && !curPacket.serverAuthority) || (nObj.ownerID != curPacket.packetOwnerID && !nObj.sharedObject && !curPacket.serverAuthority)) { return; //Means only server can run it. } nObj.rpcs[rPD.rpcIndex].InvokeRPC(rPD.ReturnArgs()); } else if (curPacket.packetType == Packet.pType.connectionPacket) { if (!curPacket.serverAuthority && curPacket.packetOwnerID != -1) { return; //Prevents anyone from disconnecting everyone. } ConnectionPacket cP = ENSSerialization.DeserializeConnectionPacket(curPacket.packetData); if (cP.immediateDisconnect) { NetClient.instanceClient.DisconnectFromServer(); NetTools.onLeaveServer.Invoke(cP.reason); } } //else if (curPacket.packetType == Packet.pType.networkAuth && NetTools.isServer) //{ //} }