internal static void OnPlayerCreate(QNetMessage message, QNetMessageReader reader, ref bool disallowRecycle)
        {
            JEMLogger.Log("QNet is receiving player create event.");

            // de-serialized message
            var serializedPlayer = reader.ReadMessage <QNetPlayerSerialized>();

            // resolve qNetPlayer
            var qNetPlayer = QNetPlayer.GetQNetPlayer(serializedPlayer.ConnectionIdentity);

            if (qNetPlayer == null)
            {
                if (QNetManager.IsHostActive)
                {
                    throw new InvalidOperationException(
                              $"Host is unable to GetQNetPlayer by identity {serializedPlayer.ConnectionIdentity}.");
                }
                qNetPlayer =
                    QNetPlayer.CreateQNetPlayer(serializedPlayer.ConnectionIdentity, serializedPlayer.NickName, 0);
            }

            if (QNetManager.Client.ConnectionIdentity == serializedPlayer.ConnectionIdentity)
            {
                // do something with local player
                // we can't TagAsReady because WORLD_SERIALIZED message already do this
            }
            else
            {
                // tag player as ready
                qNetPlayer.TagAsReady();
            }
        }
Beispiel #2
0
        public static void OnClientLevelLoadedOnFly(QNetMessage message, QNetMessageReader reader, ref bool disallowRecycle)
        {
            var player = QNetPlayer.GetQNetPlayer(reader.Connection);

            if (player == null)
            {
                throw new NullReferenceException("player");
            }
            if (player.Loaded)
            {
                return;
            }
        }
        internal static void OnPlayerDelete(QNetMessage message, QNetMessageReader reader, ref bool disallowRecycle)
        {
            JEMLogger.Log("QNet is receiving player delete event.");
            var connectionIdentity = reader.ReadInt16();
            var player             = QNetPlayer.GetQNetPlayer(connectionIdentity);

            if (player == null)
            {
                throw new InvalidOperationException("InvalidConnectionIdentityError");
            }

            player.TagAsNotReady();
            QNetPlayer.DestroyQNetPlayer(player);
        }
Beispiel #4
0
        internal static void OnClientWorldSerialized(QNetMessage message, QNetMessageReader reader, ref bool disallowRecycle)
        {
            // SERVER: player loads all sent qnet objects
            // prepare this client's controller and send final message so the player can play
            // we will tag this connection as ready, so the system should send this player to all connections on server including owner
            // if owner receive it's player instance from server, they will initialize local systems including camera and movement controller
            var player = QNetPlayer.GetQNetPlayer(reader.Connection);

            if (player == null)
            {
                JEMLogger.LogError("QNet encounter an unexcepted error. Connection QNetPlayer not exists.");
                QNetManager.Server.CloseConnection(reader.Connection, "QNetUnexceptedError");
            }
            else
            {
                player.TagAsReady();
            }
        }
Beispiel #5
0
        /// <summary>
        /// Gets QNetPlayer using Reader's Connection.
        /// </summary>
        public QNetPlayer GetPlayer()
        {
            var player = QNetPlayer.GetQNetPlayer(Reader.Connection);

            return(player);
        }
