/// <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; }
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); }
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); }
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); }
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); } }
/// <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); }
public static void WriteNetObject(this NetOutgoingMessage msg, NetObject obj) { if (obj == null) { msg.Write((ushort)0); } else { msg.Write(obj.NetID); } }
internal void RemoveObj(NetObject o) { if (o == null) { return; } if (OwnedObjectsList.Contains(o)) { OwnedObjectsList.Remove(o); } }
internal void AddObj(NetObject o) { if (o == null) { return; } if (OwnedObjectsList.Contains(o)) { return; } OwnedObjectsList.Add(o); }
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(); }
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); } } }
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; }
/// <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); } }
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); }
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); }
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); }