コード例 #1
0
ファイル: JNet.cs プロジェクト: Epicguru/ProjectB
        /// <summary>
        /// Registers a prefab to the network system, allowing it to be replicated accross clients.
        /// </summary>
        /// <param name="prefab"></param>
        public static void RegisterPrefab(NetObject prefab)
        {
            if (prefab == null)
            {
                Error("Tried to register null prefab.");
                return;
            }

            if (prefab.HasNetID)
            {
                Error("Tried to register net prefab that is actually world instance. (already spawned and reigistered)");
                return;
            }

            if (prefab.IsRegisteredPrefab)
            {
                Error(string.Format("Tried to register net prefab '{0}' twice.", prefab));
                return;
            }

            if (MaxPrefabID > ushort.MaxValue)
            {
                Error("Cannot register more than 65534 network prefabs. Nice work getting that many prefabs though.");
                return;
            }

            ushort id = (ushort)MaxPrefabID;

            MaxPrefabID++;

            prefab.PrefabID           = id;
            prefab.IsRegisteredPrefab = true;

            Prefabs[id] = prefab;
        }
コード例 #2
0
ファイル: NetRef.cs プロジェクト: Epicguru/ProjectB
        public bool Update()
        {
            if (JNet.IsServer)
            {
                return(NetDirty);
            }

            if (objID == 0)
            {
                if (obj != null)
                {
                    obj = null;
                    UponObjectUpdate?.Invoke(null);
                }
            }
            else
            {
                if (obj == null || obj.NetID != objID)
                {
                    var found = JNet.GetObject(objID);
                    if (found != null)
                    {
                        obj = found;
                        UponObjectUpdate?.Invoke(obj);
                    }
                }
            }

            return(false);
        }
コード例 #3
0
        private void ProcessDespawn(NetIncomingMessage msg)
        {
            // Do not process if the server is active.
            if (JNet.IsServer)
            {
                return;
            }

            // Net ID.
            ushort netID = msg.ReadUInt16();

            if (netID == 0)
            {
                JNet.Error("Client was instructed to despawn object with netID 0, server error or corruption?");
                return;
            }

            NetObject obj = JNet.Tracker.TrackedObjects[netID];

            if (obj == null)
            {
                // Hmmm...
                JNet.Error(string.Format("Client was instructed to depsnaw object of NetID {0}, but that object was not found. Already destroyed?", netID));
                return;
            }

            // Destroy the object and unregister it.
            JNet.Tracker.Unregister(obj);

            // Destroy.
            GameObject.Destroy(obj.gameObject);
        }
コード例 #4
0
ファイル: JNet.cs プロジェクト: Epicguru/ProjectB
        internal static void Despawn(NetObject obj)
        {
            if (!IsServer)
            {
                return;
            }

            if (Tracker == null)
            {
                return;
            }

            if (obj.OwnerID != 0)
            {
                Server.GetClient(obj.OwnerID, true)?.RemoveObj(obj);
            }

            // Send a message to all clients to despawn this object.
            NetOutgoingMessage msg = Server.CreateMessage(JDataType.DESPAWN, 16);

            // Instance Net ID.
            msg.Write(obj.NetID);

            // Send to all except local.
            Server.SendToAllExcept(Client?.ServerConnection, msg, NetDeliveryMethod.ReliableOrdered, 0);

            Tracker.Unregister(obj);
        }
コード例 #5
0
        private void LateUpdate()
        {
            if (!updateParent)
            {
                return;
            }

            updateParent = false;

            if (ParentNetID != 0 && ParentNodeID != 0)
            {
                // Try to find the object.
                NetObject obj = JNet.GetObject(ParentNetID);
                if (obj == null)
                {
                    JNet.Error($"Failed to find net object of id {ParentNetID} to sync the transform of this object.");
                    return;
                }

                var node = obj.GetParentNode(ParentNodeID);
                if (node == null)
                {
                    JNet.Error($"Failed to find net object of id {ParentNetID} parent node ({ParentNodeID}) to sync the transform of this object.");
                    return;
                }

                this.transform.SetParent(node.GetTransform(), true);
            }
            else
            {
                this.transform.SetParent(null, true);
            }
        }
