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()); }