private void OnHelloServer(ushort id, HelloServer helloServer) { Logger.Get().Info(this, $"Received HelloServer data from ID {id}"); // Start by sending the new client the current Server Settings _netServer.GetUpdateManagerForClient(id).UpdateGameSettings(_gameSettings); // Create new player data object var playerData = new ServerPlayerData( helloServer.Username, helloServer.SceneName, helloServer.Position, helloServer.Scale, helloServer.AnimationClipId ); // Store data in mapping _playerData[id] = playerData; foreach (var idPlayerDataPair in _playerData.GetCopy()) { if (idPlayerDataPair.Key == id) { continue; } _netServer.GetUpdateManagerForClient(idPlayerDataPair.Key).AddPlayerConnectData( id, helloServer.Username ); } OnClientEnterScene(id, playerData); }
/// <summary> /// Method that handles a player entering a scene. /// </summary> /// <param name="playerData">The ServerPlayerData corresponding to the player.</param> private void OnClientEnterScene(ServerPlayerData playerData) { var enterSceneList = new List <ClientPlayerEnterScene>(); var alreadyPlayersInScene = false; foreach (var idPlayerDataPair in _playerData.GetCopy()) { // Skip source player if (idPlayerDataPair.Key == playerData.Id) { continue; } var otherPlayerData = idPlayerDataPair.Value; // Send the packet to all clients on the new scene // to indicate that this client has entered their scene if (otherPlayerData.CurrentScene.Equals(playerData.CurrentScene)) { Logger.Get().Info(this, $"Sending EnterScene data to {idPlayerDataPair.Key}"); _netServer.GetUpdateManagerForClient(idPlayerDataPair.Key)?.AddPlayerEnterSceneData( playerData.Id, playerData.Username, playerData.Position, playerData.Scale, playerData.Team, playerData.SkinId, playerData.AnimationId ); Logger.Get().Info(this, $"Sending that {idPlayerDataPair.Key} is already in scene to {playerData.Id}"); alreadyPlayersInScene = true; // Also send a packet to the client that switched scenes, // notifying that these players are already in this new scene. enterSceneList.Add(new ClientPlayerEnterScene { Id = idPlayerDataPair.Key, Username = otherPlayerData.Username, Position = otherPlayerData.Position, Scale = otherPlayerData.Scale, Team = otherPlayerData.Team, SkinId = otherPlayerData.SkinId, AnimationClipId = otherPlayerData.AnimationId }); } } _netServer.GetUpdateManagerForClient(playerData.Id)?.AddPlayerAlreadyInSceneData( enterSceneList, !alreadyPlayersInScene ); }
private void OnClientEnterScene(ushort id, ServerPlayerData playerData) { var alreadyPlayersInScene = false; foreach (var idPlayerDataPair in _playerData.GetCopy()) { // Skip source player if (idPlayerDataPair.Key == id) { continue; } var otherPlayerData = idPlayerDataPair.Value; // Send the packet to all clients on the new scene // to indicate that this client has entered their scene if (otherPlayerData.CurrentScene.Equals(playerData.CurrentScene)) { Logger.Get().Info(this, $"Sending EnterScene data to {idPlayerDataPair.Key}"); _netServer.GetUpdateManagerForClient(idPlayerDataPair.Key).AddPlayerEnterSceneData( id, playerData.Username, playerData.LastPosition, playerData.LastScale, playerData.Team, playerData.SkinId, playerData.LastAnimationClip ); Logger.Get().Info(this, $"Sending that {idPlayerDataPair.Key} is already in scene to {id}"); alreadyPlayersInScene = true; // Also send a packet to the client that switched scenes, // notifying that these players are already in this new scene. _netServer.GetUpdateManagerForClient(id).AddPlayerAlreadyInSceneData( idPlayerDataPair.Key, otherPlayerData.Username, otherPlayerData.LastPosition, otherPlayerData.LastScale, otherPlayerData.Team, otherPlayerData.SkinId, otherPlayerData.LastAnimationClip ); } } if (!alreadyPlayersInScene) { _netServer.GetUpdateManagerForClient(id).SetAlreadyInSceneHost(); } }
/// <summary> /// Method for handling a login request for a new client. /// </summary> /// <param name="id">The ID of the client.</param> /// <param name="endPoint">The IP endpoint of the client.</param> /// <param name="loginRequest">The LoginRequest packet data.</param> /// <param name="updateManager">The update manager for the client.</param> /// <returns>true if the login request was approved, false otherwise.</returns> private bool OnLoginRequest( ushort id, IPEndPoint endPoint, LoginRequest loginRequest, ServerUpdateManager updateManager ) { Logger.Get().Info(this, $"Received login request from IP: {endPoint.Address}, username: {loginRequest.Username}"); if (_banList.IsIpBanned(endPoint.Address.ToString()) || _banList.Contains(loginRequest.AuthKey)) { updateManager.SetLoginResponse(new LoginResponse { LoginResponseStatus = LoginResponseStatus.Banned }); return(false); } if (_whiteList.IsEnabled) { if (!_whiteList.Contains(loginRequest.AuthKey)) { if (!_whiteList.IsPreListed(loginRequest.Username)) { updateManager.SetLoginResponse(new LoginResponse { LoginResponseStatus = LoginResponseStatus.NotWhiteListed }); return(false); } Logger.Get().Info(this, " Username was pre-listed, auth key has been added to whitelist"); _whiteList.Add(loginRequest.AuthKey); _whiteList.RemovePreList(loginRequest.Username); } } // Check whether the username is not already in use foreach (var existingPlayerData in _playerData.GetCopy().Values) { if (existingPlayerData.Username.ToLower().Equals(loginRequest.Username.ToLower())) { updateManager.SetLoginResponse(new LoginResponse { LoginResponseStatus = LoginResponseStatus.InvalidUsername }); return(false); } } var addonData = loginRequest.AddonData; // Construct a string that contains all addons and respective versions by mapping the items in the addon data var addonStringList = string.Join(", ", addonData.Select(addon => $"{addon.Identifier} v{addon.Version}")); Logger.Get().Info(this, $" Client tries to connect with following addons: {addonStringList}"); // If there is a mismatch between the number of networked addons of the client and the server, // we can immediately invalidate the request if (addonData.Count != AddonManager.GetNetworkedAddonData().Count) { HandleInvalidLoginAddons(updateManager); return(false); } // Create a byte list denoting the order of the addons on the server var addonOrder = new List <byte>(); foreach (var addon in addonData) { // Check and retrieve the server addon with the same name and version if (!AddonManager.TryGetNetworkedAddon( addon.Identifier, addon.Version, out var correspondingServerAddon )) { // There was no corresponding server addon, so we send a login response with an invalid status // and the addon data that is present on the server, so the client knows what is invalid HandleInvalidLoginAddons(updateManager); return(false); } if (!correspondingServerAddon.Id.HasValue) { continue; } // If the addon is also present on the server, we append the addon order with the correct index addonOrder.Add(correspondingServerAddon.Id.Value); } var loginResponse = new LoginResponse { LoginResponseStatus = LoginResponseStatus.Success, AddonOrder = addonOrder.ToArray() }; updateManager.SetLoginResponse(loginResponse); // Create new player data and store it var playerData = new ServerPlayerData( id, endPoint.Address.ToString(), loginRequest.Username, loginRequest.AuthKey, _authorizedList ); _playerData[id] = playerData; return(true); }