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);
        }
        public static Packet DeserializePacket(byte[] bytes)
        {
            int         intIndex    = 0;
            List <byte> packetBytes = new List <byte>();

            packetBytes.AddRange(bytes);
            Packet packet = new Packet(Packet.pType.unassigned, Packet.sendType.nonbuffered, 0);

            //Basic Fields
            packet.packetSendType    = (Packet.sendType)packetBytes[intIndex]; intIndex++; // (Packet.sendType)System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            packet.packetType        = (Packet.pType)packetBytes[intIndex]; intIndex++;    // (Packet.pType)System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            packet.packetOwnerID     = System.BitConverter.ToInt16(packetBytes.GetRange(intIndex, 2).ToArray(), 0); intIndex += 2;
            packet.serverAuthority   = System.BitConverter.ToBoolean(packetBytes.GetRange(intIndex, 1).ToArray(), 0); intIndex += 1;
            packet.sendToAll         = System.BitConverter.ToBoolean(packetBytes.GetRange(intIndex, 1).ToArray(), 0); intIndex += 1;
            packet.relatesToNetObjID = System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            packet.tag = NetworkData.instance.TagIDToTagName(System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0)); intIndex += 4;

            //Vector3 packet position
            SerializableVector vec = new SerializableVector(0, 0, 0);

            vec.x = System.BitConverter.ToSingle(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            vec.y = System.BitConverter.ToSingle(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            vec.z = System.BitConverter.ToSingle(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            packet.packetPosition = vec;

            //Lists & Arrays
            List <int> usersToRecieve = new List <int>();
            int        arraySize      = System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;

            for (int i = 0; i < arraySize; i++)
            {
                usersToRecieve.Add(System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0));
                intIndex += 4;
            }
            packet.usersToRecieve = usersToRecieve;

            List <byte> packetInfo = new List <byte>();

            arraySize  = System.BitConverter.ToInt32(packetBytes.GetRange(intIndex, 4).ToArray(), 0); intIndex += 4;
            packetInfo = packetBytes.GetRange(intIndex, arraySize); intIndex += arraySize;

            packet.packetData = packetInfo.ToArray();

            return(packet);
        }
        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);
        }