Beispiel #1
0
        private void Init()
        {
            if (doneInit)
            {
                return;
            }

            parameters = Animator.parameters;
            int count = parameters.Length;

            if (parameters.Length > 256)
            {
                count = 256;
                JNet.Error($"There are {parameters.Length} animator parameters on object {gameObject.name}, but only 256 can be networked. Some will not be syncronized. Why do you have that many anyway...");
            }

            paramDict = new Dictionary <string, byte>();
            for (int i = 0; i < count; i++)
            {
                var param = parameters[i];
                paramDict.Add(param.name.Trim(), (byte)i);
            }

            doneInit = true;
        }
        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);
            }
        }
Beispiel #3
0
        private object[] MsgToArgs(MethodInfo f, NetIncomingMessage msg)
        {
            MethodArgs.Clear();
            var parameters = f.GetParameters();

            if (Parsers.Count == 0)
            {
                AddAllParsers();
            }

            for (int i = 0; i < parameters.Length; i++)
            {
                var  parameter = parameters[i];
                Type type      = parameter.ParameterType;

                if (!Parsers.ContainsKey(type))
                {
                    JNet.Error($"Failed to find parser for incoming data type: {type.FullName}. Method invocation will probably fail.");
                    continue;
                }

                ReadWrite rw  = Parsers[type];
                object    arg = rw(true, msg, null, null);
                MethodArgs.Add(arg);
            }

            return(MethodArgs.ToArray());
        }
Beispiel #4
0
        private bool ArgsToMsg(MethodInfo f, object[] args, NetOutgoingMessage msg)
        {
            var parameters = f.GetParameters();

            if (parameters.Length != args.Length)
            {
                JNet.Error($"Expected {parameters.Length} parameters for remote invocation of {f.Name}, but only {args.Length} were supplied. Method will not be called.");
                return(false);
            }

            if (Parsers.Count == 0)
            {
                AddAllParsers();
            }

            for (int i = 0; i < parameters.Length; i++)
            {
                var param = parameters[i];

                Type type     = param.ParameterType;
                Type realType = args[i].GetType();

                if (!type.IsAssignableFrom(realType))
                {
                    JNet.Error($"Cannot automatically cast argument of type {realType.Name} to param {param.Name} of type {type.Name}.");
                    return(false);
                }

                ReadWrite rw = Parsers[type];

                rw(false, null, msg, args[i]);
            }

            return(true);
        }
Beispiel #5
0
        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);
        }
Beispiel #7
0
        protected override void ProcessStatusChanged(NetIncomingMessage msg, NetConnectionStatus status)
        {
            base.ProcessStatusChanged(msg, status);

            if (status == NetConnectionStatus.Connected)
            {
                Log("New client connected from {0}", msg.SenderConnection.RemoteEndPoint);

                // Send currently tracked objects, if not host.
                if (msg.SenderConnection != LocalClientConnection)
                {
                    SendAllObjects(msg.SenderConnection);
                }

                RemoteClient c = GetClient(msg);

                UponConnection?.Invoke(c);
            }

            if (status == NetConnectionStatus.Disconnected)
            {
                string reason = msg.ReadString();
                Log("Client has disconnected: {0}", reason);

                if (msg.SenderConnection == LocalClientConnection)
                {
                    Log("(Was local client)");
                    LocalClientConnection = null;
                }

                var client = GetClient(msg);
                if (client != null)
                {
                    // Remove net object from this client's ownership.
                    int loop = 0;
                    int max  = client.OwnedObjectsList.Count;
                    while (client.OwnedObjectsList.Count > 0)
                    {
                        JNet.SetOwner(client.OwnedObjectsList[0], null);

                        loop++;
                        if (loop > max)
                        {
                            JNet.Error($"Infinite loop?! Looped {loop}, expected {max}.");
                            break;
                        }
                    }

                    // Remove client.
                    this.Clients.Remove(client);
                    this.dictClients.Remove(client.ConnectionID);

                    UponDisconnection?.Invoke(client, reason);
                }
                else
                {
                    LogError("Client with Id {0} from {1} did not have a valid RemoteClient to remove.", msg.SenderConnection.RemoteUniqueIdentifier, msg.SenderConnection.RemoteEndPoint);
                }
            }
        }
