Beispiel #1
0
        /// <summary>
        /// Called by UnityEditor.
        /// </summary>
        void OnValidate()
        {
            if (_serverOnly && _localPlayerAuthority)
            {
                if (TinyNetLogLevel.logWarn)
                {
                    TinyLogger.LogWarning("Disabling Local Player Authority for " + gameObject + " because it is server-only.");
                }
                _localPlayerAuthority = false;
            }

            SetupIDs();
        }
Beispiel #2
0
 /// <summary>
 /// Sets the asset unique identifier during play.
 /// </summary>
 /// <param name="newAssetGUID">The new asset unique identifier.</param>
 public void SetDynamicAssetGUID(string newAssetGUID)
 {
     if (_assetGUID == null || _assetGUID == string.Empty || /*!IsValidAssetGUI(_assetGUID) || */ _assetGUID.Equals(newAssetGUID))
     {
         _assetGUID = newAssetGUID;
     }
     else
     {
         if (TinyNetLogLevel.logWarn)
         {
             TinyLogger.LogWarning("SetDynamicAssetId object already has an assetId <" + _assetGUID + ">");
         }
     }
 }
Beispiel #3
0
        /// <summary>
        /// Calls TinyDeserialize in all Components that we received updates for.
        /// </summary>
        /// <param name="netMsg">A wrapper for a <see cref="TinyNetMsgType.StateUpdate"/> message.</param>
        void OnStateUpdateMessage(TinyNetMessageReader netMsg)
        {
            LastServerTick = netMsg.reader.GetUShort();

            if (TinyNetLogLevel.logDev)
            {
                TinyLogger.Log("TinyNetClient::OnStateUpdateMessage frame: " + LastServerTick + " channel: " + netMsg.channelId);
            }

            while (netMsg.reader.AvailableBytes > 0)
            {
                int networkID = netMsg.reader.GetInt();

                int rSize = netMsg.reader.GetInt();

                _stateUpdateReader.Clear();
                //Debug.Log("OnStateUpdate: RawDataSize: " + netMsg.reader.RawDataSize + ", Position: " + netMsg.reader.Position + ", rSize: " + rSize);
                _stateUpdateReader.SetSource(netMsg.reader.RawData, netMsg.reader.Position, rSize + netMsg.reader.Position);
                _stateUpdateReader.SetFrameTick(LastServerTick);
                //Debug.Log("OnStateUpdate: _stateUpdateReader " + _stateUpdateReader.RawDataSize + ", Position: " + _stateUpdateReader.Position);

                TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(networkID);
                if (localObject != null)
                {
                    localObject.TinyDeserialize(_stateUpdateReader, false);
                }
                else
                {
                    if (TinyNetLogLevel.logWarn)
                    {
                        TinyLogger.LogWarning("Did not find target for sync message for " + networkID);
                    }
                }

                // We jump the reader position to the amount of data we read.
                //netMsg.reader.SetSource(netMsg.reader.RawData, netMsg.reader.Position + rSize, netMsg.reader.RawDataSize);
                netMsg.reader.SkipBytes(rSize);
            }

            foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values)
            {
                tinyNetId.OnStateUpdate();
            }
        }
        /// <summary>
        /// Always call this to hide an object from a client, or you will have sync issues.
        /// </summary>
        /// <param name="tni">The <see cref="TinyNetIdentity"/> of the object to hide.</param>
        public void HideObjectToConnection(TinyNetIdentity tni, bool isDestroyed)
        {
            if (!_observingNetObjects.Contains(tni))
            {
                if (TinyNetLogLevel.logDev)
                {
                    TinyLogger.LogWarning("RemoveFromVisList() called but object with networkdID: " + tni.NetworkID + " is not shown");
                }
                return;
            }

            _observingNetObjects.Remove(tni);

            if (!isDestroyed)
            {
                // hide tni for this conn
                TinyNetServer.instance.HideForConnection(tni, this);
            }
        }
