/// <summary> /// Handles incoming <see cref="UserUpdatePacket"/>s. /// </summary> /// <param name="connectionId">Original connection ID</param> /// <param name="packet">Incoming packet</param> private void handleUserUpdatePacket(string connectionId, UserUpdatePacket packet) { // Discard packets from non-authenticated sessions if (!authenticator.IsAuthenticated(connectionId, packet.SessionId)) { return; } // Discard packets from non-logged in sessions if (!IsLoggedIn(connectionId, packet.Uuid)) { return; } User user = packet.User; lock (connectedUsersLock) { // Discard packets trying to update users other than themselves if (user.Uuid != connectedUsers[connectionId]) { return; } } // Discard packets with display names longer than the limit if (TextHelper.StripRichText(user.DisplayName).Length > maxDisplayNameLength) { return; } // Update the user UpdateUser(user.Uuid, TextHelper.SanitiseRichText(user.DisplayName), user.AcceptingTrades); }
/// <summary> /// Updates the currently-logged in user locally and on the server. /// Returns whether the update was successful locally and was sent to server. /// </summary> /// <param name="displayName">New display name</param> /// <param name="acceptingTrades">Whether to accept trades from other users</param> /// <returns>User update was successful and sent to server</returns> public bool UpdateSelf(string displayName = null, bool?acceptingTrades = null) { // Don't do anything unless we are logged in if (!LoggedIn) { return(false); } // Don't do anything if the parameters are all null if (displayName == null && acceptingTrades == null) { return(false); } lock (userStoreLock) { // Make sure we are in the user store if (!userStore.Users.ContainsKey(Uuid)) { return(false); // This should never return as the server ensures you exist on login } // Clone the user to avoid editing properties by reference User user = userStore.Users[Uuid].Clone(); // Set the user's display name if it is present if (displayName != null) { user.DisplayName = displayName; } // Set the user's trade acceptance if it is present if (acceptingTrades.HasValue) { user.AcceptingTrades = acceptingTrades.Value; } // Create and pack a user update packet UserUpdatePacket packet = new UserUpdatePacket { SessionId = authenticator.SessionId, Uuid = Uuid, User = user }; Any packedPacket = ProtobufPacketHelper.Pack(packet); // Send it on its way netClient.Send(MODULE_NAME, packedPacket.ToByteArray()); } return(true); }
/// <summary> /// Handles incoming <see cref="UserUpdatePacket"/>s. /// </summary> /// <param name="connectionId">Original connection ID</param> /// <param name="packet">Incoming <see cref="UserUpdatePacket"/></param> private void userUpdatePacketHandler(string connectionId, UserUpdatePacket packet) { User user = packet.User; lock (userStoreLock) { // Check if the user does not already exist if (!userStore.Users.ContainsKey(user.Uuid)) { // Add the user userStore.Users.Add(user.Uuid, user); // Raise the user created event and return OnUserCreated?.Invoke(this, new UserCreatedEventArgs(user.Uuid, user.LoggedIn, user.DisplayName)); return; } // Hold on to the existing copy for later User existingUser = userStore.Users[user.Uuid]; // Replace the user with the new copy userStore.Users[user.Uuid] = user; // Compare the user's login states and raise an event if they differ if (user.LoggedIn != existingUser.LoggedIn) { if (user.LoggedIn) { OnUserLoggedIn?.Invoke(this, new UserLoginStateChangedEventArgs(user.Uuid, false, true)); } else { OnUserLoggedOut?.Invoke(this, new UserLoginStateChangedEventArgs(user.Uuid, true, false)); } } // Compare the user's display name and raise an event if they differ if (user.DisplayName != existingUser.DisplayName) { OnUserDisplayNameChanged?.Invoke(this, new UserDisplayNameChangedEventArgs(user.Uuid, existingUser.DisplayName, user.DisplayName)); } } }
/// <summary> /// Handles incoming <see cref="UserUpdatePacket"/>s. /// </summary> /// <param name="connectionId">Original connection ID</param> /// <param name="packet">Incoming <see cref="UserUpdatePacket"/></param> private void userUpdatePacketHandler(string connectionId, UserUpdatePacket packet) { User user = packet.User; lock (userStoreLock) { if (userStore.Users.ContainsKey(user.Uuid)) { // Update/replace the user userStore.Users[user.Uuid] = user; } else { // Add the user userStore.Users.Add(user.Uuid, user); } } OnUserChanged?.Invoke(this, new UserChangedEventArgs(user.Uuid, user.LoggedIn, user.DisplayName)); }
/// <summary> /// Packs and sends the given user to all currently-logged in users. /// Used when a user's state changes. /// </summary> /// <param name="user">User to broadcast</param> private void broadcastUserUpdate(User user) { // Create and pack the user update packet UserUpdatePacket packet = new UserUpdatePacket { User = user }; Any packedPacket = ProtobufPacketHelper.Pack(packet); lock (connectedUsersLock) { // Send the update to each connection ID foreach (string connectionId in connectedUsers.Keys) { if (!netServer.TrySend(connectionId, MODULE_NAME, packedPacket.ToByteArray())) { RaiseLogEntry(new LogEventArgs("Failed to send UserUpdatePacket to connection " + connectionId, LogLevel.ERROR)); } } } }