コード例 #6
0
ファイル: JNet.cs プロジェクト: Epicguru/ProjectB
        /// <summary>
        /// Makes a spawned object be registered to the networking system, causing it to be
        /// instantiated on all connected clients.
        /// Note that this does NOT instantiate the object on the server. The object should already be instantiated,
        /// and this method just registers it. In other words, do not pass a prefab to this method.
        /// </summary>
        /// <param name="obj">The net object to spawn.</param>
        public static void Spawn(NetObject obj, NetConnection owner = null)
        {
            if (!Initialized)
            {
                Error("JNet not initialized, cannot spawn object. Call JNet.Init()");
                return;
            }

            if (!IsServer)
            {
                Error("Network spawning should only called on the server.");
            }

            if (obj == null)
            {
                Error("Null object was attempted to be spawned using JNet.Spawn()");
                return;
            }

            if (obj.HasNetID)
            {
                Error(string.Format("Object {0} is already networked registered.", obj.ToString()));
                return;
            }

            if (!obj.IsSceneLoaded && !obj.HasPrefabID)
            {
                Error(string.Format("Object '{0}' does not have a prefab ID, register it's prefab before spawning by calling JNet.RegisterPrefab().", obj));
                return;
            }

            // Set owner.
            if (owner != null)
            {
                obj.OwnerID = owner.RemoteUniqueIdentifier;
                Server.GetClient(owner)?.AddObj(obj);
            }
            else
            {
                obj.OwnerID = 0; // NOTE: Can remote unique identifier actually ever be zero? I have no idea.
            }

            Tracker.Register(obj);

            // Send a message to all clients to spawn this object.
            NetOutgoingMessage msg = Server.CreateMessage(JDataType.SPAWN, 16);

            // Prefab ID.
            msg.Write(obj.PrefabID);

            // Instance ID.
            msg.Write(obj.NetID);

            // Write all behaviours and owner, regardless of net dirty state.
            obj.Serialize(msg, true);

            // Send to all except local.
            Server.SendToAllExcept(Server.LocalClientConnection, msg, NetDeliveryMethod.ReliableOrdered, 0);
        }
コード例 #7
0
ファイル: MessageUtils.cs プロジェクト: Epicguru/ProjectB
 public static void WriteNetObject(this NetOutgoingMessage msg, NetObject obj)
 {
     if (obj == null)
     {
         msg.Write((ushort)0);
     }
     else
     {
         msg.Write(obj.NetID);
     }
 }
コード例 #8
0
ファイル: RemoteClient.cs プロジェクト: Epicguru/ProjectB
        internal void RemoveObj(NetObject o)
        {
            if (o == null)
            {
                return;
            }

            if (OwnedObjectsList.Contains(o))
            {
                OwnedObjectsList.Remove(o);
            }
        }
コード例 #9
0
ファイル: RemoteClient.cs プロジェクト: Epicguru/ProjectB
        internal void AddObj(NetObject o)
        {
            if (o == null)
            {
                return;
            }

            if (OwnedObjectsList.Contains(o))
            {
                return;
            }

            OwnedObjectsList.Add(o);
        }
コード例 #10
0
        private void ProcessSpawnAll(NetIncomingMessage msg)
        {
            int objectCount          = msg.ReadInt32();
            int expectedSceneObjects = JNet.EnableSceneObjectNetworking ? JNet.TrackedObjectCount : 0;

            JNet.Log($"Recieved {objectCount} objects from the server.");

            for (int i = 0; i < objectCount; i++)
            {
                ushort prefabID = msg.ReadUInt16();
                ushort netID    = msg.ReadUInt16();

                // Get the prefab for that ID...
                NetObject prefab = JNet.GetPrefab(prefabID);
                if (prefab == null && netID > expectedSceneObjects)
                {
                    JNet.Error("Failed to find prefab for ID " + prefabID + ", object not spawned on client. Desync incoming!");
                    return;
                }

                if (netID == 0)
                {
                    JNet.Error("Client got spawn message with instance net ID of zero, server error or corruption? Object not spawned, prefab id was " + prefabID + " (" + prefab + ").");
                    return;
                }

                // Instantiate the game object, if not scene object.
                NetObject no;
                if (prefab != null)
                {
                    no = GameObject.Instantiate(prefab);
                }
                else
                {
                    no = JNet.GetObject(netID);
                }

                // We need to register the object to the system, if not scene object.
                if (prefab != null)
                {
                    JNet.Tracker.Register(no, netID);
                }

                // Read all the behaviours.
                no.Deserialize(msg, true);
            }

            UponWorldRecieved?.Invoke();
        }
コード例 #11
0
ファイル: NetRef.cs プロジェクト: Epicguru/ProjectB
        public void Deserialize(NetIncomingMessage msg, bool first)
        {
            ushort id = msg.ReadUInt16();

            if (objID != id)
            {
                this.objID = id;
                var found = JNet.GetObject(id);
                if (found != obj || first)
                {
                    obj = found;
                    UponObjectUpdate?.Invoke(obj);
                }
            }
        }