Beispiel #8
0
 private void CheckDeliveryMethod()
 {
     if (RMCDeliveryMethod == NetDeliveryMethod.ReliableSequenced || RMCDeliveryMethod == NetDeliveryMethod.UnreliableSequenced)
     {
         NetDeliveryMethod replacement = RMCDeliveryMethod == NetDeliveryMethod.ReliableSequenced ? NetDeliveryMethod.ReliableOrdered : NetDeliveryMethod.Unreliable;
         JNet.Error($"Remote Delivery Method {RMCDeliveryMethod} is not allowed because it is sequenced. Using {replacement} instead.");
         RMCDeliveryMethod = replacement;
     }
 }
Beispiel #9
0
        /// <summary>
        /// Invokes the named method on the corresponding behaviour on the server.
        /// When called on the server, the target method will be instantly invoked.
        /// </summary>
        /// <param name="methodName">The name of the method to call. The method should have the [Cmd] attribute.</param>
        /// <param name="args">The arguments to pass to the method.</param>
        protected void InvokeCMD(string methodName, params object[] args)
        {
            if (!NetObject.HasNetID)
            {
                JNet.Error($"Cannot call Cmd {methodName} because the object that {GetType().FullName} is on is not net spawned.");
                return;
            }

            MethodInfo method = GetCmd(methodName);

            if (method == null)
            {
                JNet.Error($"Could not find valid method with Cmd tag {methodName}. Check tags, name spelling and regenerate netcode!");
                return;
            }

            if (!IsServer && !IsClient)
            {
                JNet.Error($"Not on client or server, can't invoke cmd {methodName}");
                return;
            }

            if (!HasAuthority)
            {
                JNet.Error($"There is currently no authority over this object {name}. Must call from on a client that has object ownership, or on the server. Current owner: {NetObject.OwnerID}");
                return;
            }

            methodName = methodName.Trim().ToLower();
            byte methodID = CustomGeneratedBehaviour.GetMethodID(methodName);

            if (!JNet.IsServer)
            {
                CheckDeliveryMethod();

                NetOutgoingMessage msg = JNet.GetClient().CreateMessage(Internal.JDataType.RMC);
                msg.Write(NetObject.NetID);
                msg.Write(this.BehaviourID);
                msg.Write(methodID);

                bool worked = ArgsToMsg(method, args, msg);
                if (!worked)
                {
                    JNet.Error("Did not invoke Cmd due to error.");
                    return;
                }

                var client = JNet.GetClient();
                client.Send(msg, RMCDeliveryMethod, 24);
            }
            else
            {
                // Invoke directly.
                var m = CustomGeneratedBehaviour.GetCmd(methodName);
                m.Invoke(this, args);
            }
        }
Beispiel #10
0
 private static void AddAllParsers()
 {
     AddParser(
         (m) => m.ReadBoolean(),
         (m, o) => m.Write((bool)o));
     AddParser(
         (m) => m.ReadColor(),
         (m, o) => m.Write((Color)o));
     AddParser(
         (m) => m.ReadString(),
         (m, o) => m.Write((string)o));
     AddParser(
         (m) => m.ReadByte(),
         (m, o) => m.Write((byte)o));
     AddParser(
         (m) => m.ReadSByte(),
         (m, o) => m.Write((sbyte)o));
     AddParser(
         (m) => m.ReadInt16(),
         (m, o) => m.Write((short)o));
     AddParser(
         (m) => m.ReadUInt16(),
         (m, o) => m.Write((ushort)o));
     AddParser(
         (m) => m.ReadInt32(),
         (m, o) => m.Write((int)o));
     AddParser(
         (m) => m.ReadUInt32(),
         (m, o) => m.Write((uint)o));
     AddParser(
         (m) => m.ReadInt64(),
         (m, o) => m.Write((long)o));
     AddParser(
         (m) => m.ReadUInt64(),
         (m, o) => m.Write((ulong)o));
     AddParser(
         (m) => m.ReadFloat(),
         (m, o) => m.Write((float)o));
     AddParser(
         (m) => m.ReadDouble(),
         (m, o) => m.Write((double)o));
     AddParser(
         (m) => m.ReadDecimal(),
         (m, o) => m.Write((decimal)o));
     AddParser(
         (m) => m.ReadVector2(),
         (m, o) => m.Write((Vector2)o));
     AddParser(
         (m) => m.ReadVector3(),
         (m, o) => m.Write((Vector3)o));
     AddParser(
         (m) => m.ReadVector4(),
         (m, o) => m.Write((Vector4)o));
     AddParser(
         (m) => JNet.GetObject(m.ReadUInt16()),
         (m, o) => m.Write((ushort)o));
 }
        private void ProcessSetOwner(NetIncomingMessage msg)
        {
            ushort netID   = msg.ReadUInt16();
            long   ownerID = msg.ReadInt64();

            var obj = JNet.GetObject(netID);

            if (obj != null)
            {
                obj.OwnerID = ownerID;
            }
        }