Beispiel #6
0
        private IEnumerator InternalLoadServerLevelOnFly(string levelName)
        {
            JEMLogger.Log($"QNetUnity is loading map '{levelName}' on fly.");
            GameIsDeInitializing = true;
            GameIsInitializing   = true;
            GameInitialized      = false;

            QNetManager.Server.AcceptNewConnections = false;
            for (var index = 0; index < QNetPlayer.QNetPlayers.Length; index++)
            {
                var p = QNetPlayer.QNetPlayers[index];
                p.Loaded = false;
            }

            LastMapState = QNetMapState.Unloading;
            OnMapStateChanged?.Invoke(LastMapState);

            // destroy players
            yield return(QNetPlayer.DestroyAllQNetPlayers());

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD",
                                               $"Destroying {QNetWorldSerializer.SerializedAndInstancedObjects.Count} objects.");

            // destroy world objects
            var isDestroyingWorldObjects = true;

            QNetWorldSerializer.DestroySerializedObjects(() => { isDestroyingWorldObjects = false; });
            while (isDestroyingWorldObjects)
            {
                yield return(new WaitForEndOfFrame());
            }

            // try to destroy rest of QNet objects just for sure
            if (QNetObjectBehaviour.SpawnedBehaviours.Length != 0)
            {
                JEMLogger.Log(
                    $"QNetUnity find and will destroy {QNetObjectBehaviour.SpawnedBehaviours.Length} additional objects that has been created not by QNetWorldSerializer.");
            }

            // Destroy all behaviours
            yield return(QNetObjectBehaviour.DestroyAll());

            // clear behaviours just for sure
            QNetObjectBehaviour.ClearBehaviours();

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "LOADING LEVEL", "Loading level.");

            LastMapState = QNetMapState.Loading;
            OnMapStateChanged?.Invoke(LastMapState);

            var isLevelLoading = true;

            QNetLevelLoader.Load(levelName, () => { isLevelLoading = false; });
            while (isLevelLoading)
            {
                yield return(new WaitForEndOfFrame());
            }

            LastMapState = QNetMapState.Loaded;
            OnMapStateChanged?.Invoke(LastMapState);

            if (QNetManager.IsServerActive)
            {
                // we are on server!
                // here, we need to send level change info to all clients
                //var writer = QNetManager.Server.GenerateOutgoingMessage((ushort)QNetUnityLocalHeader.LEVEL_LOAD_ON_FLY);
                //writer.WriteString(QNetLevelLoader.LevelName);
                //QNetManager.Server.SendToAll(QNetLocalChannel.DEFAULT, QNetMessageMethod.ReliableOrdered, writer);
            }

            GameIsDeInitializing = false;
            GameIsInitializing   = false;
            GameInitialized      = true;
            QNetManager.Server.AcceptNewConnections = true;

            JEMLogger.Log($"QNetUnity has loaded map '{levelName}' on fly.");
        }
        private static IEnumerator InternalDeInitialize(Action onDone)
        {
            var sw = Stopwatch.StartNew();

            // the initialize client
            OnUnloadClientSideContent?.Invoke();

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD", "Destroying players.");
            OnClientLoadingStart?.Invoke();

            LastMapState = QNetMapState.Unloading;
            OnMapStateChanged?.Invoke(LastMapState);

            // destroy players
            yield return(QNetPlayer.DestroyAllQNetPlayers());

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING WORLD",
                                               $"Destroying {QNetWorldSerializer.SerializedAndInstancedObjects.Count} objects.");

            // destroy world objects
            var isDestroyingWorldObjects = true;

            QNetWorldSerializer.DestroySerializedObjects(() => { isDestroyingWorldObjects = false; });
            while (isDestroyingWorldObjects)
            {
                yield return(new WaitForEndOfFrame());
            }

            // try to destroy rest of QNet objects just for sure
            if (QNetObjectBehaviour.SpawnedBehaviours.Length != 0)
            {
                JEMLogger.Log(
                    $"QNetUnity find and will destroy {QNetObjectBehaviour.SpawnedBehaviours.Length} additional objects that has been created not by QNetWorldSerializer.");
            }

            while (QNetObjectBehaviour.SpawnedBehaviours.Length > 0)
            {
                QNetObjectBehaviour.InternalDestroy(QNetObjectBehaviour.SpawnedBehaviours[0]);
                yield return(new WaitForEndOfFrame());
            }

            // activate loading screen
            OnClientLoadingInfoUpdated?.Invoke(true, "UNLOADING LEVEL", "Unloading level.");

            // unload world
            var isLevelUnLoading = true;

            QNetLevelLoader.UnLoad(() => { isLevelUnLoading = false; });
            while (isLevelUnLoading)
            {
                yield return(new WaitForEndOfFrame());
            }

            // clear behaviours just for sure
            QNetObjectBehaviour.ClearBehaviours();

            LastMapState = QNetMapState.NotLoaded;
            OnMapStateChanged?.Invoke(LastMapState);

            GameIsDeInitializing = false;
            GameInitialized      = false;
            OnClientLoadingEnd?.Invoke();

            JEMLogger.Log($"QNetUnity DeInitialization main work took {sw.Elapsed.Milliseconds:0.00}ms.");
            onDone?.Invoke();
        }