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);
        }
Beispiel #5
0
        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)
            //{



            //}
        }