public void SendBatchingResetsPreviousWriter()
        {
            // batching adds 8 byte timestamp header
            const int BatchHeader = 8;

            // create connection
            NetworkConnectionToClient connection = new NetworkConnectionToClient(42);

            // send and update big message
            byte[] message = { 0x01, 0x02 };
            connection.Send(new ArraySegment <byte>(message));
            connection.Update();
            UpdateTransport();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
            Assert.That(clientReceived[0].Length, Is.EqualTo(BatchHeader + 2));
            Assert.That(clientReceived[0][BatchHeader + 0], Is.EqualTo(0x01));
            Assert.That(clientReceived[0][BatchHeader + 1], Is.EqualTo(0x02));

            // clear previous
            clientReceived.Clear();

            // send a smaller message
            message = new byte[] { 0xFF };
            connection.Send(new ArraySegment <byte>(message));
            connection.Update();
            UpdateTransport();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
            Assert.That(clientReceived[0].Length, Is.EqualTo(BatchHeader + 1));
            Assert.That(clientReceived[0][BatchHeader + 0], Is.EqualTo(0xFF));
        }
        public void SendBatchingResetsPreviousWriter()
        {
            // create connection
            NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true, 0);

            // send and update big message
            byte[] message = { 0x01, 0x02 };
            connection.Send(new ArraySegment <byte>(message));
            connection.Update();
            transport.LateUpdate();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
            Assert.That(clientReceived[0].Length, Is.EqualTo(2));
            Assert.That(clientReceived[0][0], Is.EqualTo(0x01));
            Assert.That(clientReceived[0][1], Is.EqualTo(0x02));

            // clear previous
            clientReceived.Clear();

            // send a smaller message
            message = new byte[] { 0xFF };
            connection.Send(new ArraySegment <byte>(message));
            connection.Update();
            transport.LateUpdate();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
            Assert.That(clientReceived[0].Length, Is.EqualTo(1));
            Assert.That(clientReceived[0][0], Is.EqualTo(0xFF));
        }
Example #3
0
        /// <summary>
        /// Called on server when the client's AuthRequestMessage arrives
        /// </summary>
        /// <param name="conn">Connection to client.</param>
        /// <param name="msg">The message payload</param>
        public void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg)
        {
            Debug.Log($"Authentication Request: {msg.authUsername}");

            if (connectionsPendingDisconnect.Contains(conn))
            {
                return;
            }

            // check the credentials by calling your web server, database table, playfab api, or any method appropriate.
            if (!Player.playerNames.Contains(msg.authUsername))
            {
                // Add the name to the HashSet
                Player.playerNames.Add(msg.authUsername);

                // Store username in authenticationData
                // This will be read in Player.OnStartServer
                // to set the playerName SyncVar.
                conn.authenticationData = msg.authUsername;

                // create and send msg to client so it knows to proceed
                AuthResponseMessage authResponseMessage = new AuthResponseMessage
                {
                    code    = 100,
                    message = "Success"
                };

                conn.Send(authResponseMessage);

                // Accept the successful authentication
                ServerAccept(conn);
            }
            else
            {
                connectionsPendingDisconnect.Add(conn);

                // create and send msg to client so it knows to disconnect
                AuthResponseMessage authResponseMessage = new AuthResponseMessage
                {
                    code    = 200,
                    message = "Username already in use...try again"
                };

                conn.Send(authResponseMessage);

                // must set NetworkConnection isAuthenticated = false
                conn.isAuthenticated = false;

                // disconnect the client after 1 second so that response message gets delivered
                StartCoroutine(DelayedDisconnect(conn, 1f));
            }
        }
Example #4
0
        void OnServerCancelMatch(NetworkConnectionToClient conn)
        {
            if (!NetworkServer.active || !playerMatches.ContainsKey(conn))
            {
                return;
            }

            conn.Send(new ClientMatchMessage {
                clientMatchOperation = ClientMatchOperation.Cancelled
            });

            Guid matchId;

            if (playerMatches.TryGetValue(conn, out matchId))
            {
                playerMatches.Remove(conn);
                openMatches.Remove(matchId);

                foreach (NetworkConnectionToClient playerConn in matchConnections[matchId])
                {
                    PlayerInfo playerInfo = playerInfos[playerConn];
                    playerInfo.ready        = false;
                    playerInfo.matchId      = Guid.Empty;
                    playerInfos[playerConn] = playerInfo;
                    playerConn.Send(new ClientMatchMessage {
                        clientMatchOperation = ClientMatchOperation.Departed
                    });
                }

                SendMatchList();
            }
        }