Beispiel #12
0
        /// <summary>
        /// Connects the active client [see <see cref="StartClient"/>] to the specified address and port.
        /// If attempting to connect the client to the local device, ALWAYS USE <see cref="ConnectClientToHost(NetOutgoingMessage)"/>.
        /// Only works if the client is not already connected or connecting.
        /// </summary>
        /// <param name="host">The address to connect to. Use 127.0.0.1 to connect to a local server.</param>
        /// <param name="port">The port number to connect on.</param>
        /// <param name="msg">A hail message. The contents of this message will be read in <see cref="JNetServer.UponConnectionRequest"/> if this behaviour is enabled.</param>
        public static void ConnectClientToRemote(string host, int port, NetOutgoingMessage msg)
        {
            if (!Initialized)
            {
                Error("Call Init() before connecting the client.");
                return;
            }

            if (!IsClient)
            {
                Error("Client is not created. Call StartClient before trying to connect.");
                return;
            }

            if (ClientConnectonStatus != NetConnectionStatus.Disconnected)
            {
                Error("Client is already connected, connecting or disconnecting. Cannot start connect now.");
                return;
            }

            host = host.Trim();
            if (host == "localhost" || host == "127.0.0.1" && IsServer)
            {
                Error("Possibly attempting to connect to local server using ConnectToRemote. Consider ConnectClientToHost instead.");
                // return;
            }

            if (!IsServer)
            {
                Tracker.Reset();
                if (EnableSceneObjectNetworking)
                {
                    RegisterAllSceneObjects();
                }
            }

            NetOutgoingMessage required = Client.CreateMessage();

            required.Write(false);
            required.Write(double.MinValue);

            if (msg != null)
            {
                Client.Connect(host, port, JNet.CreateCombinedMessage(required, msg, false));
            }
            else
            {
                Client.Connect(host, port, required);
            }

            Log("Started client connect to " + host + " on port " + port);
        }
Beispiel #13
0
        /// <summary>
        /// Invokes the named method on the behaviours of all connected clients.
        /// Therefore, this is only valid when called on the server.
        /// If the server is a host (client & server at the same time), then the method is also invoked
        /// locally.
        /// </summary>
        /// <param name="methodName">The name of the method to invoke.</param>
        /// <param name="args"></param>
        protected void InvokeRPC(string methodName, params object[] args)
        {
            if (!JNet.IsServer)
            {
                JNet.Error($"Cannot call Rpc {methodName} because server is not active!");
                return;
            }

            if (!NetObject.HasNetID)
            {
                JNet.Error($"Cannot call Rpc {methodName} because the object that {GetType().FullName} is on is not net spawned.");
                return;
            }

            MethodInfo method = GetRpc(methodName);

            if (method == null)
            {
                JNet.Error($"Could not find valid method with Rpc tag {methodName}. Check tags, name spelling and regenerate netcode!");
                return;
            }

            methodName = methodName.Trim().ToLower();
            byte methodID = CustomGeneratedBehaviour.GetMethodID(methodName);

            CheckDeliveryMethod();

            NetOutgoingMessage msg = JNet.GetServer().CreateMessage(Internal.JDataType.RMC);

            msg.Write(NetObject.NetID);
            msg.Write(this.BehaviourID);
            msg.Write(methodID);

            bool worked = ArgsToMsg(method, args, msg);

            if (!worked)
            {
                JNet.Error("Did not invoke Rpc due to error.");
                return;
            }

            var server = JNet.GetServer();

            server.SendToAllExcept(server.LocalClientConnection, msg, RMCDeliveryMethod, 24);

            // Call on local client, if we are a local client...
            if (JNet.IsClient)
            {
                method.Invoke(this, args);
            }
        }
        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();
        }