コード例 #12
0
ファイル: NetRef.cs プロジェクト: Epicguru/ProjectB
        public void Set(NetObject value)
        {
            if (!JNet.IsServer)
            {
                JNet.Error("Cannot set value of net reference when not on server.");
                return;
            }

            if (obj == value)
            {
                return;
            }

            obj   = value;
            objID = value?.NetID ?? 0;

            NetDirty = true;
        }
コード例 #13
0
ファイル: JNet.cs プロジェクト: Epicguru/ProjectB
        /// <summary>
        /// Sets the OwnerID of the target NetObject to the specified net connection.
        /// </summary>
        /// <param name="obj">The target NetObject. <see cref="JNet.Spawn"/> should have already been called for this object.</param>
        /// <param name="owner">The new owner for this object. Can be null to remove owner.</param>
        public static void SetOwner(NetObject obj, NetConnection owner)
        {
            if (!JNet.IsServer)
            {
                Error("Not on server, cannot set owner.");
                return;
            }

            if (obj == null)
            {
                return;
            }

            long id = 0;

            if (owner != null)
            {
                id = owner.RemoteUniqueIdentifier;
            }

            if (obj.OwnerID != id)
            {
                var client = Server.GetClient(obj.OwnerID);
                if (obj.OwnerID != 0)
                {
                    client?.RemoveObj(obj);
                }

                obj.OwnerID = id;
                if (id != 0)
                {
                    client?.AddObj(obj);
                }

                // Send message.
                NetOutgoingMessage msg = Server.CreateMessage(JDataType.SET_OWNER, 12);
                msg.Write(obj.NetID);
                msg.Write(obj.OwnerID);
                Server.SendToAllExcept(Server.LocalClientConnection, msg, NetDeliveryMethod.ReliableOrdered, 0);
            }
        }
コード例 #14
0
        private void ProcessSpawn(NetIncomingMessage msg)
        {
            // Do not process if the server is active.
            if (JNet.IsServer)
            {
                return;
            }

            // Prefab ID.
            ushort prefabID = msg.ReadUInt16();

            // Net ID.
            ushort netID = msg.ReadUInt16();

            // Get the prefab for that ID...
            NetObject prefab = JNet.GetPrefab(prefabID);

            if (prefab == null)
            {
                JNet.Error("Failed to find prefab for ID " + prefabID + ", object not spawned on client. Desync incoming!");
                return;
            }

            if (netID == 0)
            {
                JNet.Error("Client got spawn message with instance net ID of zero, server error or corruption? Object not spawned, prefab id was " + prefabID + " (" + prefab + ").");
                return;
            }

            // Instantiate the game object.
            NetObject no = GameObject.Instantiate(prefab);

            // We need to register the object to the system.
            JNet.Tracker.Register(no, netID);

            // Read all the behaviours.
            no.Deserialize(msg, true);
        }
コード例 #15
0
        public void Unregister(NetObject obj)
        {
            if (obj == null)
                return;

            if (!obj.HasNetID)
                return;

            ushort id = obj.NetID;

            NetObject current = TrackedObjects[id];
            if(current != obj)
            {
                JNet.Error("Current is not the object that is about to be unregistered.");
                return;
            }

            TrackedObjects[id] = null;
            obj.NetID = 0;
            ObjectCount--;

            ActiveObjects.Remove(obj);
        }
コード例 #16
0
        public void Register(NetObject obj, ushort overrideNetID = 0)
        {
            if (obj == null)
            {
                JNet.Error("Null object to register.");
                return;
            }

            if (obj.HasNetID)
            {
                JNet.Error("Object already registered!");
                return;
            }

            ushort id = 0;
            if(overrideNetID == 0)
            {
                int maxID = TrackedObjects.Length;

                for (int i = 0; i < maxID + 1; i++)
                {
                    id = CurrentTopID;

                    CurrentTopID++;
                    if (CurrentTopID >= maxID)
                    {
                        CurrentTopID = 1;
                    }

                    if (TrackedObjects[id] == null)
                    {
                        break;
                    }
                    else
                    {
                        id = 0;
                    }
                }
            }
            else
            {
                id = overrideNetID;
            }            

            if(id == 0)
            {
                JNet.Error("Cannot register new net object to be tracked, out of ID's! Too many objects are already tracked! Max object count: " + MAX_TRACKED_OBJECTS);
                return;
            }

            obj.NetID = id;
            obj.UpdateBehaviourList();

            if(TrackedObjects[id] != null)
            {
                JNet.Error("Overriding object in register, possibly from client. Override netID: " + overrideNetID);
            }

            TrackedObjects[id] = obj;
            ObjectCount++;

            ActiveObjects.Add(obj);
        }