Example #5
0
        void OnServerJoinMatch(NetworkConnectionToClient conn, Guid matchId)
        {
            if (!NetworkServer.active || !matchConnections.ContainsKey(matchId) || !openMatches.ContainsKey(matchId))
            {
                return;
            }

            MatchInfo matchInfo = openMatches[matchId];

            matchInfo.players++;
            openMatches[matchId] = matchInfo;
            matchConnections[matchId].Add(conn);

            PlayerInfo playerInfo = playerInfos[conn];

            playerInfo.ready   = false;
            playerInfo.matchId = matchId;
            playerInfos[conn]  = playerInfo;

            PlayerInfo[] infos = matchConnections[matchId].Select(playerConn => playerInfos[playerConn]).ToArray();
            SendMatchList();

            conn.Send(new ClientMatchMessage {
                clientMatchOperation = ClientMatchOperation.Joined, matchId = matchId, playerInfos = infos
            });

            foreach (NetworkConnectionToClient playerConn in matchConnections[matchId])
            {
                playerConn.Send(new ClientMatchMessage {
                    clientMatchOperation = ClientMatchOperation.UpdateRoom, playerInfos = infos
                });
            }
        }
        // This delay is mostly for the host player that loads too fast for the
        // server to have subscenes async loaded from OnServerSceneChanged ahead of it.
        IEnumerator AddPlayerDelayed(NetworkConnectionToClient conn)
        {
            // Wait for server to async load all subscenes for game instances
            while (!subscenesLoaded)
            {
                yield return(null);
            }

            // Send Scene msg to client telling it to load the first additive scene
            conn.Send(new SceneMessage {
                sceneName = additiveScenes[0], sceneOperation = SceneOperation.LoadAdditive, customHandling = true
            });

            // We have Network Start Positions in first additive scene...pick one
            Transform start = GetStartPosition();

            // Instantiate player as child of start position - this will place it in the additive scene
            // This also lets player object "inherit" pos and rot from start position transform
            GameObject player = Instantiate(playerPrefab, start);

            // now set parent null to get it out from under the Start Position object
            player.transform.SetParent(null);

            // Wait for end of frame before adding the player to ensure Scene Message goes first
            yield return(new WaitForEndOfFrame());

            // Finally spawn the player object for this connection
            NetworkServer.AddPlayerForConnection(conn, player);
        }
Example #7
0
        // This delay is mostly for the host player that loads too fast for the
        // server to have subscenes async loaded from OnStartServer ahead of it.
        IEnumerator OnServerAddPlayerDelayed(NetworkConnectionToClient conn)
        {
            // wait for server to async load all subscenes for game instances
            while (!subscenesLoaded)
            {
                yield return(null);
            }

            // Send Scene message to client to additively load the game scene
            conn.Send(new SceneMessage {
                sceneName = gameScene, sceneOperation = SceneOperation.LoadAdditive
            });

            // Wait for end of frame before adding the player to ensure Scene Message goes first
            yield return(new WaitForEndOfFrame());

            base.OnServerAddPlayer(conn);

            PlayerScore playerScore = conn.identity.GetComponent <PlayerScore>();

            playerScore.playerNumber = clientIndex;
            playerScore.scoreIndex   = clientIndex / subScenes.Count;
            playerScore.matchIndex   = clientIndex % subScenes.Count;

            // Do this only on server, not on clients
            // This is what allows the NetworkSceneChecker on player and scene objects
            // to isolate matches per scene instance on server.
            if (subScenes.Count > 0)
            {
                SceneManager.MoveGameObjectToScene(conn.identity.gameObject, subScenes[clientIndex % subScenes.Count]);
            }

            clientIndex++;
        }
Example #8
0
        void OnServerCreateMatch(NetworkConnectionToClient conn)
        {
            if (!NetworkServer.active || playerMatches.ContainsKey(conn))
            {
                return;
            }

            Guid newMatchId = Guid.NewGuid();

            matchConnections.Add(newMatchId, new HashSet <NetworkConnectionToClient>());
            matchConnections[newMatchId].Add(conn);
            playerMatches.Add(conn, newMatchId);
            openMatches.Add(newMatchId, new MatchInfo {
                matchId = newMatchId, maxPlayers = 2, players = 1
            });

            PlayerInfo playerInfo = playerInfos[conn];

            playerInfo.ready   = false;
            playerInfo.matchId = newMatchId;
            playerInfos[conn]  = playerInfo;

            PlayerInfo[] infos = matchConnections[newMatchId].Select(playerConn => playerInfos[playerConn]).ToArray();

            conn.Send(new ClientMatchMessage {
                clientMatchOperation = ClientMatchOperation.Created, matchId = newMatchId, playerInfos = infos
            });

            SendMatchList();
        }