Beispiel #15
0
        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);
                }
            }
        }
Beispiel #16
0
        public JNetServer(string name, NetPeerConfiguration config) : base(config, true)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                JNet.Error(string.Format("Null name supplied to server, default name '{0}' will be used.", DEFAULT_NAME));
                name = DEFAULT_NAME;
            }

            Name        = name.Trim();
            Clients     = new List <RemoteClient>();
            dictClients = new Dictionary <long, RemoteClient>();

            SetProcessor(JDataType.PING, this.ProcessPing);
            SetProcessor(JDataType.RMC, this.ProcessRMC);
        }
Beispiel #17
0
        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;
        }
Beispiel #18
0
        /// <summary>
        /// Connects the active client [see <see cref="StartClient"/>] to the locally running server.
        /// It is important to use this method when connecting to the local server since it allows the server
        /// to exclude it from certain messages.
        /// Only works if the client is not already connected or connecting.
        /// </summary>
        /// <param name="msg">The optional hail/connection request message. Can be null.</param>
        public static void ConnectClientToHost(NetOutgoingMessage msg)
        {
            if (!Initialized)
            {
                Error("Call Init() before connecting the client.");
                return;
            }

            if (!IsClient)
            {
                Error("Client is not created. Call StartClient before trying to connect.");
                return;
            }

            if (ClientConnectonStatus != NetConnectionStatus.Disconnected)
            {
                Error("Client is already connected, connecting or disconnecting. Cannot start connect now.");
                return;
            }

            if (!IsServer)
            {
                Error("Server is not running on this instance, cannot connect client as host. Use JNet.ConnectClientToRemote instead.");
                return;
            }

            Client.IsHost = true;

            NetOutgoingMessage required = Client.CreateMessage();

            required.Write(true);
            required.Write(Server.GenNewHostKey());

            if (msg != null)
            {
                Client.Connect("127.0.0.1", Server.Port, JNet.CreateCombinedMessage(required, msg, false));
            }
            else
            {
                Client.Connect("127.0.0.1", Server.Port, required);
            }

            Log("Started client connect to (localhost) on port " + Server.Port);
        }
Beispiel #19
0
        internal void NetAwake()
        {
            // This (derived) class should have a corresponding autogenerated netcode class. Let's find it!
            Type c = GetGeneratedType(this.GetType());

            if (c == null)
            {
                JNet.Error($"Failed to find network autogenerated class for {this.GetType().FullName}, perhaps network code needs to be regenerated?");
#if UNITY_EDITOR
                UnityEditor.EditorApplication.isPaused = true;
#endif
                return;
            }

            var constructor = c.GetConstructors()[0];
            var instance    = constructor.Invoke(null);

            CustomGeneratedBehaviour = instance as JNetGeneratedBehaviour;
        }
Beispiel #20
0
        internal void HandleRMCMessage(NetIncomingMessage msg, byte methodID)
        {
            // TODO catch exceptions.

            bool   expectCmd  = JNet.IsServer;
            string methodName = CustomGeneratedBehaviour.GetMethodName(methodID);

            (var method, bool isCmd) = CustomGeneratedBehaviour.RemoteMethods[methodName];

            if (expectCmd != isCmd)
            {
                JNet.Error("Wrong remote type?? Invesitgate.");
                return;
            }

            if (isCmd)
            {
                // Check message sender for ownership of this object.
                long owner         = this.NetObject.OwnerID;
                long messageSender = msg.SenderConnection.RemoteUniqueIdentifier;

                if (owner != messageSender)
                {
                    JNet.Error($"Got CMD from a client for an object that they don't own. Serious bug or hacking attempt? owner ID: {owner}, message sender: {messageSender}.");
                    return;
                }
            }

            // Read arguments.
            object[] args = MsgToArgs(method, msg);

            try
            {
                method.Invoke(this, args);
            }
            catch (Exception e)
            {
                JNet.Error($"Exception invoking {(isCmd ? "CMD" : "RPC")} {method.Name} - {e.GetType().Name}: {e.Message}");
            }
        }
