private void OnClientConnect() { Logger.Info(this, "Client is connected, sending Hello packet"); // If we are in a non-gameplay scene, we transmit that we are not active yet var currentSceneName = SceneUtil.GetCurrentSceneName(); if (SceneUtil.IsNonGameplayScene(currentSceneName)) { Logger.Error(this, $"Client connected during a non-gameplay scene named {currentSceneName}, this should never happen!"); return; } var transform = HeroController.instance.transform; // Fill the hello packet with necessary data var helloPacket = new HelloServerPacket { Username = _username, SceneName = SceneUtil.GetCurrentSceneName(), Position = transform.position, Scale = transform.localScale, AnimationClipId = (ushort)_animationManager.GetCurrentAnimationClip() }; helloPacket.CreatePacket(); Logger.Info(this, "Sending Hello packet"); _netClient.SendTcp(helloPacket); // Since we are probably in the pause menu when we connect, set the timescale so the game // is running while paused SetGameManagerTimeScale(1.0f); // We have established a TCP connection so we should receive heart beats now _heartBeatReceiveStopwatch.Reset(); _heartBeatReceiveStopwatch.Start(); MonoBehaviourUtil.Instance.OnUpdateEvent += CheckHeartBeat; UI.UIManager.InfoBox.AddMessage("You are connected to the server"); }
private void OnHelloServer(ushort id, HelloServerPacket packet) { Logger.Info(this, $"Received Hello packet from ID {id}"); // Start by sending the new client the current Server Settings var settingsUpdatePacket = new GameSettingsUpdatePacket { GameSettings = _gameSettings }; settingsUpdatePacket.CreatePacket(); _netServer.SendTcp(id, settingsUpdatePacket); // Read username from packet var username = packet.Username; // Read scene name from packet var sceneName = packet.SceneName; // Read the rest of the data, since we know that we have it var position = packet.Position; var scale = packet.Scale; var currentClip = packet.AnimationClipId; // Create new player data object var playerData = new ServerPlayerData( username, sceneName, position, scale, currentClip ); // Store data in mapping _playerData[id] = playerData; // Create PlayerConnect packet var playerConnectPacket = new ClientPlayerConnectPacket { Id = id, Username = username }; playerConnectPacket.CreatePacket(); // Create PlayerEnterScene packet var enterScenePacket = new ClientPlayerEnterScenePacket { ScenePlayerData = new ScenePlayerData { Id = id, Username = playerData.Username, Position = position, Scale = scale, Team = playerData.Team, AnimationClipId = currentClip, } }; enterScenePacket.CreatePacket(); // Create the AlreadyInScene packet var alreadyInScenePacket = new ClientAlreadyInScenePacket(); // Loop over all other clients and skip over the client that just connected foreach (var idPlayerDataPair in _playerData.GetCopy()) { if (idPlayerDataPair.Key == id) { continue; } var otherPlayerData = idPlayerDataPair.Value; // Send the PlayerConnect packet to all other clients _netServer.SendTcp(idPlayerDataPair.Key, playerConnectPacket); // Send the EnterScene packet only to clients in the same scene if (otherPlayerData.CurrentScene.Equals(sceneName)) { Logger.Info(this, $"Sending a EnterScene packet to ID: {idPlayerDataPair.Key}"); _netServer.SendTcp(idPlayerDataPair.Key, enterScenePacket); // Also send the source client that this player is in their scene, // by adding a new player data instance to the AlreadyInScene packet alreadyInScenePacket.ScenePlayerData.Add(new ScenePlayerData { Id = idPlayerDataPair.Key, Username = otherPlayerData.Username, Position = otherPlayerData.LastPosition, Scale = otherPlayerData.LastScale, Team = otherPlayerData.Team, AnimationClipId = otherPlayerData.LastAnimationClip, }); } } // Now we send the AlreadyInScene packet after it is completely populated, // or not in case of no players in the scene already _netServer.SendTcp(id, alreadyInScenePacket.CreatePacket()); }