Example #9
0
        /// <summary>
        /// Called on server when the client's AuthRequestMessage arrives
        /// </summary>
        /// <param name="conn">Connection to client.</param>
        /// <param name="msg">The message payload</param>
        public void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg)
        {
            //Debug.Log($"Authentication Request: {msg.authUsername} {msg.authPassword}");

            if (connectionsPendingDisconnect.Contains(conn))
            {
                return;
            }

            // check the credentials by calling your web server, database table, playfab api, or any method appropriate.
            if (msg.authUsername == serverUsername && msg.authPassword == serverPassword)
            {
                // create and send msg to client so it knows to proceed
                AuthResponseMessage authResponseMessage = new AuthResponseMessage
                {
                    code    = 100,
                    message = "Success"
                };

                conn.Send(authResponseMessage);

                // Accept the successful authentication
                ServerAccept(conn);
            }
            else
            {
                connectionsPendingDisconnect.Add(conn);

                // create and send msg to client so it knows to disconnect
                AuthResponseMessage authResponseMessage = new AuthResponseMessage
                {
                    code    = 200,
                    message = "Invalid Credentials"
                };

                conn.Send(authResponseMessage);

                // must set NetworkConnection isAuthenticated = false
                conn.isAuthenticated = false;

                // disconnect the client after 1 second so that response message gets delivered
                StartCoroutine(DelayedDisconnect(conn, 1f));
            }
        }
Example #10
0
        IEnumerator SendPlayerToNewScene(GameObject player)
        {
            if (player.TryGetComponent <NetworkIdentity>(out NetworkIdentity identity))
            {
                NetworkConnectionToClient conn = identity.connectionToClient;
                if (conn == null)
                {
                    yield break;
                }

                // Tell client to unload previous subscene. No custom handling for this.
                conn.Send(new SceneMessage {
                    sceneName = gameObject.scene.path, sceneOperation = SceneOperation.UnloadAdditive, customHandling = true
                });

                yield return(waitForFade);

                //Debug.Log($"SendPlayerToNewScene RemovePlayerForConnection {conn} netId:{conn.identity.netId}");
                NetworkServer.RemovePlayerForConnection(conn, false);

                // reposition player on server and client
                player.transform.position = startPosition;
                player.transform.LookAt(Vector3.up);

                // Move player to new subscene.
                SceneManager.MoveGameObjectToScene(player, SceneManager.GetSceneByPath(destinationScene));

                // Tell client to load the new subscene with custom handling (see NetworkManager::OnClientChangeScene).
                conn.Send(new SceneMessage {
                    sceneName = destinationScene, sceneOperation = SceneOperation.LoadAdditive, customHandling = true
                });

                //Debug.Log($"SendPlayerToNewScene AddPlayerForConnection {conn} netId:{conn.identity.netId}");
                NetworkServer.AddPlayerForConnection(conn, player);

                // host client would have been disabled by OnTriggerEnter above
                if (NetworkClient.localPlayer != null && NetworkClient.localPlayer.TryGetComponent <PlayerController>(out PlayerController playerController))
                {
                    playerController.enabled = true;
                }
            }
        }
        public void Send_WithoutBatching_SendsImmediately()
        {
            // create connection and send
            NetworkConnectionToClient connection = new NetworkConnectionToClient(42, false, 0);

            byte[] message = { 0x01, 0x02 };
            connection.Send(new ArraySegment <byte>(message));

            // Send() should send immediately, not only in server.update flushing
            transport.LateUpdate();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
        }