Beispiel #21
0
        public void SerializeAll()
        {
            if (!JNet.IsServer)
            {
                JNet.Error("Not on server, cannot serialize all.");
                return;
            }

            for (int i = 0; i < ActiveObjects.Count; i++)
            {
                var obj = ActiveObjects[i];
                if(obj == null)
                {
                    JNet.Error("Null object in tracked objects list.");
                    ActiveObjects.RemoveAt(i);
                    i--;
                    continue;
                }

                if(obj.NetBehaviours != null)
                {
                    foreach (var b in obj.NetBehaviours)
                    {
                        if(b != null && b.NetDirty)
                        {
                            JNetServer server = JNet.GetServer();
                            NetOutgoingMessage msg = server.CreateMessage();
                            msg.Write((byte)JDataType.SERIALIZED);
                            msg.Write(obj.NetID);
                            msg.Write(b.BehaviourID);
                            b.NetSerialize(msg, false);

                            server.SendToAllExcept(server.LocalClientConnection, msg, b.SerializationDeliveryMethod, 1);

                            b.NetDirty = false;
                        }
                    }
                }
            }
        }
        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);
        }
Beispiel #23
0
        internal void UpdateBehaviourList()
        {
            var comps = this.GetComponents <NetBehaviour>();

            if (comps.Length <= 256)
            {
                NetBehaviours = comps;
            }
            else
            {
                NetBehaviours = new NetBehaviour[256];
                System.Array.Copy(comps, NetBehaviours, 256);
                JNet.Error(string.Format("NetObject {0} has {1} NetBehaviour components, but a max of 256 are supported. Some of them will not function properly, and errors will arise.", this.ToString(), comps.Length));
            }

            for (int i = 0; i < NetBehaviours.Length; i++)
            {
                NetBehaviours[i].BehaviourID = (byte)i;
                NetBehaviours[i].NetAwake();
            }

            RefreshParentNodes();
        }
Beispiel #24
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);
        }
Beispiel #25
0
        internal static void UpdateClassMap()
        {
            classMap.Clear();

            var s = new System.Diagnostics.Stopwatch();

            s.Start();

            Type parent        = typeof(JNetGeneratedBehaviour);
            uint typeCount     = 0;
            uint assemblyCount = 0;
            var  assemblies    = AppDomain.CurrentDomain.GetAssemblies();

            foreach (var assembly in assemblies)
            {
                string name = assembly.GetName().Name;

                if (name.StartsWith("Unity"))
                {
                    continue;
                }
                if (name.StartsWith("Mono"))
                {
                    continue;
                }
                if (name.StartsWith("System"))
                {
                    continue;
                }
                if (name.StartsWith("Microsoft"))
                {
                    continue;
                }
                if (name == "mscorlib")
                {
                    continue;
                }

                // JNet.Log(name);
                assemblyCount++;

                var types = assembly.GetTypes();
                foreach (var type in types)
                {
                    typeCount++;

                    if (!type.IsClass)
                    {
                        continue;
                    }
                    if (!type.IsSealed)
                    {
                        continue;
                    }

                    if (type.IsSubclassOf(parent))
                    {
                        var attribute = type.GetCustomAttribute <GeneratedTargetAttribute>();
                        if (attribute != null)
                        {
                            var targetType = attribute.GetTargetType();

                            classMap.Add(targetType, type);
                        }
                    }
                }
            }

            s.Stop();
            JNet.Log(string.Format("Rebuild class map in {0}ms, scanned {1} assemblies and {2} types.", s.Elapsed.TotalMilliseconds, assemblyCount, typeCount));
        }
Beispiel #26
0
 /// <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">A behaviour on the net object to spawn.</param>
 public static void Spawn(NetBehaviour behaviour, NetConnection owner = null)
 {
     JNet.Spawn(behaviour.NetObject, owner);
 }
Beispiel #27
0
 private void OnDestroy()
 {
     JNet.Despawn(this);
 }
Beispiel #28
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);
        }
Beispiel #29
0
 public static NetObject ReadNetObject(this NetIncomingMessage msg)
 {
     return(JNet.GetObject(msg.ReadUInt16()));
 }
Beispiel #30
0
 protected void LogError(string s, params object[] args)
 {
     JNet.Error((IsServer ? "[S] " : "[C] ") + string.Format(s, args));
 }