Beispiel #5
0
        /// <summary>
        /// Called when an object is destroyed.
        /// </summary>
        /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectDestroyMessage"/>.</param>
        void OnObjectDestroy(TinyNetMessageReader netMsg)
        {
            netMsg.ReadMessage(s_TinyNetObjectDestroyMessage);

            if (TinyNetLogLevel.logDebug)
            {
                TinyLogger.Log("TinyNetClient::OnObjDestroy networkID:" + s_TinyNetObjectDestroyMessage.networkID);
            }

            TinyNetIdentity localObject = GetTinyNetIdentityByNetworkID(s_TinyNetObjectDestroyMessage.networkID);

            if (localObject != null)
            {
                RemoveTinyNetIdentityFromList(localObject);
                localObject.OnNetworkDestroy();

                if (!TinyNetGameManager.instance.InvokeUnSpawnHandler(localObject.assetGUID, localObject.gameObject))
                {
                    // default handling
                    if (localObject.sceneID == 0)
                    {
                        Object.Destroy(localObject.gameObject);
                    }
                    else
                    {
                        // scene object.. disable it in scene instead of destroying
                        localObject.gameObject.SetActive(false);
                        _sceneIdentityObjectsToSpawn[localObject.sceneID] = localObject;
                    }
                }
            }
            else
            {
                if (TinyNetLogLevel.logDebug)
                {
                    TinyLogger.LogWarning("Did not find target for destroy message for " + s_TinyNetObjectDestroyMessage.networkID);
                }
            }
        }
        /// <summary>
        /// By default it will deserialize the <see cref="TinyNetSyncVar"/> properties.
        /// </summary>
        /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectStateUpdate"/> message.</param>
        void OnStateUpdateMessage(TinyNetMessageReader netMsg)
        {
            int networkID = netMsg.reader.GetInt();

            if (TinyNetLogLevel.logDev)
            {
                TinyLogger.Log("TinyNetClient::OnUpdateVarsMessage " + networkID + " channel:" + netMsg.channelId);
            }

            ITinyNetObject localObject = _localNetObjects[networkID];

            if (localObject != null)
            {
                localObject.TinyDeserialize(netMsg.reader, false);
            }
            else
            {
                if (TinyNetLogLevel.logWarn)
                {
                    TinyLogger.LogWarning("Did not find target for sync message for " + networkID);
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Called when an object is spawned.
        /// </summary>
        /// <param name="netMsg">A wrapper for a <see cref="TinyNetObjectSpawnMessage"/>.</param>
        void OnObjectSpawn(TinyNetMessageReader netMsg)
        {
            netMsg.ReadMessage(s_TinyNetObjectSpawnMessage);

            if (s_TinyNetObjectSpawnMessage.assetIndex < 0 || s_TinyNetObjectSpawnMessage.assetIndex > int.MaxValue || s_TinyNetObjectSpawnMessage.assetIndex > TinyNetGameManager.instance.GetAmountOfRegisteredAssets())
            {
                if (TinyNetLogLevel.logError)
                {
                    TinyLogger.LogError("OnObjSpawn networkID: " + s_TinyNetObjectSpawnMessage.networkID + " has invalid asset Id");
                }
                return;
            }
            if (TinyNetLogLevel.logDev)
            {
                TinyLogger.Log("Client spawn handler instantiating [networkID:" + s_TinyNetObjectSpawnMessage.networkID + " asset ID:" + s_TinyNetObjectSpawnMessage.assetIndex + " pos:" + s_TinyNetObjectSpawnMessage.position + "]");
            }

            TinyNetIdentity localTinyNetIdentity = GetTinyNetIdentityByNetworkID(s_TinyNetObjectSpawnMessage.networkID);

            // Check if this object was already registered in the scene:
            if (localTinyNetIdentity != null)
            {
                // this object already exists (was in the scene), just apply the update to existing object.
                ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.initialState, s_TinyNetObjectSpawnMessage.networkID, null, s_TinyNetObjectSpawnMessage.frameTick);
                return;
            }

            GameObject    prefab;
            SpawnDelegate handler;

            prefab = TinyNetGameManager.instance.GetPrefabFromAssetId(s_TinyNetObjectSpawnMessage.assetIndex);
            // Check if the prefab is registered in the list of spawnable prefabs.
            if (prefab != null)
            {
                var obj = (GameObject)Object.Instantiate(prefab, s_TinyNetObjectSpawnMessage.position, Quaternion.identity);

                localTinyNetIdentity = obj.GetComponent <TinyNetIdentity>();

                if (localTinyNetIdentity == null)
                {
                    if (TinyNetLogLevel.logError)
                    {
                        TinyLogger.LogError("Client object spawned for " + s_TinyNetObjectSpawnMessage.assetIndex + " does not have a TinyNetidentity");
                    }
                    return;
                }

                ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.initialState, s_TinyNetObjectSpawnMessage.networkID, obj, s_TinyNetObjectSpawnMessage.frameTick);
                // If not, check if the prefab have a spawn handler registered.
            }
            else if (TinyNetGameManager.instance.GetSpawnHandler(s_TinyNetObjectSpawnMessage.assetIndex, out handler))
            {
                GameObject obj = handler(s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.assetIndex);
                if (obj == null)
                {
                    if (TinyNetLogLevel.logWarn)
                    {
                        TinyLogger.LogWarning("Client spawn handler for " + s_TinyNetObjectSpawnMessage.assetIndex + " returned null");
                    }
                    return;
                }

                localTinyNetIdentity = obj.GetComponent <TinyNetIdentity>();
                if (localTinyNetIdentity == null)
                {
                    if (TinyNetLogLevel.logError)
                    {
                        TinyLogger.LogError("Client object spawned for " + s_TinyNetObjectSpawnMessage.assetIndex + " does not have a network identity");
                    }
                    return;
                }

                localTinyNetIdentity.SetDynamicAssetGUID(TinyNetGameManager.instance.GetAssetGUIDFromAssetId(s_TinyNetObjectSpawnMessage.assetIndex));
                ApplyInitialState(localTinyNetIdentity, s_TinyNetObjectSpawnMessage.position, s_TinyNetObjectSpawnMessage.initialState, s_TinyNetObjectSpawnMessage.networkID, obj, s_TinyNetObjectSpawnMessage.frameTick);
                // If also not, we literally cannot spawn this object and you should feel bad.
            }
            else
            {
                if (TinyNetLogLevel.logError)
                {
                    TinyLogger.LogError("Failed to spawn server object, assetId=" + s_TinyNetObjectSpawnMessage.assetIndex + " networkID=" + s_TinyNetObjectSpawnMessage.networkID);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Deserializes all <see cref="ITinyNetComponent"/> data.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="bInitialState">if set to <c>true</c> [b initial state].</param>
        public virtual void TinyDeserialize(TinyNetStateReader reader, bool firstStateUpdate)
        {
            if (firstStateUpdate && _tinyNetComponents == null)
            {
                if (TinyNetLogLevel.logWarn)
                {
                    TinyLogger.LogWarning("TinyNetIdentity::TinyDeserialize called with firstStateUpdate true, but _tinyNetComponents is null.");
                }
                CacheTinyNetObjects();
            }

            if (firstStateUpdate)
            {
                for (int i = 0; i < _tinyNetComponents.Length; i++)
                {
                    _tinyNetComponents[i].ReceiveNetworkID(new TinyNetworkID(TinyInstanceID.NetworkID, (byte)(i + 1)));

                    _recycleReader.Clear();
                    int rSize = reader.GetInt();
                    _recycleReader.SetSource(reader.RawData, reader.Position, rSize);

                    _recycleReader.SetFrameTick(reader.FrameTick);
                    _tinyNetComponents[i].TinyDeserialize(_recycleReader, firstStateUpdate);
                    // We jump the reader position to the amount of data we read.
                    reader.SkipBytes(rSize);
                }

                return;
            }

            switch (_dirtyFlag.Length)
            {
            case 8:
                TinyBitArrayUtil.U64ToBitArray(reader.GetByte(), _dirtyFlag);
                break;

            case 16:
                TinyBitArrayUtil.U64ToBitArray(reader.GetUShort(), _dirtyFlag);
                break;

            case 32:
                TinyBitArrayUtil.U64ToBitArray(reader.GetUInt(), _dirtyFlag);
                break;

            case 64:
                TinyBitArrayUtil.U64ToBitArray(reader.GetULong(), _dirtyFlag);
                break;
            }

            for (int i = 0; i < _tinyNetComponents.Length; i++)
            {
                if (_dirtyFlag[i] == true)
                {
                    _recycleReader.Clear();
                    int rSize = reader.GetInt();
                    _recycleReader.SetSource(reader.RawData, reader.Position, rSize);

                    _recycleReader.SetFrameTick(reader.FrameTick);
                    //Debug.Log("[Deserialize] Size: " + rSize + ", DirtyFlag: " + TinyBitArrayUtil.Display(_recycleReader.PeekByte()));
                    _tinyNetComponents[i].TinyDeserialize(_recycleReader, firstStateUpdate);
                    // We jump the reader position to the amount of data we read.
                    reader.SkipBytes(rSize);
                }
            }
        }
        //============ Clients Functions ====================//

        /// <summary>
        /// Sets the client as ready.
        /// </summary>
        /// <param name="conn">The connection.</param>
        void SetClientReady(TinyNetConnection conn)
        {
            if (TinyNetLogLevel.logDebug)
            {
                TinyLogger.Log("SetClientReady for conn:" + conn.ConnectId);
            }

            if (conn.isReady)
            {
                if (TinyNetLogLevel.logDebug)
                {
                    TinyLogger.Log("SetClientReady conn " + conn.ConnectId + " already ready");
                }
                return;
            }

            if (conn.playerControllers.Count == 0)
            {
                if (TinyNetLogLevel.logDebug)
                {
                    TinyLogger.LogWarning("Ready with no player object");
                }
            }

            conn.isReady = true;

            // This is only in case this is a listen server.
            TinyNetLocalConnectionToClient localConnection = conn as TinyNetLocalConnectionToClient;

            if (localConnection != null)
            {
                if (TinyNetLogLevel.logDev)
                {
                    TinyLogger.Log("NetworkServer Ready handling TinyNetLocalConnectionToClient");
                }

                // Setup spawned objects for local player
                // Only handle the local objects for the first player (no need to redo it when doing more local players)
                // and don't handle player objects here, they were done above
                foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values)
                {
                    // Need to call OnStartClient directly here, as it's already been added to the local object dictionary
                    // in the above SetLocalPlayer call
                    if (tinyNetId != null && tinyNetId.gameObject != null)
                    {
                        if (!tinyNetId.isClient)
                        {
                            localConnection.ShowObjectToConnection(tinyNetId);

                            if (TinyNetLogLevel.logDev)
                            {
                                TinyLogger.Log("LocalClient.SetSpawnObject calling OnStartClient");
                            }
                            tinyNetId.OnStartClient();
                        }
                    }
                }

                return;
            }

            // Spawn/update all current server objects
            if (TinyNetLogLevel.logDebug)
            {
                TinyLogger.Log("Spawning " + LocalIdentityObjects.Count + " objects for conn " + conn.ConnectId);
            }

            TinyNetObjectSpawnFinishedMessage msg = new TinyNetObjectSpawnFinishedMessage();

            msg.state = 0;             //State 0 means we are starting the spawn messages 'spam'.
            SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, conn);

            foreach (TinyNetIdentity tinyNetId in LocalIdentityObjects.Values)
            {
                if (tinyNetId == null)
                {
                    if (TinyNetLogLevel.logWarn)
                    {
                        TinyLogger.LogWarning("Invalid object found in server local object list (null TinyNetIdentity).");
                    }
                    continue;
                }
                if (!tinyNetId.gameObject.activeSelf)
                {
                    continue;
                }

                if (TinyNetLogLevel.logDebug)
                {
                    TinyLogger.Log("Sending spawn message for current server objects name='" + tinyNetId.gameObject.name + "' netId=" + tinyNetId.TinyInstanceID);
                }

                conn.ShowObjectToConnection(tinyNetId);
            }

            if (TinyNetLogLevel.logDebug)
            {
                TinyLogger.Log("Spawning objects for conn " + conn.ConnectId + " finished");
            }

            msg.state = 1;             //We finished spamming the spawn messages!
            SendMessageByChannelToTargetConnection(msg, DeliveryMethod.ReliableOrdered, conn);
        }