Example #12
0
        void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg)
        {
            Debug.Log($"connection {conn.connectionId} authenticated with id {msg.clientDeviceID}");

            // Store the device id for later reference, e.g. when spawning the player
            conn.authenticationData = msg.clientDeviceID;

            // Send a response to client telling it to proceed as authenticated
            conn.Send(new AuthResponseMessage());

            // Accept the successful authentication
            ServerAccept(conn);
        }
        public void OnAuthRequestMessage(NetworkConnectionToClient conn, AuthRequestMessage msg)
        {
            Debug.LogFormat("Authentication Request: {0} {1}", msg.AuthUsername, msg.AuthPassword);

            // check the credentials by calling your web server, database table, playfab api, or any method appropriate.
            if (msg.AuthUsername == Username && msg.AuthPassword == Password)
            {
                // create and send msg to client so it knows to proceed
                var authResponseMessage = new AuthResponseMessage
                {
                    Code    = 100,
                    Message = "Success"
                };

                conn.Send(authResponseMessage);

                // Invoke the event to complete a successful authentication
                base.OnServerAuthenticate(conn);
            }
            else
            {
                // create and send msg to client so it knows to disconnect
                var authResponseMessage = new AuthResponseMessage
                {
                    Code    = 200,
                    Message = "Invalid Credentials"
                };

                conn.Send(authResponseMessage);

                // must set NetworkConnection isAuthenticated = false
                conn.isAuthenticated = false;

                // disconnect the client after 1 second so that response message gets delivered
                StartCoroutine(DelayedDisconnect(conn, 1));
            }
        }
        public void Send_BatchesUntilUpdate()
        {
            // create connection and send
            NetworkConnectionToClient connection = new NetworkConnectionToClient(42);

            byte[] message = { 0x01, 0x02 };
            connection.Send(new ArraySegment <byte>(message));

            // Send() should only add to batch, not send anything yet
            UpdateTransport();
            Assert.That(clientReceived.Count, Is.EqualTo(0));

            // updating the connection should now send
            connection.Update();
            UpdateTransport();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
        }
Example #15
0
        void OnServerLeaveMatch(NetworkConnectionToClient conn, Guid matchId)
        {
            if (!NetworkServer.active)
            {
                return;
            }

            MatchInfo matchInfo = openMatches[matchId];

            matchInfo.players--;
            openMatches[matchId] = matchInfo;

            PlayerInfo playerInfo = playerInfos[conn];

            playerInfo.ready   = false;
            playerInfo.matchId = Guid.Empty;
            playerInfos[conn]  = playerInfo;

            foreach (KeyValuePair <Guid, HashSet <NetworkConnectionToClient> > kvp in matchConnections)
            {
                kvp.Value.Remove(conn);
            }

            HashSet <NetworkConnectionToClient> connections = matchConnections[matchId];

            PlayerInfo[] infos = connections.Select(playerConn => playerInfos[playerConn]).ToArray();

            foreach (NetworkConnectionToClient playerConn in matchConnections[matchId])
            {
                playerConn.Send(new ClientMatchMessage {
                    clientMatchOperation = ClientMatchOperation.UpdateRoom, playerInfos = infos
                });
            }

            SendMatchList();

            conn.Send(new ClientMatchMessage {
                clientMatchOperation = ClientMatchOperation.Departed
            });
        }
        public void Send_BatchesUntilInterval()
        {
            // create connection and send
            int   intervalMilliseconds           = 10;
            float intervalSeconds                = intervalMilliseconds / 1000f;
            NetworkConnectionToClient connection = new NetworkConnectionToClient(42, true, intervalSeconds);

            byte[] message = { 0x01, 0x02 };
            connection.Send(new ArraySegment <byte>(message));

            // Send() and update shouldn't send yet until interval elapsed
            connection.Update();
            transport.LateUpdate();
            Assert.That(clientReceived.Count, Is.EqualTo(0));

            // wait 'interval'
            Thread.Sleep(intervalMilliseconds);

            // updating again should flush out the batch
            connection.Update();
            transport.LateUpdate();
            Assert.That(clientReceived.Count, Is.EqualTo(1));
        }
Example #17
0
        /// <summary>
        /// Sends updated match list to all waiting connections or just one if specified
        /// </summary>
        /// <param name="conn"></param>
        internal void SendMatchList(NetworkConnectionToClient conn = null)
        {
            if (!NetworkServer.active)
            {
                return;
            }

            if (conn != null)
            {
                conn.Send(new ClientMatchMessage {
                    clientMatchOperation = ClientMatchOperation.List, matchInfos = openMatches.Values.ToArray()
                });
            }
            else
            {
                foreach (NetworkConnectionToClient waiter in waitingConnections)
                {
                    waiter.Send(new ClientMatchMessage {
                        clientMatchOperation = ClientMatchOperation.List, matchInfos = openMatches.Values.ToArray()
                    });
                }
            }
        }