aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewermessage.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-08-29 17:44:38 -0500
committerJacek Antonelli2009-08-29 22:49:51 -0500
commit6a5aab98892df74f60743f5b789959c9593d6647 (patch)
tree62da18f8540879ed01e12eeb0ce49375474272e4 /linden/indra/newview/llviewermessage.cpp
parentMerge branch 'mac-openal-url' into next (diff)
parentConverted 1.23 XUI files to unix line endings. (diff)
downloadmeta-impy-6a5aab98892df74f60743f5b789959c9593d6647.zip
meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.tar.gz
meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.tar.bz2
meta-impy-6a5aab98892df74f60743f5b789959c9593d6647.tar.xz
Merged SL 1.23.4 into Imprudence.
Conflicts: linden/doc/contributions.txt linden/indra/CMakeLists.txt linden/indra/cmake/APR.cmake linden/indra/cmake/CopyWinLibs.cmake linden/indra/cmake/OPENAL.cmake linden/indra/develop.py linden/indra/llaudio/audioengine.cpp linden/indra/llcommon/indra_constants.h linden/indra/llcommon/llversionviewer.h linden/indra/llcrashlogger/llcrashlogger.cpp linden/indra/llmedia/llmediaimplgstreamer.cpp linden/indra/llmedia/llmediaimplgstreamer.h linden/indra/llmedia/llmediaimplgstreamer_syms.cpp linden/indra/llmedia/llmediaimplgstreamer_syms.h linden/indra/llmedia/llmediaimplgstreamer_syms_raw.inc linden/indra/llmedia/llmediamanager.cpp linden/indra/llmessage/llassetstorage.cpp linden/indra/llui/lltexteditor.cpp linden/indra/llvfs/lldir.cpp linden/indra/newview/CMakeLists.txt linden/indra/newview/English.lproj/InfoPlist.strings linden/indra/newview/Info-Imprudence.plist linden/indra/newview/app_settings/logcontrol.xml linden/indra/newview/app_settings/settings.xml linden/indra/newview/installers/windows/installer_template.nsi linden/indra/newview/llagent.cpp linden/indra/newview/llappviewer.cpp linden/indra/newview/llcallingcard.cpp linden/indra/newview/llfilepicker.cpp linden/indra/newview/llfloateractivespeakers.cpp linden/indra/newview/llfloateravatarpicker.cpp linden/indra/newview/llfloaterbulkpermission.cpp linden/indra/newview/llfloaterbulkpermission.h linden/indra/newview/llfloaterchat.cpp linden/indra/newview/llfloatergodtools.cpp linden/indra/newview/llfloaterhtmlhelp.cpp linden/indra/newview/llfloatertools.cpp linden/indra/newview/llfloatertools.h linden/indra/newview/llfloatertopobjects.cpp linden/indra/newview/llinventorybridge.cpp linden/indra/newview/llinventoryview.cpp linden/indra/newview/llnetmap.cpp linden/indra/newview/llnetmap.h linden/indra/newview/llpanelland.cpp linden/indra/newview/llpanellogin.cpp linden/indra/newview/llpanelobject.cpp linden/indra/newview/llprefsim.cpp linden/indra/newview/lltexturecache.cpp linden/indra/newview/lltoolbrush.cpp linden/indra/newview/llvieweraudio.cpp linden/indra/newview/llviewermenu.cpp linden/indra/newview/llviewermessage.cpp linden/indra/newview/llviewerparcelmedia.cpp linden/indra/newview/llvoavatar.cpp linden/indra/newview/llwebbrowserctrl.cpp linden/indra/newview/llworldmapview.cpp linden/indra/newview/pipeline.cpp linden/indra/newview/res/viewerRes.rc linden/indra/newview/skins/default/colors_base.xml linden/indra/newview/skins/default/xui/de/floater_active_speakers.xml linden/indra/newview/skins/default/xui/de/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/de/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/de/floater_joystick.xml linden/indra/newview/skins/default/xui/de/floater_mute_object.xml linden/indra/newview/skins/default/xui/de/floater_sim_release_message.xml linden/indra/newview/skins/default/xui/de/panel_media_controls.xml linden/indra/newview/skins/default/xui/de/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/de/strings.xml linden/indra/newview/skins/default/xui/de/teleport_strings.xml linden/indra/newview/skins/default/xui/en-us/alerts.xml linden/indra/newview/skins/default/xui/en-us/floater_about_land.xml linden/indra/newview/skins/default/xui/en-us/floater_avatar_picker.xml linden/indra/newview/skins/default/xui/en-us/floater_beacons.xml linden/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml linden/indra/newview/skins/default/xui/en-us/floater_buy_land.xml linden/indra/newview/skins/default/xui/en-us/floater_chatterbox.xml linden/indra/newview/skins/default/xui/en-us/floater_inventory_view_finder.xml linden/indra/newview/skins/default/xui/en-us/floater_media_browser.xml linden/indra/newview/skins/default/xui/en-us/floater_mini_map.xml linden/indra/newview/skins/default/xui/en-us/floater_tools.xml linden/indra/newview/skins/default/xui/en-us/menu_login.xml linden/indra/newview/skins/default/xui/en-us/menu_mini_map.xml linden/indra/newview/skins/default/xui/en-us/menu_pie_attachment.xml linden/indra/newview/skins/default/xui/en-us/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/en-us/menu_pie_object.xml linden/indra/newview/skins/default/xui/en-us/menu_pie_self.xml linden/indra/newview/skins/default/xui/en-us/menu_viewer.xml linden/indra/newview/skins/default/xui/en-us/notify.xml linden/indra/newview/skins/default/xui/en-us/panel_bars.xml linden/indra/newview/skins/default/xui/en-us/panel_groups.xml linden/indra/newview/skins/default/xui/en-us/panel_media_controls.xml linden/indra/newview/skins/default/xui/en-us/panel_mini_map.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_im.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_input.xml linden/indra/newview/skins/default/xui/en-us/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/en-us/strings.xml linden/indra/newview/skins/default/xui/es/alerts.xml linden/indra/newview/skins/default/xui/es/floater_about.xml linden/indra/newview/skins/default/xui/es/floater_about_land.xml linden/indra/newview/skins/default/xui/es/floater_animation_preview.xml linden/indra/newview/skins/default/xui/es/floater_auction.xml linden/indra/newview/skins/default/xui/es/floater_avatar_picker.xml linden/indra/newview/skins/default/xui/es/floater_avatar_textures.xml linden/indra/newview/skins/default/xui/es/floater_build_options.xml linden/indra/newview/skins/default/xui/es/floater_bumps.xml linden/indra/newview/skins/default/xui/es/floater_buy_contents.xml linden/indra/newview/skins/default/xui/es/floater_buy_currency.xml linden/indra/newview/skins/default/xui/es/floater_buy_land.xml linden/indra/newview/skins/default/xui/es/floater_buy_object.xml linden/indra/newview/skins/default/xui/es/floater_chat_history.xml linden/indra/newview/skins/default/xui/es/floater_choose_group.xml linden/indra/newview/skins/default/xui/es/floater_clothing.xml linden/indra/newview/skins/default/xui/es/floater_color_picker.xml linden/indra/newview/skins/default/xui/es/floater_critical.xml linden/indra/newview/skins/default/xui/es/floater_customize.xml linden/indra/newview/skins/default/xui/es/floater_directory.xml linden/indra/newview/skins/default/xui/es/floater_gesture.xml linden/indra/newview/skins/default/xui/es/floater_group_info.xml linden/indra/newview/skins/default/xui/es/floater_html.xml linden/indra/newview/skins/default/xui/es/floater_im.xml linden/indra/newview/skins/default/xui/es/floater_image_preview.xml linden/indra/newview/skins/default/xui/es/floater_import.xml linden/indra/newview/skins/default/xui/es/floater_instant_message.xml linden/indra/newview/skins/default/xui/es/floater_inventory.xml linden/indra/newview/skins/default/xui/es/floater_inventory_item_properties.xml linden/indra/newview/skins/default/xui/es/floater_inventory_view_finder.xml linden/indra/newview/skins/default/xui/es/floater_land_holdings.xml linden/indra/newview/skins/default/xui/es/floater_live_lsleditor.xml linden/indra/newview/skins/default/xui/es/floater_moveview.xml linden/indra/newview/skins/default/xui/es/floater_mute.xml linden/indra/newview/skins/default/xui/es/floater_name_description.xml linden/indra/newview/skins/default/xui/es/floater_new_im.xml linden/indra/newview/skins/default/xui/es/floater_new_outfit_dialog.xml linden/indra/newview/skins/default/xui/es/floater_openobject.xml linden/indra/newview/skins/default/xui/es/floater_pay.xml linden/indra/newview/skins/default/xui/es/floater_pay_object.xml linden/indra/newview/skins/default/xui/es/floater_postcard.xml linden/indra/newview/skins/default/xui/es/floater_preferences.xml linden/indra/newview/skins/default/xui/es/floater_preview_animation.xml linden/indra/newview/skins/default/xui/es/floater_preview_embedded_texture.xml linden/indra/newview/skins/default/xui/es/floater_preview_gesture.xml linden/indra/newview/skins/default/xui/es/floater_preview_notecard.xml linden/indra/newview/skins/default/xui/es/floater_preview_notecard_keep_discard.xml linden/indra/newview/skins/default/xui/es/floater_preview_sound.xml linden/indra/newview/skins/default/xui/es/floater_preview_texture.xml linden/indra/newview/skins/default/xui/es/floater_preview_texture_keep_discard.xml linden/indra/newview/skins/default/xui/es/floater_price_for_listing.xml linden/indra/newview/skins/default/xui/es/floater_profile.xml linden/indra/newview/skins/default/xui/es/floater_report_abuse.xml linden/indra/newview/skins/default/xui/es/floater_script_debug.xml linden/indra/newview/skins/default/xui/es/floater_script_ed_panel.xml linden/indra/newview/skins/default/xui/es/floater_script_preview.xml linden/indra/newview/skins/default/xui/es/floater_script_queue.xml linden/indra/newview/skins/default/xui/es/floater_script_search.xml linden/indra/newview/skins/default/xui/es/floater_sell_land.xml linden/indra/newview/skins/default/xui/es/floater_settings_debug.xml linden/indra/newview/skins/default/xui/es/floater_snapshot.xml linden/indra/newview/skins/default/xui/es/floater_sound_preview.xml linden/indra/newview/skins/default/xui/es/floater_telehub.xml linden/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml linden/indra/newview/skins/default/xui/es/floater_tools.xml linden/indra/newview/skins/default/xui/es/floater_top_objects.xml linden/indra/newview/skins/default/xui/es/floater_tos.xml linden/indra/newview/skins/default/xui/es/floater_wearable_save_as.xml linden/indra/newview/skins/default/xui/es/floater_world_map.xml linden/indra/newview/skins/default/xui/es/menu_inventory.xml linden/indra/newview/skins/default/xui/es/menu_pie_attachment.xml linden/indra/newview/skins/default/xui/es/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/es/menu_pie_land.xml linden/indra/newview/skins/default/xui/es/menu_pie_object.xml linden/indra/newview/skins/default/xui/es/menu_pie_self.xml linden/indra/newview/skins/default/xui/es/menu_viewer.xml linden/indra/newview/skins/default/xui/es/notify.xml linden/indra/newview/skins/default/xui/es/panel_avatar.xml linden/indra/newview/skins/default/xui/es/panel_avatar_classified.xml linden/indra/newview/skins/default/xui/es/panel_avatar_pick.xml linden/indra/newview/skins/default/xui/es/panel_chat_bar.xml linden/indra/newview/skins/default/xui/es/panel_classified.xml linden/indra/newview/skins/default/xui/es/panel_event.xml linden/indra/newview/skins/default/xui/es/panel_group.xml linden/indra/newview/skins/default/xui/es/panel_group_finder.xml linden/indra/newview/skins/default/xui/es/panel_group_general.xml linden/indra/newview/skins/default/xui/es/panel_group_invite.xml linden/indra/newview/skins/default/xui/es/panel_group_land_money.xml linden/indra/newview/skins/default/xui/es/panel_group_notices.xml linden/indra/newview/skins/default/xui/es/panel_group_roles.xml linden/indra/newview/skins/default/xui/es/panel_group_voting.xml linden/indra/newview/skins/default/xui/es/panel_land_covenant.xml linden/indra/newview/skins/default/xui/es/panel_login.xml linden/indra/newview/skins/default/xui/es/panel_overlaybar.xml linden/indra/newview/skins/default/xui/es/panel_place.xml linden/indra/newview/skins/default/xui/es/panel_place_small.xml linden/indra/newview/skins/default/xui/es/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/es/panel_preferences_chat.xml linden/indra/newview/skins/default/xui/es/panel_preferences_general.xml linden/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml linden/indra/newview/skins/default/xui/es/panel_preferences_im.xml linden/indra/newview/skins/default/xui/es/panel_preferences_input.xml linden/indra/newview/skins/default/xui/es/panel_preferences_network.xml linden/indra/newview/skins/default/xui/es/panel_preferences_popups.xml linden/indra/newview/skins/default/xui/es/panel_region_covenant.xml linden/indra/newview/skins/default/xui/es/panel_region_debug.xml linden/indra/newview/skins/default/xui/es/panel_region_estate.xml linden/indra/newview/skins/default/xui/es/panel_region_general.xml linden/indra/newview/skins/default/xui/es/panel_region_terrain.xml linden/indra/newview/skins/default/xui/es/panel_region_texture.xml linden/indra/newview/skins/default/xui/es/panel_scrolling_param.xml linden/indra/newview/skins/default/xui/es/panel_status_bar.xml linden/indra/newview/skins/default/xui/es/panel_toolbar.xml linden/indra/newview/skins/default/xui/es/panel_top_pick.xml linden/indra/newview/skins/default/xui/fr/alerts.xml linden/indra/newview/skins/default/xui/fr/floater_about.xml linden/indra/newview/skins/default/xui/fr/floater_about_land.xml linden/indra/newview/skins/default/xui/fr/floater_avatar_picker.xml linden/indra/newview/skins/default/xui/fr/floater_avatar_textures.xml linden/indra/newview/skins/default/xui/fr/floater_beacons.xml linden/indra/newview/skins/default/xui/fr/floater_buy_contents.xml linden/indra/newview/skins/default/xui/fr/floater_buy_currency.xml linden/indra/newview/skins/default/xui/fr/floater_buy_land.xml linden/indra/newview/skins/default/xui/fr/floater_chat_history.xml linden/indra/newview/skins/default/xui/fr/floater_clothing.xml linden/indra/newview/skins/default/xui/fr/floater_customize.xml linden/indra/newview/skins/default/xui/fr/floater_directory.xml linden/indra/newview/skins/default/xui/fr/floater_god_tools.xml linden/indra/newview/skins/default/xui/fr/floater_group_info.xml linden/indra/newview/skins/default/xui/fr/floater_html.xml linden/indra/newview/skins/default/xui/fr/floater_im.xml linden/indra/newview/skins/default/xui/fr/floater_instant_message.xml linden/indra/newview/skins/default/xui/fr/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/fr/floater_inventory.xml linden/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml linden/indra/newview/skins/default/xui/fr/floater_joystick.xml linden/indra/newview/skins/default/xui/fr/floater_land_holdings.xml linden/indra/newview/skins/default/xui/fr/floater_live_lsleditor.xml linden/indra/newview/skins/default/xui/fr/floater_media_browser.xml linden/indra/newview/skins/default/xui/fr/floater_mem_leaking.xml linden/indra/newview/skins/default/xui/fr/floater_name_description.xml linden/indra/newview/skins/default/xui/fr/floater_preview_gesture.xml linden/indra/newview/skins/default/xui/fr/floater_profile.xml linden/indra/newview/skins/default/xui/fr/floater_report_abuse.xml linden/indra/newview/skins/default/xui/fr/floater_script_search.xml linden/indra/newview/skins/default/xui/fr/floater_sell_land.xml linden/indra/newview/skins/default/xui/fr/floater_snapshot.xml linden/indra/newview/skins/default/xui/fr/floater_sound_preview.xml linden/indra/newview/skins/default/xui/fr/floater_tools.xml linden/indra/newview/skins/default/xui/fr/floater_top_objects.xml linden/indra/newview/skins/default/xui/fr/floater_world_map.xml linden/indra/newview/skins/default/xui/fr/menu_inventory.xml linden/indra/newview/skins/default/xui/fr/menu_login.xml linden/indra/newview/skins/default/xui/fr/menu_pie_attachment.xml linden/indra/newview/skins/default/xui/fr/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/fr/menu_pie_object.xml linden/indra/newview/skins/default/xui/fr/menu_viewer.xml linden/indra/newview/skins/default/xui/fr/notify.xml linden/indra/newview/skins/default/xui/fr/panel_audio.xml linden/indra/newview/skins/default/xui/fr/panel_avatar.xml linden/indra/newview/skins/default/xui/fr/panel_avatar_classified.xml linden/indra/newview/skins/default/xui/fr/panel_classified.xml linden/indra/newview/skins/default/xui/fr/panel_event.xml linden/indra/newview/skins/default/xui/fr/panel_friends.xml linden/indra/newview/skins/default/xui/fr/panel_group_general.xml linden/indra/newview/skins/default/xui/fr/panel_group_invite.xml linden/indra/newview/skins/default/xui/fr/panel_group_land_money.xml linden/indra/newview/skins/default/xui/fr/panel_group_roles.xml linden/indra/newview/skins/default/xui/fr/panel_login.xml linden/indra/newview/skins/default/xui/fr/panel_media_controls.xml linden/indra/newview/skins/default/xui/fr/panel_media_remote_expanded.xml linden/indra/newview/skins/default/xui/fr/panel_overlaybar.xml linden/indra/newview/skins/default/xui/fr/panel_place.xml linden/indra/newview/skins/default/xui/fr/panel_place_small.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_general.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_im.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_input.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_network.xml linden/indra/newview/skins/default/xui/fr/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/fr/panel_region_covenant.xml linden/indra/newview/skins/default/xui/fr/panel_region_debug.xml linden/indra/newview/skins/default/xui/fr/panel_region_general.xml linden/indra/newview/skins/default/xui/fr/panel_voice_controls.xml linden/indra/newview/skins/default/xui/fr/role_actions.xml linden/indra/newview/skins/default/xui/fr/strings.xml linden/indra/newview/skins/default/xui/fr/teleport_strings.xml linden/indra/newview/skins/default/xui/ja/floater_active_speakers.xml linden/indra/newview/skins/default/xui/ja/floater_html.xml linden/indra/newview/skins/default/xui/ja/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/ja/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/ja/floater_joystick.xml linden/indra/newview/skins/default/xui/ja/floater_media_browser.xml linden/indra/newview/skins/default/xui/ja/floater_windlight_options.xml linden/indra/newview/skins/default/xui/ja/menu_login.xml linden/indra/newview/skins/default/xui/ja/panel_friends.xml linden/indra/newview/skins/default/xui/ja/panel_media_controls.xml linden/indra/newview/skins/default/xui/ja/panel_media_remote_expanded.xml linden/indra/newview/skins/default/xui/ja/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/ja/panel_speaker_controls.xml linden/indra/newview/skins/default/xui/ja/strings.xml linden/indra/newview/skins/default/xui/ja/teleport_strings.xml linden/indra/newview/skins/default/xui/ko/panel_media_controls.xml linden/indra/newview/skins/default/xui/pt/alerts.xml linden/indra/newview/skins/default/xui/pt/floater_about.xml linden/indra/newview/skins/default/xui/pt/floater_about_land.xml linden/indra/newview/skins/default/xui/pt/floater_active_speakers.xml linden/indra/newview/skins/default/xui/pt/floater_animation_preview.xml linden/indra/newview/skins/default/xui/pt/floater_auction.xml linden/indra/newview/skins/default/xui/pt/floater_avatar_picker.xml linden/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml linden/indra/newview/skins/default/xui/pt/floater_beacons.xml linden/indra/newview/skins/default/xui/pt/floater_build_options.xml linden/indra/newview/skins/default/xui/pt/floater_bumps.xml linden/indra/newview/skins/default/xui/pt/floater_buy_contents.xml linden/indra/newview/skins/default/xui/pt/floater_buy_currency.xml linden/indra/newview/skins/default/xui/pt/floater_buy_land.xml linden/indra/newview/skins/default/xui/pt/floater_buy_object.xml linden/indra/newview/skins/default/xui/pt/floater_chat_history.xml linden/indra/newview/skins/default/xui/pt/floater_clothing.xml linden/indra/newview/skins/default/xui/pt/floater_color_picker.xml linden/indra/newview/skins/default/xui/pt/floater_critical.xml linden/indra/newview/skins/default/xui/pt/floater_customize.xml linden/indra/newview/skins/default/xui/pt/floater_day_cycle_options.xml linden/indra/newview/skins/default/xui/pt/floater_directory.xml linden/indra/newview/skins/default/xui/pt/floater_env_settings.xml linden/indra/newview/skins/default/xui/pt/floater_gesture.xml linden/indra/newview/skins/default/xui/pt/floater_god_tools.xml linden/indra/newview/skins/default/xui/pt/floater_group_info.xml linden/indra/newview/skins/default/xui/pt/floater_im.xml linden/indra/newview/skins/default/xui/pt/floater_image_preview.xml linden/indra/newview/skins/default/xui/pt/floater_inspect.xml linden/indra/newview/skins/default/xui/pt/floater_instant_message.xml linden/indra/newview/skins/default/xui/pt/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/pt/floater_instant_message_group.xml linden/indra/newview/skins/default/xui/pt/floater_inventory.xml linden/indra/newview/skins/default/xui/pt/floater_inventory_item_properties.xml linden/indra/newview/skins/default/xui/pt/floater_inventory_view_finder.xml linden/indra/newview/skins/default/xui/pt/floater_joystick.xml linden/indra/newview/skins/default/xui/pt/floater_lagmeter.xml linden/indra/newview/skins/default/xui/pt/floater_land_holdings.xml linden/indra/newview/skins/default/xui/pt/floater_landmark_ctrl.xml linden/indra/newview/skins/default/xui/pt/floater_live_lsleditor.xml linden/indra/newview/skins/default/xui/pt/floater_lsl_guide.xml linden/indra/newview/skins/default/xui/pt/floater_media_browser.xml linden/indra/newview/skins/default/xui/pt/floater_moveview.xml linden/indra/newview/skins/default/xui/pt/floater_mute.xml linden/indra/newview/skins/default/xui/pt/floater_mute_object.xml linden/indra/newview/skins/default/xui/pt/floater_name_description.xml linden/indra/newview/skins/default/xui/pt/floater_new_outfit_dialog.xml linden/indra/newview/skins/default/xui/pt/floater_openobject.xml linden/indra/newview/skins/default/xui/pt/floater_pay.xml linden/indra/newview/skins/default/xui/pt/floater_postcard.xml linden/indra/newview/skins/default/xui/pt/floater_preferences.xml linden/indra/newview/skins/default/xui/pt/floater_preview_animation.xml linden/indra/newview/skins/default/xui/pt/floater_preview_classified.xml linden/indra/newview/skins/default/xui/pt/floater_preview_event.xml linden/indra/newview/skins/default/xui/pt/floater_preview_gesture.xml linden/indra/newview/skins/default/xui/pt/floater_preview_notecard_keep_discard.xml linden/indra/newview/skins/default/xui/pt/floater_preview_sound.xml linden/indra/newview/skins/default/xui/pt/floater_preview_url.xml linden/indra/newview/skins/default/xui/pt/floater_price_for_listing.xml linden/indra/newview/skins/default/xui/pt/floater_profile.xml linden/indra/newview/skins/default/xui/pt/floater_report_abuse.xml linden/indra/newview/skins/default/xui/pt/floater_script_debug.xml linden/indra/newview/skins/default/xui/pt/floater_script_queue.xml linden/indra/newview/skins/default/xui/pt/floater_script_search.xml linden/indra/newview/skins/default/xui/pt/floater_sell_land.xml linden/indra/newview/skins/default/xui/pt/floater_settings_debug.xml linden/indra/newview/skins/default/xui/pt/floater_sim_release_message.xml linden/indra/newview/skins/default/xui/pt/floater_snapshot.xml linden/indra/newview/skins/default/xui/pt/floater_sound_preview.xml linden/indra/newview/skins/default/xui/pt/floater_telehub.xml linden/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml linden/indra/newview/skins/default/xui/pt/floater_tools.xml linden/indra/newview/skins/default/xui/pt/floater_top_objects.xml linden/indra/newview/skins/default/xui/pt/floater_tos.xml linden/indra/newview/skins/default/xui/pt/floater_url_entry.xml linden/indra/newview/skins/default/xui/pt/floater_water.xml linden/indra/newview/skins/default/xui/pt/floater_wearable_save_as.xml linden/indra/newview/skins/default/xui/pt/floater_windlight_options.xml linden/indra/newview/skins/default/xui/pt/floater_world_map.xml linden/indra/newview/skins/default/xui/pt/menu_inventory.xml linden/indra/newview/skins/default/xui/pt/menu_pie_attachment.xml linden/indra/newview/skins/default/xui/pt/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/pt/menu_pie_land.xml linden/indra/newview/skins/default/xui/pt/menu_pie_object.xml linden/indra/newview/skins/default/xui/pt/menu_viewer.xml linden/indra/newview/skins/default/xui/pt/notify.xml linden/indra/newview/skins/default/xui/pt/panel_account_details.xml linden/indra/newview/skins/default/xui/pt/panel_account_planning.xml linden/indra/newview/skins/default/xui/pt/panel_account_transactions.xml linden/indra/newview/skins/default/xui/pt/panel_audio_device.xml linden/indra/newview/skins/default/xui/pt/panel_avatar.xml linden/indra/newview/skins/default/xui/pt/panel_avatar_classified.xml linden/indra/newview/skins/default/xui/pt/panel_avatar_pick.xml linden/indra/newview/skins/default/xui/pt/panel_chat_bar.xml linden/indra/newview/skins/default/xui/pt/panel_classified.xml linden/indra/newview/skins/default/xui/pt/panel_event.xml linden/indra/newview/skins/default/xui/pt/panel_friends.xml linden/indra/newview/skins/default/xui/pt/panel_group.xml linden/indra/newview/skins/default/xui/pt/panel_group_finder.xml linden/indra/newview/skins/default/xui/pt/panel_group_general.xml linden/indra/newview/skins/default/xui/pt/panel_group_invite.xml linden/indra/newview/skins/default/xui/pt/panel_group_land_money.xml linden/indra/newview/skins/default/xui/pt/panel_group_notices.xml linden/indra/newview/skins/default/xui/pt/panel_group_roles.xml linden/indra/newview/skins/default/xui/pt/panel_group_voting.xml linden/indra/newview/skins/default/xui/pt/panel_land_covenant.xml linden/indra/newview/skins/default/xui/pt/panel_login.xml linden/indra/newview/skins/default/xui/pt/panel_overlaybar.xml linden/indra/newview/skins/default/xui/pt/panel_place.xml linden/indra/newview/skins/default/xui/pt/panel_place_small.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_general.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_im.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_input.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_network.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_popups.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_voice.xml linden/indra/newview/skins/default/xui/pt/panel_preferences_web.xml linden/indra/newview/skins/default/xui/pt/panel_region_covenant.xml linden/indra/newview/skins/default/xui/pt/panel_region_debug.xml linden/indra/newview/skins/default/xui/pt/panel_region_estate.xml linden/indra/newview/skins/default/xui/pt/panel_region_general.xml linden/indra/newview/skins/default/xui/pt/panel_region_terrain.xml linden/indra/newview/skins/default/xui/pt/panel_region_texture.xml linden/indra/newview/skins/default/xui/pt/panel_scrolling_param.xml linden/indra/newview/skins/default/xui/pt/panel_speaker_controls.xml linden/indra/newview/skins/default/xui/pt/panel_status_bar.xml linden/indra/newview/skins/default/xui/pt/panel_toolbar.xml linden/indra/newview/skins/default/xui/pt/panel_top_pick.xml linden/indra/newview/skins/default/xui/pt/panel_voice_controls.xml linden/indra/newview/skins/default/xui/pt/panel_voice_enable.xml linden/indra/newview/skins/default/xui/pt/panel_voice_options.xml linden/indra/newview/skins/default/xui/pt/strings.xml linden/indra/newview/skins/default/xui/pt/teleport_strings.xml linden/indra/newview/skins/default/xui/zh/floater_env_settings.xml linden/indra/newview/skins/default/xui/zh/floater_instant_message_ad_hoc.xml linden/indra/newview/skins/default/xui/zh/floater_lagmeter.xml linden/indra/newview/skins/default/xui/zh/floater_landmark_ctrl.xml linden/indra/newview/skins/default/xui/zh/floater_post_process.xml linden/indra/newview/skins/default/xui/zh/floater_settings_debug.xml linden/indra/newview/skins/default/xui/zh/floater_windlight_options.xml linden/indra/newview/skins/default/xui/zh/menu_pie_attachment.xml linden/indra/newview/skins/default/xui/zh/menu_pie_avatar.xml linden/indra/newview/skins/default/xui/zh/menu_pie_land.xml linden/indra/newview/skins/default/xui/zh/menu_pie_object.xml linden/indra/newview/skins/default/xui/zh/menu_viewer.xml linden/indra/newview/skins/default/xui/zh/panel_avatar.xml linden/indra/newview/skins/default/xui/zh/panel_friends.xml linden/indra/newview/skins/default/xui/zh/panel_group_general.xml linden/indra/newview/skins/default/xui/zh/panel_group_invite.xml linden/indra/newview/skins/default/xui/zh/panel_group_land_money.xml linden/indra/newview/skins/default/xui/zh/panel_group_notices.xml linden/indra/newview/skins/default/xui/zh/panel_group_roles.xml linden/indra/newview/skins/default/xui/zh/panel_preferences_audio.xml linden/indra/newview/skins/default/xui/zh/panel_preferences_im.xml linden/indra/newview/skins/default/xui/zh/panel_region_covenant.xml linden/indra/newview/skins/default/xui/zh/panel_speaker_controls.xml linden/indra/newview/skins/default/xui/zh/panel_voice_options.xml linden/indra/newview/skins/default/xui/zh/strings.xml linden/indra/newview/skins/silver/colors_base.xml linden/indra/newview/skins/silver/xui/en-us/floater_about_land.xml linden/indra/newview/skins/silver/xui/en-us/floater_directory.xml linden/indra/newview/skins/silver/xui/en-us/floater_tools.xml linden/indra/newview/skins/silver/xui/en-us/panel_media_controls.xml linden/indra/newview/viewer_manifest.py linden/install.xml
Diffstat (limited to 'linden/indra/newview/llviewermessage.cpp')
-rw-r--r--linden/indra/newview/llviewermessage.cpp1413
1 files changed, 844 insertions, 569 deletions
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 3fb8e9a..5d83065 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -18,7 +18,8 @@
18 * There are special exceptions to the terms and conditions of the GPL as 18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 21 * online at
22 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 23 *
23 * By copying, modifying or distributing this software, you acknowledge 24 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 25 * that you have read and understood your obligations described above,
@@ -72,6 +73,7 @@
72#include "lldrawpool.h" 73#include "lldrawpool.h"
73#include "llfirstuse.h" 74#include "llfirstuse.h"
74#include "llfloateractivespeakers.h" 75#include "llfloateractivespeakers.h"
76#include "llfloateranimpreview.h"
75#include "llfloaterbuycurrency.h" 77#include "llfloaterbuycurrency.h"
76#include "llfloaterbuyland.h" 78#include "llfloaterbuyland.h"
77#include "llfloaterchat.h" 79#include "llfloaterchat.h"
@@ -94,6 +96,7 @@
94#include "llinventoryview.h" 96#include "llinventoryview.h"
95#include "llmenugl.h" 97#include "llmenugl.h"
96#include "llmutelist.h" 98#include "llmutelist.h"
99#include "llnotifications.h"
97#include "llnotify.h" 100#include "llnotify.h"
98#include "llpanelgrouplandmoney.h" 101#include "llpanelgrouplandmoney.h"
99#include "llselectmgr.h" 102#include "llselectmgr.h"
@@ -130,7 +133,6 @@
130#include "pipeline.h" 133#include "pipeline.h"
131#include "llappviewer.h" 134#include "llappviewer.h"
132#include "llfloaterworldmap.h" 135#include "llfloaterworldmap.h"
133#include "llkeythrottle.h"
134#include "llviewerdisplay.h" 136#include "llviewerdisplay.h"
135#include "llkeythrottle.h" 137#include "llkeythrottle.h"
136 138
@@ -156,7 +158,6 @@ extern BOOL gDebugClicks;
156 158
157// function prototypes 159// function prototypes
158void open_offer(const std::vector<LLUUID>& items, const std::string& from_name); 160void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
159void friendship_offer_callback(S32 option, void* user_data);
160bool check_offer_throttle(const std::string& from_name, bool check_only); 161bool check_offer_throttle(const std::string& from_name, bool check_only);
161void callbackCacheEstateOwnerName(const LLUUID& id, 162void callbackCacheEstateOwnerName(const LLUUID& id,
162 const std::string& first, const std::string& last, 163 const std::string& first, const std::string& last,
@@ -183,14 +184,68 @@ const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] =
183 "ControlYourCamera" 184 "ControlYourCamera"
184 }; 185 };
185 186
186struct LLFriendshipOffer 187const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
187{ 188{
188 LLUUID mFromID; 189 TRUE, // ScriptTakeMoney,
189 LLUUID mTransactionID; 190 FALSE, // ActOnControlInputs
190 BOOL mOnline; 191 FALSE, // RemapControlInputs
191 LLHost mHost; 192 FALSE, // AnimateYourAvatar
193 FALSE, // AttachToYourAvatar
194 FALSE, // ReleaseOwnership,
195 FALSE, // LinkAndDelink,
196 FALSE, // AddAndRemoveJoints
197 FALSE, // ChangePermissions
198 FALSE, // TrackYourCamera,
199 FALSE // ControlYourCamera
192}; 200};
193 201
202bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
203{
204 S32 option = LLNotification::getSelectedOption(notification, response);
205 LLUUID fid;
206 LLMessageSystem* msg = gMessageSystem;
207 const LLSD& payload = notification["payload"];
208 switch(option)
209 {
210 case 0:
211 // accept
212 LLAvatarTracker::formFriendship(payload["from_id"]);
213
214 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
215
216 // This will also trigger an onlinenotification if the user is online
217 msg->newMessageFast(_PREHASH_AcceptFriendship);
218 msg->nextBlockFast(_PREHASH_AgentData);
219 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
220 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
221 msg->nextBlockFast(_PREHASH_TransactionBlock);
222 msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
223 msg->nextBlockFast(_PREHASH_FolderData);
224 msg->addUUIDFast(_PREHASH_FolderID, fid);
225 msg->sendReliable(LLHost(payload["sender"].asString()));
226 break;
227 case 1:
228 // decline
229 // We no longer notify other viewers, but we DO still send
230 // the rejection to the simulator to delete the pending userop.
231 msg->newMessageFast(_PREHASH_DeclineFriendship);
232 msg->nextBlockFast(_PREHASH_AgentData);
233 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
234 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
235 msg->nextBlockFast(_PREHASH_TransactionBlock);
236 msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
237 msg->sendReliable(LLHost(payload["sender"].asString()));
238 break;
239 default:
240 // close button probably, possibly timed out
241 break;
242 }
243
244 return false;
245}
246static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
247static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
248
194//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have " 249//const char BUSY_AUTO_RESPONSE[] = "The Resident you messaged is in 'busy mode' which means they have "
195// "requested not to be disturbed. Your message will still be shown in their IM " 250// "requested not to be disturbed. Your message will still be shown in their IM "
196// "panel for later viewing."; 251// "panel for later viewing.";
@@ -562,34 +617,31 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
562 gAgent.sendMessage(); 617 gAgent.sendMessage();
563} 618}
564 619
565struct LLJoinGroupData 620bool join_group_response(const LLSD& notification, const LLSD& response)
566{
567 LLUUID mGroupID;
568 LLUUID mTransactionID;
569 std::string mName;
570 std::string mMessage;
571 S32 mFee;
572};
573
574void join_group_callback(S32 option, void* user_data)
575{ 621{
576 LLJoinGroupData* data = (LLJoinGroupData*)user_data; 622 S32 option = LLNotification::getSelectedOption(notification, response);
577 BOOL delete_context_data = TRUE; 623 BOOL delete_context_data = TRUE;
578 bool accept_invite = false; 624 bool accept_invite = false;
579 625
580 if (option == 2 && data && !data->mGroupID.isNull()) 626 LLUUID group_id = notification["payload"]["group_id"].asUUID();
627 LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
628 std::string name = notification["payload"]["name"].asString();
629 std::string message = notification["payload"]["message"].asString();
630 S32 fee = notification["payload"]["fee"].asInteger();
631
632 if (option == 2 && !group_id.isNull())
581 { 633 {
582 LLFloaterGroupInfo::showFromUUID(data->mGroupID); 634 LLFloaterGroupInfo::showFromUUID(group_id);
583 LLStringUtil::format_map_t args; 635 LLSD args;
584 args["[MESSAGE]"] = data->mMessage; 636 args["MESSAGE"] = message;
585 LLNotifyBox::showXml("JoinGroup", args, &join_group_callback, data); 637 LLNotifications::instance().add("JoinGroup", args, notification["payload"]);
586 return; 638 return false;
587 } 639 }
588 if(option == 0 && data && !data->mGroupID.isNull()) 640 if(option == 0 && !group_id.isNull())
589 { 641 {
590 // check for promotion or demotion. 642 // check for promotion or demotion.
591 S32 max_groups = MAX_AGENT_GROUPS; 643 S32 max_groups = MAX_AGENT_GROUPS;
592 if(gAgent.isInGroup(data->mGroupID)) ++max_groups; 644 if(gAgent.isInGroup(group_id)) ++max_groups;
593 645
594 if(gAgent.mGroups.count() < max_groups) 646 if(gAgent.mGroups.count() < max_groups)
595 { 647 {
@@ -598,10 +650,10 @@ void join_group_callback(S32 option, void* user_data)
598 else 650 else
599 { 651 {
600 delete_context_data = FALSE; 652 delete_context_data = FALSE;
601 LLStringUtil::format_map_t args; 653 LLSD args;
602 args["[NAME]"] = data->mName; 654 args["NAME"] = name;
603 args["[INVITE]"] = data->mMessage; 655 args["INVITE"] = message;
604 LLAlertDialog::showXml("JoinedTooManyGroupsMember", args, join_group_callback, (void*)data); 656 LLNotifications::instance().add("JoinedTooManyGroupsMember", args, notification["payload"]);
605 } 657 }
606 } 658 }
607 659
@@ -609,45 +661,44 @@ void join_group_callback(S32 option, void* user_data)
609 { 661 {
610 // If there is a fee to join this group, make 662 // If there is a fee to join this group, make
611 // sure the user is sure they want to join. 663 // sure the user is sure they want to join.
612 if (data->mFee > 0) 664 if (fee > 0)
613 { 665 {
614 delete_context_data = FALSE; 666 delete_context_data = FALSE;
615 LLStringUtil::format_map_t args; 667 LLSD args;
616 args["[COST]"] = llformat("%d", data->mFee); 668 args["COST"] = llformat("%d", fee);
617 // Set the fee to 0, so that we don't keep 669 // Set the fee for next time to 0, so that we don't keep
618 // asking about a fee. 670 // asking about a fee.
619 data->mFee = 0; 671 LLSD next_payload = notification["payload"];
620 gViewerWindow->alertXml("JoinGroupCanAfford", 672 next_payload["fee"] = 0;
673 LLNotifications::instance().add("JoinGroupCanAfford",
621 args, 674 args,
622 join_group_callback, 675 next_payload);
623 (void*)data);
624 } 676 }
625 else 677 else
626 { 678 {
627 send_improved_im(data->mGroupID, 679 send_improved_im(group_id,
628 std::string("name"), 680 std::string("name"),
629 std::string("message"), 681 std::string("message"),
630 IM_ONLINE, 682 IM_ONLINE,
631 IM_GROUP_INVITATION_ACCEPT, 683 IM_GROUP_INVITATION_ACCEPT,
632 data->mTransactionID); 684 transaction_id);
633 } 685 }
634 } 686 }
635 else if (data) 687 else
636 { 688 {
637 send_improved_im(data->mGroupID, 689 send_improved_im(group_id,
638 std::string("name"), 690 std::string("name"),
639 std::string("message"), 691 std::string("message"),
640 IM_ONLINE, 692 IM_ONLINE,
641 IM_GROUP_INVITATION_DECLINE, 693 IM_GROUP_INVITATION_DECLINE,
642 data->mTransactionID); 694 transaction_id);
643 } 695 }
644 696
645 if(delete_context_data) 697 return false;
646 {
647 delete data;
648 data = NULL;
649 }
650} 698}
699static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);
700static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);
701static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response);
651 702
652 703
653//----------------------------------------------------------------------------- 704//-----------------------------------------------------------------------------
@@ -671,7 +722,7 @@ private:
671//instance of the AddedObserver for TaskOffers 722//instance of the AddedObserver for TaskOffers
672//and it never dies. We do this because we don't know the UUID of 723//and it never dies. We do this because we don't know the UUID of
673//task offers until they are accepted, so we don't wouldn't 724//task offers until they are accepted, so we don't wouldn't
674//know what to watch for, so instead we just watch for all additions. -Gigs 725//know what to watch for, so instead we just watch for all additions.
675class LLOpenTaskOffer : public LLInventoryAddedObserver 726class LLOpenTaskOffer : public LLInventoryAddedObserver
676{ 727{
677protected: 728protected:
@@ -747,7 +798,7 @@ protected:
747 798
748//Returns TRUE if we are OK, FALSE if we are throttled 799//Returns TRUE if we are OK, FALSE if we are throttled
749//Set check_only true if you want to know the throttle status 800//Set check_only true if you want to know the throttle status
750//without registering a hit -Gigs 801//without registering a hit
751bool check_offer_throttle(const std::string& from_name, bool check_only) 802bool check_offer_throttle(const std::string& from_name, bool check_only)
752{ 803{
753 static U32 throttle_count; 804 static U32 throttle_count;
@@ -774,14 +825,14 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
774 { 825 {
775 LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL; 826 LL_DEBUGS("Messaging") << "Throttle Not Expired, Count: " << throttle_count << LL_ENDL;
776 // When downloading the initial inventory we get a lot of new items 827 // When downloading the initial inventory we get a lot of new items
777 // coming in and can't tell that from spam. JC 828 // coming in and can't tell that from spam.
778 if (LLStartUp::getStartupState() >= STATE_STARTED 829 if (LLStartUp::getStartupState() >= STATE_STARTED
779 && throttle_count >= OFFER_THROTTLE_MAX_COUNT) 830 && throttle_count >= OFFER_THROTTLE_MAX_COUNT)
780 { 831 {
781 if (!throttle_logged) 832 if (!throttle_logged)
782 { 833 {
783 // Use the name of the last item giver, who is probably the person 834 // Use the name of the last item giver, who is probably the person
784 // spamming you. JC 835 // spamming you.
785 std::ostringstream message; 836 std::ostringstream message;
786 message << LLAppViewer::instance()->getSecondLifeTitle(); 837 message << LLAppViewer::instance()->getSecondLifeTitle();
787 if (!from_name.empty()) 838 if (!from_name.empty())
@@ -829,12 +880,12 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
829 } 880 }
830 LLAssetType::EType asset_type = item->getType(); 881 LLAssetType::EType asset_type = item->getType();
831 882
832 //if we are throttled, don't display them - Gigs 883 //if we are throttled, don't display them
833 if (check_offer_throttle(from_name, false)) 884 if (check_offer_throttle(from_name, false))
834 { 885 {
835 // I'm not sure this is a good idea. JC - Definitely a bad idea. HB 886 // I'm not sure this is a good idea.
836 //bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID(); 887 bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
837 bool show_keep_discard = true; 888 //bool show_keep_discard = true;
838 switch(asset_type) 889 switch(asset_type)
839 { 890 {
840 case LLAssetType::AT_NOTECARD: 891 case LLAssetType::AT_NOTECARD:
@@ -884,7 +935,7 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
884 return; 935 return;
885 } 936 }
886 937
887 //Not sure about this check. Could make it easy to miss incoming items. -Gigs 938 //Not sure about this check. Could make it easy to miss incoming items.
888 //don't dick with highlight while the user is working 939 //don't dick with highlight while the user is working
889 //if(inventory_has_focus && !user_is_away) 940 //if(inventory_has_focus && !user_is_away)
890 // break; 941 // break;
@@ -929,9 +980,15 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
929 { 980 {
930 public: 981 public:
931 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {} 982 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
932 BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const 983 BOOL matches(const LLNotificationPtr notification) const
933 { 984 {
934 return callback == inventory_offer_callback && ((LLOfferInfo*)cb_data)->mFromID == blocked_id; 985 if(notification->getName() == "ObjectGiveItem"
986 || notification->getName() == "ObjectGiveItemUnknownUser"
987 || notification->getName() == "UserGiveItem")
988 {
989 return (notification->getPayload()["from_id"].asUUID() == blocked_id);
990 }
991 return FALSE;
935 } 992 }
936 private: 993 private:
937 const LLUUID& blocked_id; 994 const LLUUID& blocked_id;
@@ -939,21 +996,52 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
939 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id)); 996 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id));
940} 997}
941 998
942void inventory_offer_callback(S32 button, void* user_data) 999LLOfferInfo::LLOfferInfo(const LLSD& sd)
1000{
1001 mIM = (EInstantMessage)sd["im_type"].asInteger();
1002 mFromID = sd["from_id"].asUUID();
1003 mFromGroup = sd["from_group"].asBoolean();
1004 mFromObject = sd["from_object"].asBoolean();
1005 mTransactionID = sd["transaction_id"].asUUID();
1006 mFolderID = sd["folder_id"].asUUID();
1007 mObjectID = sd["object_id"].asUUID();
1008 mType = LLAssetType::lookup(sd["type"].asString().c_str());
1009 mFromName = sd["from_name"].asString();
1010 mDesc = sd["description"].asString();
1011 mHost = LLHost(sd["sender"].asString());
1012}
1013
1014LLSD LLOfferInfo::asLLSD()
1015{
1016 LLSD sd;
1017 sd["im_type"] = mIM;
1018 sd["from_id"] = mFromID;
1019 sd["from_group"] = mFromGroup;
1020 sd["from_object"] = mFromObject;
1021 sd["transaction_id"] = mTransactionID;
1022 sd["folder_id"] = mFolderID;
1023 sd["object_id"] = mObjectID;
1024 sd["type"] = LLAssetType::lookup(mType);
1025 sd["from_name"] = mFromName;
1026 sd["description"] = mDesc;
1027 sd["sender"] = mHost.getIPandPort();
1028 return sd;
1029}
1030
1031bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
943 { 1032 {
944 LLChat chat; 1033 LLChat chat;
945 std::string log_message; 1034 std::string log_message;
946 LLOfferInfo* info = (LLOfferInfo*)user_data; 1035 S32 button = LLNotification::getSelectedOption(notification, response);
947 if(!info) return;
948 1036
949 // For muting, we need to add the mute, then decline the offer. 1037 // For muting, we need to add the mute, then decline the offer.
950 // This must be done here because: 1038 // This must be done here because:
951 // * callback may be called immediately, 1039 // * callback may be called immediately,
952 // * adding the mute sends a message, 1040 // * adding the mute sends a message,
953 // * we can't build two messages at once. JC 1041 // * we can't build two messages at once.
954 if (2 == button) 1042 if (2 == button)
955 { 1043 {
956 gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, user_data); 1044 gCacheName->get(mFromID, mFromGroup, inventory_offer_mute_callback, this);
957 } 1045 }
958 1046
959 LLMessageSystem* msg = gMessageSystem; 1047 LLMessageSystem* msg = gMessageSystem;
@@ -963,9 +1051,9 @@ void inventory_offer_callback(S32 button, void* user_data)
963 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 1051 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
964 msg->nextBlockFast(_PREHASH_MessageBlock); 1052 msg->nextBlockFast(_PREHASH_MessageBlock);
965 msg->addBOOLFast(_PREHASH_FromGroup, FALSE); 1053 msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
966 msg->addUUIDFast(_PREHASH_ToAgentID, info->mFromID); 1054 msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
967 msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); 1055 msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
968 msg->addUUIDFast(_PREHASH_ID, info->mTransactionID); 1056 msg->addUUIDFast(_PREHASH_ID, mTransactionID);
969 msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary 1057 msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
970 std::string name; 1058 std::string name;
971 gAgent.buildFullname(name); 1059 gAgent.buildFullname(name);
@@ -976,50 +1064,50 @@ void inventory_offer_callback(S32 button, void* user_data)
976 msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); 1064 msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
977 LLInventoryObserver* opener = NULL; 1065 LLInventoryObserver* opener = NULL;
978 LLViewerInventoryCategory* catp = NULL; 1066 LLViewerInventoryCategory* catp = NULL;
979 catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID); 1067 catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
980 LLViewerInventoryItem* itemp = NULL; 1068 LLViewerInventoryItem* itemp = NULL;
981 if(!catp) 1069 if(!catp)
982 { 1070 {
983 itemp = (LLViewerInventoryItem*)gInventory.getItem(info->mObjectID); 1071 itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
984 } 1072 }
985 1073
986 // *TODO:translate 1074 // *TODO:translate
987 std::string from_string; // Used in the pop-up. 1075 std::string from_string; // Used in the pop-up.
988 std::string chatHistory_string; // Used in chat history. 1076 std::string chatHistory_string; // Used in chat history.
989 if (info->mFromObject == TRUE) 1077 if (mFromObject == TRUE)
990 { 1078 {
991 if (info->mFromGroup) 1079 if (mFromGroup)
992 { 1080 {
993 std::string group_name; 1081 std::string group_name;
994 if (gCacheName->getGroupName(info->mFromID, group_name)) 1082 if (gCacheName->getGroupName(mFromID, group_name))
995 { 1083 {
996 from_string = std::string("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'"; 1084 from_string = std::string("An object named '") + mFromName + "' owned by the group '" + group_name + "'";
997 chatHistory_string = info->mFromName + " owned by the group '" + group_name + "'"; 1085 chatHistory_string = mFromName + " owned by the group '" + group_name + "'";
998 } 1086 }
999 else 1087 else
1000 { 1088 {
1001 from_string = std::string("An object named '") + info->mFromName + "' owned by an unknown group"; 1089 from_string = std::string("An object named '") + mFromName + "' owned by an unknown group";
1002 chatHistory_string = info->mFromName + " owned by an unknown group"; 1090 chatHistory_string = mFromName + " owned by an unknown group";
1003 } 1091 }
1004 } 1092 }
1005 else 1093 else
1006 { 1094 {
1007 std::string first_name, last_name; 1095 std::string first_name, last_name;
1008 if (gCacheName->getName(info->mFromID, first_name, last_name)) 1096 if (gCacheName->getName(mFromID, first_name, last_name))
1009 { 1097 {
1010 from_string = std::string("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name; 1098 from_string = std::string("An object named '") + mFromName + "' owned by " + first_name + " " + last_name;
1011 chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name; 1099 chatHistory_string = mFromName + " owned by " + first_name + " " + last_name;
1012 } 1100 }
1013 else 1101 else
1014 { 1102 {
1015 from_string = std::string("An object named '") + info->mFromName + "' owned by an unknown user"; 1103 from_string = std::string("An object named '") + mFromName + "' owned by an unknown user";
1016 chatHistory_string = info->mFromName + " owned by an unknown user"; 1104 chatHistory_string = mFromName + " owned by an unknown user";
1017 } 1105 }
1018 } 1106 }
1019 } 1107 }
1020 else 1108 else
1021 { 1109 {
1022 from_string = chatHistory_string = info->mFromName; 1110 from_string = chatHistory_string = mFromName;
1023 } 1111 }
1024 1112
1025 bool busy=FALSE; 1113 bool busy=FALSE;
@@ -1032,24 +1120,24 @@ void inventory_offer_callback(S32 button, void* user_data)
1032 // group_notice_inventory is 1 greater than the offer integer value. 1120 // group_notice_inventory is 1 greater than the offer integer value.
1033 // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 1121 // Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED,
1034 // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED 1122 // or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
1035 msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 1)); 1123 msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
1036 msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(info->mFolderID.mData), 1124 msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
1037 sizeof(info->mFolderID.mData)); 1125 sizeof(mFolderID.mData));
1038 // send the message 1126 // send the message
1039 msg->sendReliable(info->mHost); 1127 msg->sendReliable(mHost);
1040 1128
1041 //don't spam them if they are getting flooded 1129 //don't spam them if they are getting flooded
1042 if (check_offer_throttle(info->mFromName, true)) 1130 if (check_offer_throttle(mFromName, true))
1043 { 1131 {
1044 log_message = chatHistory_string + " gave you " + info->mDesc + "."; 1132 log_message = chatHistory_string + " gave you " + mDesc + ".";
1045 chat.mText = log_message; 1133 chat.mText = log_message;
1046 LLFloaterChat::addChatHistory(chat); 1134 LLFloaterChat::addChatHistory(chat);
1047 } 1135 }
1048 1136
1049 // we will want to open this item when it comes back. 1137 // we will want to open this item when it comes back.
1050 LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << info->mTransactionID 1138 LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
1051 << LL_ENDL; 1139 << LL_ENDL;
1052 switch (info->mIM) 1140 switch (mIM)
1053 { 1141 {
1054 case IM_INVENTORY_OFFERED: 1142 case IM_INVENTORY_OFFERED:
1055 { 1143 {
@@ -1057,7 +1145,7 @@ void inventory_offer_callback(S32 button, void* user_data)
1057 // end has already copied the items into your inventory, 1145 // end has already copied the items into your inventory,
1058 // so we can fetch it out of our inventory. 1146 // so we can fetch it out of our inventory.
1059 LLInventoryFetchObserver::item_ref_t items; 1147 LLInventoryFetchObserver::item_ref_t items;
1060 items.push_back(info->mObjectID); 1148 items.push_back(mObjectID);
1061 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string); 1149 LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
1062 open_agent_offer->fetchItems(items); 1150 open_agent_offer->fetchItems(items);
1063 if(catp || (itemp && itemp->isComplete())) 1151 if(catp || (itemp && itemp->isComplete()))
@@ -1083,7 +1171,7 @@ void inventory_offer_callback(S32 button, void* user_data)
1083 default: 1171 default:
1084 LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL; 1172 LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
1085 break; 1173 break;
1086 } // end switch (info->mIM) 1174 } // end switch (mIM)
1087 break; 1175 break;
1088 1176
1089 case IOR_BUSY: 1177 case IOR_BUSY:
@@ -1099,14 +1187,14 @@ void inventory_offer_callback(S32 button, void* user_data)
1099 // or IM_GROUP_NOTICE_INVENTORY_DECLINED 1187 // or IM_GROUP_NOTICE_INVENTORY_DECLINED
1100 default: 1188 default:
1101 // close button probably (or any of the fall-throughs from above) 1189 // close button probably (or any of the fall-throughs from above)
1102 msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 2)); 1190 msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
1103 msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE); 1191 msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
1104 // send the message 1192 // send the message
1105 msg->sendReliable(info->mHost); 1193 msg->sendReliable(mHost);
1106 1194
1107 log_message = "You decline " + info->mDesc + " from " + info->mFromName + "."; 1195 log_message = "You decline " + mDesc + " from " + mFromName + ".";
1108 chat.mText = log_message; 1196 chat.mText = log_message;
1109 if( LLMuteList::getInstance()->isMuted(info->mFromID ) && ! LLMuteList::getInstance()->isLinden(info->mFromName) ) // muting for SL-42269 1197 if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269
1110 { 1198 {
1111 chat.mMuted = TRUE; 1199 chat.mMuted = TRUE;
1112 } 1200 }
@@ -1115,13 +1203,13 @@ void inventory_offer_callback(S32 button, void* user_data)
1115 // If it's from an agent, we have to fetch the item to throw 1203 // If it's from an agent, we have to fetch the item to throw
1116 // it away. If it's from a task or group, just denying the 1204 // it away. If it's from a task or group, just denying the
1117 // request will suffice to discard the item. 1205 // request will suffice to discard the item.
1118 if(IM_INVENTORY_OFFERED == info->mIM) 1206 if(IM_INVENTORY_OFFERED == mIM)
1119 { 1207 {
1120 LLInventoryFetchComboObserver::folder_ref_t folders; 1208 LLInventoryFetchComboObserver::folder_ref_t folders;
1121 LLInventoryFetchComboObserver::item_ref_t items; 1209 LLInventoryFetchComboObserver::item_ref_t items;
1122 items.push_back(info->mObjectID); 1210 items.push_back(mObjectID);
1123 LLDiscardAgentOffer* discard_agent_offer; 1211 LLDiscardAgentOffer* discard_agent_offer;
1124 discard_agent_offer = new LLDiscardAgentOffer(info->mFolderID, info->mObjectID); 1212 discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
1125 discard_agent_offer->fetch(folders, items); 1213 discard_agent_offer->fetch(folders, items);
1126 if(catp || (itemp && itemp->isComplete())) 1214 if(catp || (itemp && itemp->isComplete()))
1127 { 1215 {
@@ -1133,9 +1221,9 @@ void inventory_offer_callback(S32 button, void* user_data)
1133 } 1221 }
1134 1222
1135 } 1223 }
1136 if (busy && (!info->mFromGroup && !info->mFromObject)) 1224 if (busy && (!mFromGroup && !mFromObject))
1137 { 1225 {
1138 busy_message(msg,info->mFromID); 1226 busy_message(msg,mFromID);
1139 } 1227 }
1140 break; 1228 break;
1141 } 1229 }
@@ -1145,12 +1233,12 @@ void inventory_offer_callback(S32 button, void* user_data)
1145 gInventory.addObserver(opener); 1233 gInventory.addObserver(opener);
1146 } 1234 }
1147 1235
1148 delete info;
1149 info = NULL;
1150
1151 // Allow these to stack up, but once you deal with one, reset the 1236 // Allow these to stack up, but once you deal with one, reset the
1152 // position. 1237 // position.
1153 gFloaterView->resetStartingFloaterPosition(); 1238 gFloaterView->resetStartingFloaterPosition();
1239
1240 delete this;
1241 return false;
1154} 1242}
1155 1243
1156 1244
@@ -1160,14 +1248,14 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1160 //accepting it. SEE SL-39554 1248 //accepting it. SEE SL-39554
1161 if (gAgent.getBusy()) 1249 if (gAgent.getBusy())
1162 { 1250 {
1163 inventory_offer_callback(IOR_BUSY, info); 1251 info->forceResponse(IOR_BUSY);
1164 return; 1252 return;
1165 } 1253 }
1166 1254
1167 //If muted, don't even go through the messaging stuff. Just curtail the offer here. 1255 //If muted, don't even go through the messaging stuff. Just curtail the offer here.
1168 if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName)) 1256 if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
1169 { 1257 {
1170 inventory_offer_callback(IOR_MUTE, info); 1258 info->forceResponse(IOR_MUTE);
1171 return; 1259 return;
1172 } 1260 }
1173 1261
@@ -1179,7 +1267,7 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1179 { 1267 {
1180 // For certain types, just accept the items into the inventory, 1268 // For certain types, just accept the items into the inventory,
1181 // and possibly open them on receipt depending upon "ShowNewInventory". 1269 // and possibly open them on receipt depending upon "ShowNewInventory".
1182 inventory_offer_callback(IOR_ACCEPT, info); 1270 info->forceResponse(IOR_ACCEPT);
1183 return; 1271 return;
1184 } 1272 }
1185 1273
@@ -1191,36 +1279,38 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1191 LLStringUtil::truncate(msg, indx); 1279 LLStringUtil::truncate(msg, indx);
1192 } 1280 }
1193 1281
1194 LLStringUtil::format_map_t args; 1282 LLSD args;
1195 args["[OBJECTNAME]"] = msg; 1283 args["[OBJECTNAME]"] = msg;
1196 1284
1285 LLSD payload;
1286
1197 // must protect against a NULL return from lookupHumanReadable() 1287 // must protect against a NULL return from lookupHumanReadable()
1198 std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType)); 1288 std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
1199 if (!typestr.empty()) 1289 if (!typestr.empty())
1200 { 1290 {
1201 args["[OBJECTTYPE]"] = typestr; 1291 args["OBJECTTYPE"] = typestr;
1202 } 1292 }
1203 else 1293 else
1204 { 1294 {
1205 LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL; 1295 LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
1206 args["[OBJECTTYPE]"] = ""; 1296 args["OBJECTTYPE"] = "";
1207 1297
1208 // This seems safest, rather than propagating bogosity 1298 // This seems safest, rather than propagating bogosity
1209 LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL; 1299 LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
1210 inventory_offer_callback(IOR_DECLINE, info); 1300 info->forceResponse(IOR_DECLINE);
1211 return; 1301 return;
1212 } 1302 }
1213 1303
1214 // Name cache callbacks don't store userdata, so can't save 1304 // Name cache callbacks don't store userdata, so can't save
1215 // off the LLOfferInfo. Argh. JC 1305 // off the LLOfferInfo. Argh.
1216 BOOL name_found = FALSE; 1306 BOOL name_found = FALSE;
1217 if (info->mFromGroup) 1307 if (info->mFromGroup)
1218 { 1308 {
1219 std::string group_name; 1309 std::string group_name;
1220 if (gCacheName->getGroupName(info->mFromID, group_name)) 1310 if (gCacheName->getGroupName(info->mFromID, group_name))
1221 { 1311 {
1222 args["[FIRST]"] = group_name; 1312 args["FIRST"] = group_name;
1223 args["[LAST]"] = ""; 1313 args["LAST"] = "";
1224 name_found = TRUE; 1314 name_found = TRUE;
1225 } 1315 }
1226 } 1316 }
@@ -1229,95 +1319,100 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
1229 std::string first_name, last_name; 1319 std::string first_name, last_name;
1230 if (gCacheName->getName(info->mFromID, first_name, last_name)) 1320 if (gCacheName->getName(info->mFromID, first_name, last_name))
1231 { 1321 {
1232 args["[FIRST]"] = first_name; 1322 args["FIRST"] = first_name;
1233 args["[LAST]"] = last_name; 1323 args["LAST"] = last_name;
1234 name_found = TRUE; 1324 name_found = TRUE;
1235 } 1325 }
1236 } 1326 }
1327
1328 payload["from_id"] = info->mFromID;
1329 args["OBJECTFROMNAME"] = info->mFromName;
1330 args["NAME"] = info->mFromName;
1331
1332 LLNotification::Params p("ObjectGiveItem");
1333 p.substitutions(args).payload(payload).functor(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
1334
1237 if (from_task) 1335 if (from_task)
1238 { 1336 {
1239 args["[OBJECTFROMNAME]"] = info->mFromName; 1337 p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser";
1240 LLNotifyBox::showXml(name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser",
1241 args, &inventory_offer_callback, (void*)info);
1242 } 1338 }
1243 else 1339 else
1244 { 1340 {
1245 // *TODO:translate -> [FIRST] [LAST] 1341 p.name = "UserGiveItem";
1246 args["[NAME]"] = info->mFromName;
1247 LLNotifyBox::showXml("UserGiveItem", args,
1248 &inventory_offer_callback, (void*)info);
1249 } 1342 }
1343
1344 LLNotifications::instance().add(p);
1250} 1345}
1251 1346
1252 1347
1253void group_vote_callback(S32 option, void *userdata) 1348bool group_vote_callback(const LLSD& notification, const LLSD& response)
1254{ 1349{
1255 LLUUID *group_id = (LLUUID *)userdata; 1350 LLUUID group_id = notification["payload"]["group_id"].asUUID();
1256 if (!group_id) return; 1351 S32 option = LLNotification::getSelectedOption(notification, response);
1257
1258 switch(option) 1352 switch(option)
1259 { 1353 {
1260 case 0: 1354 case 0:
1261 // Vote Now 1355 // Vote Now
1262 // Open up the voting tab 1356 // Open up the voting tab
1263 LLFloaterGroupInfo::showFromUUID(*group_id, "voting_tab"); 1357 LLFloaterGroupInfo::showFromUUID(group_id, "voting_tab");
1264 break; 1358 break;
1265 default: 1359 default:
1266 // Vote Later or 1360 // Vote Later or
1267 // close button 1361 // close button
1268 break; 1362 break;
1269 } 1363 }
1270 delete group_id; 1364 return false;
1271 group_id = NULL;
1272} 1365}
1366static LLNotificationFunctorRegistration group_vote_callback_reg("GroupVote", group_vote_callback);
1273 1367
1274struct LLLureInfo 1368bool lure_callback(const LLSD& notification, const LLSD& response)
1275{ 1369{
1276 LLLureInfo(const LLUUID& from, const LLUUID& lure_id, BOOL godlike) : 1370 S32 option = 0;
1277 mFromID(from), 1371 if (response.isInteger())
1278 mLureID(lure_id), 1372 {
1279 mGodlike(godlike) 1373 option = response.asInteger();
1280 {} 1374 }
1281 1375 else
1282 LLUUID mFromID; 1376 {
1283 LLUUID mLureID; 1377 option = LLNotification::getSelectedOption(notification, response);
1284 BOOL mGodlike; 1378 }
1285}; 1379
1380 LLUUID from_id = notification["payload"]["from_id"].asUUID();
1381 LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
1382 BOOL godlike = notification["payload"]["godlike"].asBoolean();
1286 1383
1287void lure_callback(S32 option, void* user_data)
1288{
1289 LLLureInfo* info = (LLLureInfo*)user_data;
1290 if(!info) return;
1291 switch(option) 1384 switch(option)
1292 { 1385 {
1293 case 0: 1386 case 0:
1294 { 1387 {
1295 // accept 1388 // accept
1296 gAgent.teleportViaLure(info->mLureID, info->mGodlike); 1389 gAgent.teleportViaLure(lure_id, godlike);
1297 } 1390 }
1298 break; 1391 break;
1299 case 1: 1392 case 1:
1300 default: 1393 default:
1301 // decline 1394 // decline
1302 send_simple_im(info->mFromID, 1395 send_simple_im(from_id,
1303 LLStringUtil::null, 1396 LLStringUtil::null,
1304 IM_LURE_DECLINED, 1397 IM_LURE_DECLINED,
1305 info->mLureID); 1398 lure_id);
1306 break; 1399 break;
1307 } 1400 }
1308 delete info; 1401 return false;
1309 info = NULL;
1310} 1402}
1403static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
1311 1404
1312void goto_url_callback(S32 option, void* user_data) 1405bool goto_url_callback(const LLSD& notification, const LLSD& response)
1313{ 1406{
1314 char* url = (char*)user_data; 1407 std::string url = notification["payload"]["url"].asString();
1408 S32 option = LLNotification::getSelectedOption(notification, response);
1315 if(1 == option) 1409 if(1 == option)
1316 { 1410 {
1317 LLWeb::loadURL(url); 1411 LLWeb::loadURL(url);
1318 } 1412 }
1319 delete[] url; 1413 return false;
1320} 1414}
1415static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
1321 1416
1322void process_improved_im(LLMessageSystem *msg, void **user_data) 1417void process_improved_im(LLMessageSystem *msg, void **user_data)
1323{ 1418{
@@ -1331,7 +1426,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1331 U8 offline; 1426 U8 offline;
1332 U8 d = 0; 1427 U8 d = 0;
1333 LLUUID session_id; 1428 LLUUID session_id;
1334 U32 t; 1429 U32 timestamp;
1335 std::string name; 1430 std::string name;
1336 std::string message; 1431 std::string message;
1337 U32 parent_estate_id = 0; 1432 U32 parent_estate_id = 0;
@@ -1349,7 +1444,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1349 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Offline, offline); 1444 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Offline, offline);
1350 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Dialog, d); 1445 msg->getU8Fast( _PREHASH_MessageBlock, _PREHASH_Dialog, d);
1351 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id); 1446 msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
1352 msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, t); 1447 msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
1353 //msg->getData("MessageBlock", "Count", &count); 1448 //msg->getData("MessageBlock", "Count", &count);
1354 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name); 1449 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
1355 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message); 1450 msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message, message);
@@ -1359,7 +1454,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1359 msg->getBinaryDataFast( _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES); 1454 msg->getBinaryDataFast( _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
1360 binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket); 1455 binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
1361 EInstantMessage dialog = (EInstantMessage)d; 1456 EInstantMessage dialog = (EInstantMessage)d;
1362 time_t timestamp = (time_t)t;
1363 1457
1364 BOOL is_busy = gAgent.getBusy(); 1458 BOOL is_busy = gAgent.getBusy();
1365 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); 1459 BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
@@ -1388,18 +1482,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1388 message_offset = 3; 1482 message_offset = 3;
1389 } 1483 }
1390 1484
1391 LLStringUtil::format_map_t args; 1485 LLSD args;
1392 switch(dialog) 1486 switch(dialog)
1393 { 1487 {
1394 case IM_CONSOLE_AND_CHAT_HISTORY: 1488 case IM_CONSOLE_AND_CHAT_HISTORY:
1395 // These are used for system messages, hence don't need the name, 1489 // These are used for system messages, hence don't need the name,
1396 // as it is always "Second Life". 1490 // as it is always "Second Life".
1397 // *TODO:translate 1491 // *TODO:translate
1398 args["[MESSAGE]"] = message; 1492 args["MESSAGE"] = message;
1399 1493
1400 // Note: don't put the message in the IM history, even though was sent 1494 // Note: don't put the message in the IM history, even though was sent
1401 // via the IM mechanism. 1495 // via the IM mechanism.
1402 LLNotifyBox::showXml("SystemMessageTip",args); 1496 LLNotifications::instance().add("SystemMessageTip",args);
1403 break; 1497 break;
1404 1498
1405 case IM_NOTHING_SPECIAL: 1499 case IM_NOTHING_SPECIAL:
@@ -1469,9 +1563,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1469 else if (to_id.isNull()) 1563 else if (to_id.isNull())
1470 { 1564 {
1471 // Message to everyone from GOD 1565 // Message to everyone from GOD
1472 args["[NAME]"] = name; 1566 args["NAME"] = name;
1473 args["[MESSAGE]"] = message; 1567 args["MESSAGE"] = message;
1474 LLNotifyBox::showXml("GodMessage", args); 1568 LLNotifications::instance().add("GodMessage", args);
1475 1569
1476 // Treat like a system message and put in chat history. 1570 // Treat like a system message and put in chat history.
1477 // Claim to be from a local agent so it doesn't go into 1571 // Claim to be from a local agent so it doesn't go into
@@ -1540,8 +1634,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1540 { 1634 {
1541 // This is a block, modeless dialog. 1635 // This is a block, modeless dialog.
1542 //*TODO:translate 1636 //*TODO:translate
1543 args["[MESSAGE]"] = message; 1637 args["MESSAGE"] = message;
1544 LLNotifyBox::showXml("SystemMessage", args); 1638 LLNotifications::instance().add("SystemMessage", args);
1545 } 1639 }
1546 break; 1640 break;
1547 case IM_GROUP_NOTICE: 1641 case IM_GROUP_NOTICE:
@@ -1578,9 +1672,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1578 1672
1579 // If there is inventory, give the user the inventory offer. 1673 // If there is inventory, give the user the inventory offer.
1580 LLOfferInfo* info = NULL; 1674 LLOfferInfo* info = NULL;
1675
1581 if (has_inventory) 1676 if (has_inventory)
1582 { 1677 {
1583 info = new LLOfferInfo; 1678 info = new LLOfferInfo;
1679
1584 info->mIM = IM_GROUP_NOTICE; 1680 info->mIM = IM_GROUP_NOTICE;
1585 info->mFromID = from_id; 1681 info->mFromID = from_id;
1586 info->mFromGroup = from_group; 1682 info->mFromGroup = from_group;
@@ -1609,13 +1705,26 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1609 std::string subj(*iter++); 1705 std::string subj(*iter++);
1610 std::string mes(*iter++); 1706 std::string mes(*iter++);
1611 1707
1612 if (IM_GROUP_NOTICE == dialog) 1708 // Send the notification down the new path.
1709 // For requested notices, we don't want to send the popups.
1710 if (dialog != IM_GROUP_NOTICE_REQUESTED)
1613 { 1711 {
1614 subj += "\n"; 1712 LLSD payload;
1615 mes = "\n\n" + mes; 1713 payload["subject"] = subj;
1616 LLGroupNotifyBox::show(subj,mes,name,group_id,t,has_inventory,item_name,info); 1714 payload["message"] = mes;
1715 payload["sender_name"] = name;
1716 payload["group_id"] = group_id;
1717 payload["inventory_name"] = item_name;
1718 payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
1719
1720 LLSD args;
1721 args["SUBJECT"] = subj;
1722 args["MESSAGE"] = mes;
1723 LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp));
1617 } 1724 }
1618 else if (IM_GROUP_NOTICE_REQUESTED == dialog) 1725
1726 // Also send down the old path for now.
1727 if (IM_GROUP_NOTICE_REQUESTED == dialog)
1619 { 1728 {
1620 LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info); 1729 LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info);
1621 } 1730 }
@@ -1627,7 +1736,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1627 if ((is_busy || is_muted)) 1736 if ((is_busy || is_muted))
1628 { 1737 {
1629 LLMessageSystem *msg = gMessageSystem; 1738 LLMessageSystem *msg = gMessageSystem;
1630 join_group_callback(1, NULL);
1631 busy_message(msg,from_id); 1739 busy_message(msg,from_id);
1632 } 1740 }
1633 else 1741 else
@@ -1650,18 +1758,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1650 invite_bucket = (struct invite_bucket_t*) &binary_bucket[0]; 1758 invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
1651 S32 membership_fee = ntohl(invite_bucket->membership_fee); 1759 S32 membership_fee = ntohl(invite_bucket->membership_fee);
1652 1760
1653 LLJoinGroupData* userdata = new LLJoinGroupData; 1761 LLSD payload;
1654 userdata->mTransactionID = session_id; 1762 payload["transaction_id"] = session_id;
1655 userdata->mGroupID = from_id; 1763 payload["group_id"] = from_id;
1656 userdata->mName.assign(name); 1764 payload["name"] = name;
1657 userdata->mMessage.assign(message); 1765 payload["message"] = message;
1658 userdata->mFee = membership_fee; 1766 payload["fee"] = membership_fee;
1659 1767
1660 LLStringUtil::format_map_t args; 1768 LLSD args;
1661 args["[MESSAGE]"] = message; 1769 args["MESSAGE"] = message;
1662 LLNotifyBox::showXml("JoinGroup", args, 1770 LLNotifications::instance().add("JoinGroup", args, payload, join_group_response);
1663 &join_group_callback,
1664 (void*)userdata);
1665 } 1771 }
1666 } 1772 }
1667 break; 1773 break;
@@ -1721,7 +1827,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1721 if ( is_muted ) 1827 if ( is_muted )
1722 { 1828 {
1723 // Same as closing window 1829 // Same as closing window
1724 inventory_offer_callback(-1, info); 1830 info->forceResponse(IOR_DECLINE);
1725 } 1831 }
1726 else 1832 else
1727 { 1833 {
@@ -1732,23 +1838,25 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1732 1838
1733 case IM_INVENTORY_ACCEPTED: 1839 case IM_INVENTORY_ACCEPTED:
1734 { 1840 {
1735 args["[NAME]"] = name; 1841 args["NAME"] = name;
1736 LLNotifyBox::showXml("InventoryAccepted", args); 1842 LLNotifications::instance().add("InventoryAccepted", args);
1737 break; 1843 break;
1738 } 1844 }
1739 case IM_INVENTORY_DECLINED: 1845 case IM_INVENTORY_DECLINED:
1740 { 1846 {
1741 args["[NAME]"] = name; 1847 args["NAME"] = name;
1742 LLNotifyBox::showXml("InventoryDeclined", args); 1848 LLNotifications::instance().add("InventoryDeclined", args);
1743 break; 1849 break;
1744 } 1850 }
1745 case IM_GROUP_VOTE: 1851 case IM_GROUP_VOTE:
1746 { 1852 {
1747 LLUUID *userdata = new LLUUID(session_id); 1853 LLSD args;
1748 args["[NAME]"] = name; 1854 args["NAME"] = name;
1749 args["[MESSAGE]"] = message; 1855 args["MESSAGE"] = message;
1750 LLNotifyBox::showXml("GroupVote", args, 1856
1751 &group_vote_callback, userdata); 1857 LLSD payload;
1858 payload["group_id"] = session_id;
1859 LLNotifications::instance().add("GroupVote", args, payload);
1752 } 1860 }
1753 break; 1861 break;
1754 1862
@@ -1802,15 +1910,52 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1802 break; 1910 break;
1803 1911
1804 case IM_FROM_TASK: 1912 case IM_FROM_TASK:
1805 if (is_busy && !is_owned_by_me)
1806 { 1913 {
1807 return; 1914 if (is_busy && !is_owned_by_me)
1915 {
1916 return;
1917 }
1918 chat.mText = name + separator_string + message.substr(message_offset);
1919 chat.mFromName = name;
1920
1921 // Build a link to open the object IM info window.
1922 std::string location = ll_safe_string((char*)binary_bucket,binary_bucket_size);
1923
1924 LLSD query_string;
1925 query_string["owner"] = from_id;
1926 query_string["slurl"] = location.c_str();
1927 query_string["name"] = name;
1928 if (from_group)
1929 {
1930 query_string["groupowned"] = "true";
1931 }
1932
1933 if (session_id.notNull())
1934 {
1935 chat.mFromID = session_id;
1936 }
1937 else
1938 {
1939 // This message originated on a region without the updated code for task id and slurl information.
1940 // We just need a unique ID for this object that isn't the owner ID.
1941 // If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
1942 // This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
1943 // This works because the only thing we can really do in this case is show the owner name and link to their profile.
1944 chat.mFromID = from_id ^ gAgent.getSessionID();
1945 }
1946
1947 std::ostringstream link;
1948 link << "secondlife:///app/objectim/" << session_id
1949 << LLURI::mapToQueryString(query_string);
1950
1951 chat.mURL = link.str();
1952 chat.mText = name + separator_string + message.substr(message_offset);
1953
1954 // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because
1955 // IMs from objcts don't open IM sessions.
1956 chat.mSourceType = CHAT_SOURCE_OBJECT;
1957 LLFloaterChat::addChat(chat, FALSE, FALSE);
1808 } 1958 }
1809 chat.mText = name + separator_string + message.substr(message_offset);
1810 // Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because
1811 // IMs from objcts don't open IM sessions.
1812 chat.mSourceType = CHAT_SOURCE_OBJECT;
1813 LLFloaterChat::addChat(chat, FALSE, FALSE);
1814 break; 1959 break;
1815 case IM_FROM_TASK_AS_ALERT: 1960 case IM_FROM_TASK_AS_ALERT:
1816 if (is_busy && !is_owned_by_me) 1961 if (is_busy && !is_owned_by_me)
@@ -1819,9 +1964,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1819 } 1964 }
1820 { 1965 {
1821 // Construct a viewer alert for this message. 1966 // Construct a viewer alert for this message.
1822 args["[NAME]"] = name; 1967 args["NAME"] = name;
1823 args["[MESSAGE]"] = message; 1968 args["MESSAGE"] = message;
1824 LLNotifyBox::showXml("ObjectMessage", args); 1969 LLNotifications::instance().add("ObjectMessage", args);
1825 } 1970 }
1826 break; 1971 break;
1827 case IM_BUSY_AUTO_RESPONSE: 1972 case IM_BUSY_AUTO_RESPONSE:
@@ -1850,27 +1995,34 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1850 } 1995 }
1851 else 1996 else
1852 { 1997 {
1998 LLSD args;
1853 // *TODO:translate -> [FIRST] [LAST] (maybe) 1999 // *TODO:translate -> [FIRST] [LAST] (maybe)
1854 LLLureInfo* info = new LLLureInfo(from_id, session_id, FALSE); 2000 args["NAME"] = name;
1855 args["[NAME]"] = name; 2001 args["MESSAGE"] = message;
1856 args["[MESSAGE]"] = message; 2002 LLSD payload;
1857 LLNotifyBox::showXml("OfferTeleport", args, 2003 payload["from_id"] = from_id;
1858 lure_callback, (void*)info); 2004 payload["lure_id"] = session_id;
2005 payload["godlike"] = FALSE;
2006 LLNotifications::instance().add("TeleportOffered", args, payload);
1859 } 2007 }
1860 } 2008 }
1861 break; 2009 break;
1862 2010
1863 case IM_GODLIKE_LURE_USER: 2011 case IM_GODLIKE_LURE_USER:
1864 { 2012 {
1865 LLLureInfo* info = new LLLureInfo(from_id, session_id, TRUE); 2013 LLSD payload;
2014 payload["from_id"] = from_id;
2015 payload["lure_id"] = session_id;
2016 payload["godlike"] = TRUE;
1866 // do not show a message box, because you're about to be 2017 // do not show a message box, because you're about to be
1867 // teleported. 2018 // teleported.
1868 lure_callback(0, (void *)info); 2019 LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
1869 } 2020 }
1870 break; 2021 break;
1871 2022
1872 case IM_GOTO_URL: 2023 case IM_GOTO_URL:
1873 { 2024 {
2025 LLSD args;
1874 // n.b. this is for URLs sent by the system, not for 2026 // n.b. this is for URLs sent by the system, not for
1875 // URLs sent by scripts (i.e. llLoadURL) 2027 // URLs sent by scripts (i.e. llLoadURL)
1876 if (binary_bucket_size <= 0) 2028 if (binary_bucket_size <= 0)
@@ -1881,38 +2033,33 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1881 return; 2033 return;
1882 } 2034 }
1883 2035
1884 char* url = new char[binary_bucket_size]; 2036 std::string url;
1885 if (url == NULL) 2037
1886 { 2038 url.assign((char*)binary_bucket, binary_bucket_size-1);
1887 LL_ERRS("Messaging") << "Memory Allocation failed" << LL_ENDL; 2039 args["MESSAGE"] = message;
1888 return; 2040 args["URL"] = url;
1889 } 2041 LLSD payload;
1890 2042 payload["url"] = url;
1891 strncpy(url, (char*)binary_bucket, binary_bucket_size-1); /* Flawfinder: ignore */ 2043 LLNotifications::instance().add("GotoURL", args, payload );
1892 url[binary_bucket_size-1] = '\0';
1893 args["[MESSAGE]"] = message;
1894 args["[URL]"] = url;
1895 LLNotifyBox::showXml("GotoURL", args,
1896 goto_url_callback, (void*)url);
1897 } 2044 }
1898 break; 2045 break;
1899 2046
1900 case IM_FRIENDSHIP_OFFERED: 2047 case IM_FRIENDSHIP_OFFERED:
1901 { 2048 {
1902 LLFriendshipOffer* offer = new LLFriendshipOffer; 2049 LLSD payload;
1903 offer->mFromID = from_id; 2050 payload["from_id"] = from_id;
1904 offer->mTransactionID = session_id; 2051 payload["session_id"] = session_id;;
1905 offer->mOnline = (offline == IM_ONLINE); 2052 payload["online"] = (offline == IM_ONLINE);
1906 offer->mHost = msg->getSender(); 2053 payload["sender"] = msg->getSender().getIPandPort();
1907 2054
1908 if (is_busy) 2055 if (is_busy)
1909 { 2056 {
1910 busy_message(msg, from_id); 2057 busy_message(msg, from_id);
1911 friendship_offer_callback(1, (void*)offer); 2058 LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
1912 } 2059 }
1913 else if (is_muted) 2060 else if (is_muted)
1914 { 2061 {
1915 friendship_offer_callback(1, (void*)offer); 2062 LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
1916 } 2063 }
1917 else 2064 else
1918 { 2065 {
@@ -1920,14 +2067,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1920 if(message.empty()) 2067 if(message.empty())
1921 { 2068 {
1922 //support for frienship offers from clients before July 2008 2069 //support for frienship offers from clients before July 2008
1923 LLNotifyBox::showXml("OfferFriendshipNoMessage", args, 2070 LLNotifications::instance().add("OfferFriendshipNoMessage", args, payload);
1924 &friendship_offer_callback, (void*)offer);
1925 } 2071 }
1926 else 2072 else
1927 { 2073 {
1928 args["[MESSAGE]"] = message; 2074 args["[MESSAGE]"] = message;
1929 LLNotifyBox::showXml("OfferFriendship", args, 2075 LLNotifications::instance().add("OfferFriendship", args, payload);
1930 &friendship_offer_callback, (void*)offer);
1931 } 2076 }
1932 } 2077 }
1933 } 2078 }
@@ -1944,16 +2089,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
1944 strings.push_back(from_id.asString()); 2089 strings.push_back(from_id.asString());
1945 send_generic_message("requestonlinenotification", strings); 2090 send_generic_message("requestonlinenotification", strings);
1946 2091
1947 args["[NAME]"] = name; 2092 args["NAME"] = name;
1948 LLNotifyBox::showXml("FriendshipAccepted", args); 2093 LLNotifications::instance().add("FriendshipAccepted", args);
1949 } 2094 }
1950 break; 2095 break;
1951 2096
1952 case IM_FRIENDSHIP_DECLINED: 2097 case IM_FRIENDSHIP_DECLINED_DEPRECATED:
1953 args["[NAME]"] = name;
1954 LLNotifyBox::showXml("FriendshipDeclined", args);
1955 break;
1956
1957 default: 2098 default:
1958 LL_WARNS("Messaging") << "Instant message calling for unknown dialog " 2099 LL_WARNS("Messaging") << "Instant message calling for unknown dialog "
1959 << (S32)dialog << LL_ENDL; 2100 << (S32)dialog << LL_ENDL;
@@ -1988,61 +2129,9 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
1988 } 2129 }
1989} 2130}
1990 2131
1991void friendship_offer_callback(S32 option, void* user_data) 2132bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
1992{
1993 LLFriendshipOffer* offer = (LLFriendshipOffer*)user_data;
1994 if(!offer) return;
1995 LLUUID fid;
1996 LLMessageSystem* msg = gMessageSystem;
1997 switch(option)
1998 {
1999 case 0:
2000 // accept
2001 LLAvatarTracker::formFriendship(offer->mFromID);
2002
2003 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
2004
2005 // This will also trigger an onlinenotification if the user is online
2006 msg->newMessageFast(_PREHASH_AcceptFriendship);
2007 msg->nextBlockFast(_PREHASH_AgentData);
2008 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2009 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2010 msg->nextBlockFast(_PREHASH_TransactionBlock);
2011 msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
2012 msg->nextBlockFast(_PREHASH_FolderData);
2013 msg->addUUIDFast(_PREHASH_FolderID, fid);
2014 msg->sendReliable(offer->mHost);
2015 break;
2016 case 1:
2017 // decline
2018 msg->newMessageFast(_PREHASH_DeclineFriendship);
2019 msg->nextBlockFast(_PREHASH_AgentData);
2020 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2021 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2022 msg->nextBlockFast(_PREHASH_TransactionBlock);
2023 msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
2024 msg->sendReliable(offer->mHost);
2025 break;
2026 default:
2027 // close button probably, possibly timed out
2028 break;
2029 }
2030
2031 delete offer;
2032 offer = NULL;
2033}
2034
2035struct LLCallingCardOfferData
2036{ 2133{
2037 LLUUID mTransactionID; 2134 S32 option = LLNotification::getSelectedOption(notification, response);
2038 LLUUID mSourceID;
2039 LLHost mHost;
2040};
2041
2042void callingcard_offer_callback(S32 option, void* user_data)
2043{
2044 LLCallingCardOfferData* offerdata = (LLCallingCardOfferData*)user_data;
2045 if(!offerdata) return;
2046 LLUUID fid; 2135 LLUUID fid;
2047 LLUUID from_id; 2136 LLUUID from_id;
2048 LLMessageSystem* msg = gMessageSystem; 2137 LLMessageSystem* msg = gMessageSystem;
@@ -2055,11 +2144,11 @@ void callingcard_offer_callback(S32 option, void* user_data)
2055 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 2144 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2056 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 2145 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2057 msg->nextBlockFast(_PREHASH_TransactionBlock); 2146 msg->nextBlockFast(_PREHASH_TransactionBlock);
2058 msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID); 2147 msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
2059 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD); 2148 fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
2060 msg->nextBlockFast(_PREHASH_FolderData); 2149 msg->nextBlockFast(_PREHASH_FolderData);
2061 msg->addUUIDFast(_PREHASH_FolderID, fid); 2150 msg->addUUIDFast(_PREHASH_FolderID, fid);
2062 msg->sendReliable(offerdata->mHost); 2151 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
2063 break; 2152 break;
2064 case 1: 2153 case 1:
2065 // decline 2154 // decline
@@ -2068,18 +2157,18 @@ void callingcard_offer_callback(S32 option, void* user_data)
2068 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 2157 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2069 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 2158 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2070 msg->nextBlockFast(_PREHASH_TransactionBlock); 2159 msg->nextBlockFast(_PREHASH_TransactionBlock);
2071 msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID); 2160 msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
2072 msg->sendReliable(offerdata->mHost); 2161 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
2073 busy_message(msg, offerdata->mSourceID); 2162 busy_message(msg, notification["payload"]["source_id"].asUUID());
2074 break; 2163 break;
2075 default: 2164 default:
2076 // close button probably, possibly timed out 2165 // close button probably, possibly timed out
2077 break; 2166 break;
2078 } 2167 }
2079 2168
2080 delete offerdata; 2169 return false;
2081 offerdata = NULL;
2082} 2170}
2171static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingCard", callingcard_offer_callback);
2083 2172
2084void process_offer_callingcard(LLMessageSystem* msg, void**) 2173void process_offer_callingcard(LLMessageSystem* msg, void**)
2085{ 2174{
@@ -2091,13 +2180,13 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2091 LLUUID tid; 2180 LLUUID tid;
2092 msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid); 2181 msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid);
2093 2182
2094 LLCallingCardOfferData* offerdata = new LLCallingCardOfferData; 2183 LLSD payload;
2095 offerdata->mTransactionID = tid; 2184 payload["transaction_id"] = tid;
2096 offerdata->mSourceID = source_id; 2185 payload["source_id"] = source_id;
2097 offerdata->mHost = msg->getSender(); 2186 payload["sender"] = msg->getSender().getIPandPort();
2098 2187
2099 LLViewerObject* source = gObjectList.findObject(source_id); 2188 LLViewerObject* source = gObjectList.findObject(source_id);
2100 LLStringUtil::format_map_t args; 2189 LLSD args;
2101 std::string source_name; 2190 std::string source_name;
2102 if(source && source->isAvatar()) 2191 if(source && source->isAvatar())
2103 { 2192 {
@@ -2105,8 +2194,8 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2105 LLNameValue* nvlast = source->getNVPair("LastName"); 2194 LLNameValue* nvlast = source->getNVPair("LastName");
2106 if (nvfirst && nvlast) 2195 if (nvfirst && nvlast)
2107 { 2196 {
2108 args["[FIRST]"] = nvfirst->getString(); 2197 args["FIRST"] = nvfirst->getString();
2109 args["[LAST]"] = nvlast->getString(); 2198 args["LAST"] = nvlast->getString();
2110 source_name = std::string(nvfirst->getString()) + " " + nvlast->getString(); 2199 source_name = std::string(nvfirst->getString()) + " " + nvlast->getString();
2111 } 2200 }
2112 } 2201 }
@@ -2117,33 +2206,27 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
2117 || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat)) 2206 || LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
2118 { 2207 {
2119 // automatically decline offer 2208 // automatically decline offer
2120 callingcard_offer_callback(1, (void*)offerdata); 2209 LLNotifications::instance().forceResponse(LLNotification::Params("OfferCallingCard").payload(payload), 1);
2121 offerdata = NULL; // pointer was freed by callback
2122 } 2210 }
2123 else 2211 else
2124 { 2212 {
2125 LLNotifyBox::showXml("OfferCallingCard", args, 2213 LLNotifications::instance().add("OfferCallingCard", args, payload);
2126 &callingcard_offer_callback, (void*)offerdata);
2127 offerdata = NULL; // pointer ownership transferred
2128 } 2214 }
2129 } 2215 }
2130 else 2216 else
2131 { 2217 {
2132 LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL; 2218 LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL;
2133 } 2219 }
2134
2135 delete offerdata; // !=NULL if we didn't give ownership away
2136 offerdata = NULL;
2137} 2220}
2138 2221
2139void process_accept_callingcard(LLMessageSystem* msg, void**) 2222void process_accept_callingcard(LLMessageSystem* msg, void**)
2140{ 2223{
2141 LLNotifyBox::showXml("CallingCardAccepted"); 2224 LLNotifications::instance().add("CallingCardAccepted");
2142} 2225}
2143 2226
2144void process_decline_callingcard(LLMessageSystem* msg, void**) 2227void process_decline_callingcard(LLMessageSystem* msg, void**)
2145{ 2228{
2146 LLNotifyBox::showXml("CallingCardDeclined"); 2229 LLNotifications::instance().add("CallingCardDeclined");
2147} 2230}
2148 2231
2149 2232
@@ -2459,18 +2542,18 @@ public:
2459 LLInventoryModel::EXCLUDE_TRASH, 2542 LLInventoryModel::EXCLUDE_TRASH,
2460 is_card); 2543 is_card);
2461 } 2544 }
2462 LLStringUtil::format_map_t args; 2545 LLSD args;
2463 if ( land_items.count() > 0 ) 2546 if ( land_items.count() > 0 )
2464 { // Show notification that they can now teleport to landmarks. Use a random landmark from the inventory 2547 { // Show notification that they can now teleport to landmarks. Use a random landmark from the inventory
2465 S32 random_land = ll_rand( land_items.count() - 1 ); 2548 S32 random_land = ll_rand( land_items.count() - 1 );
2466 args["[NAME]"] = land_items[random_land]->getName(); 2549 args["NAME"] = land_items[random_land]->getName();
2467 LLNotifyBox::showXml("TeleportToLandmark",args); 2550 LLNotifications::instance().add("TeleportToLandmark",args);
2468 } 2551 }
2469 if ( card_items.count() > 0 ) 2552 if ( card_items.count() > 0 )
2470 { // Show notification that they can now contact people. Use a random calling card from the inventory 2553 { // Show notification that they can now contact people. Use a random calling card from the inventory
2471 S32 random_card = ll_rand( card_items.count() - 1 ); 2554 S32 random_card = ll_rand( card_items.count() - 1 );
2472 args["[NAME]"] = card_items[random_card]->getName(); 2555 args["NAME"] = card_items[random_card]->getName();
2473 LLNotifyBox::showXml("TeleportToPerson",args); 2556 LLNotifications::instance().add("TeleportToPerson",args);
2474 } 2557 }
2475 2558
2476 gInventory.removeObserver(this); 2559 gInventory.removeObserver(this);
@@ -2651,11 +2734,6 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
2651} 2734}
2652*/ 2735*/
2653 2736
2654static void display_release_notes(S32, void* data)
2655{
2656 gAgent.getRegion()->showReleaseNotes();
2657}
2658
2659void process_agent_movement_complete(LLMessageSystem* msg, void**) 2737void process_agent_movement_complete(LLMessageSystem* msg, void**)
2660{ 2738{
2661 gAgentMovementCompleted = true; 2739 gAgentMovementCompleted = true;
@@ -2689,7 +2767,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2689 if (!avatarp) 2767 if (!avatarp)
2690 { 2768 {
2691 // Could happen if you were immediately god-teleported away on login, 2769 // Could happen if you were immediately god-teleported away on login,
2692 // maybe other cases. Continue, but warn. JC 2770 // maybe other cases. Continue, but warn.
2693 LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL; 2771 LL_WARNS("Messaging") << "agent_movement_complete() with NULL avatarp." << LL_ENDL;
2694 } 2772 }
2695 2773
@@ -2729,7 +2807,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2729 2807
2730 if( is_teleport ) 2808 if( is_teleport )
2731 { 2809 {
2732 // Force the camera back onto the agent, don't animate. JC 2810 // Force the camera back onto the agent, don't animate.
2733 gAgent.setFocusOnAvatar(TRUE, FALSE); 2811 gAgent.setFocusOnAvatar(TRUE, FALSE);
2734 gAgent.slamLookAt(look_at); 2812 gAgent.slamLookAt(look_at);
2735 gAgent.updateCamera(); 2813 gAgent.updateCamera();
@@ -2827,8 +2905,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
2827 2905
2828 if (!gLastVersionChannel.empty()) 2906 if (!gLastVersionChannel.empty())
2829 { 2907 {
2830 LLNotifyBox::showXml( 2908 LLSD payload;
2831 "ServerVersionChanged", display_release_notes, NULL); 2909 payload["message"] = version_channel;
2910 LLNotifications::instance().add("ServerVersionChanged", LLSD(), payload);
2832 } 2911 }
2833 2912
2834 gLastVersionChannel = version_channel; 2913 gLastVersionChannel = version_channel;
@@ -3314,6 +3393,12 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
3314 return; 3393 return;
3315 } 3394 }
3316 3395
3396 // Don't play sounds from a region with maturity above current agent maturity
3397 if( !gAgent.canAccessMaturityInRegion( region_handle ) )
3398 {
3399 return;
3400 }
3401
3317 gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global); 3402 gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
3318} 3403}
3319 3404
@@ -3347,6 +3432,13 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
3347 // audio data into a buffer at this point, as it won't actually 3432 // audio data into a buffer at this point, as it won't actually
3348 // help us out. 3433 // help us out.
3349 3434
3435 // Don't play sounds from a region with maturity above current agent maturity
3436 LLVector3d pos_global = objectp->getPositionGlobal();
3437 if( !gAgent.canAccessMaturityAtGlobal( pos_global ) )
3438 {
3439 return;
3440 }
3441
3350 // Add audioData starts a transfer internally. 3442 // Add audioData starts a transfer internally.
3351 sourcep->addAudioData(datap, FALSE); 3443 sourcep->addAudioData(datap, FALSE);
3352} 3444}
@@ -3379,6 +3471,14 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
3379 3471
3380 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return; 3472 if (LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagObjectSounds)) return;
3381 3473
3474
3475 // Don't play sounds from a region with maturity above current agent maturity
3476 LLVector3d pos = objectp->getPositionGlobal();
3477 if( !gAgent.canAccessMaturityAtGlobal(pos) )
3478 {
3479 return;
3480 }
3481
3382 objectp->setAttachedSound(sound_id, owner_id, gain, flags); 3482 objectp->setAttachedSound(sound_id, owner_id, gain, flags);
3383} 3483}
3384 3484
@@ -3601,7 +3701,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data)
3601 3701
3602 avatarp->mSignaledAnimations.clear(); 3702 avatarp->mSignaledAnimations.clear();
3603 3703
3604 if (avatarp->mIsSelf) 3704 if (avatarp->isSelf())
3605 { 3705 {
3606 LLUUID object_id; 3706 LLUUID object_id;
3607 3707
@@ -4032,9 +4132,9 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
4032 // Make the user confirm the transaction, since they might 4132 // Make the user confirm the transaction, since they might
4033 // have missed something during an event. 4133 // have missed something during an event.
4034 // *TODO:translate 4134 // *TODO:translate
4035 LLStringUtil::format_map_t args; 4135 LLSD args;
4036 args["[MESSAGE]"] = desc; 4136 args["MESSAGE"] = desc;
4037 LLNotifyBox::showXml("SystemMessage", args); 4137 LLNotifications::instance().add("SystemMessage", args);
4038 4138
4039 // Once the 'recent' container gets large enough, chop some 4139 // Once the 'recent' container gets large enough, chop some
4040 // off the beginning. 4140 // off the beginning.
@@ -4050,29 +4150,158 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
4050 } 4150 }
4051} 4151}
4052 4152
4053void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data) 4153bool handle_special_notification_callback(const LLSD& notification, const LLSD& response)
4054{ 4154{
4055 std::string buffer; 4155 S32 option = LLNotification::getSelectedOption(notification, response);
4056 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); 4156
4057 BOOL modal = FALSE; 4157 if (0 == option)
4058 msgsystem->getBOOL("AlertData", "Modal", modal); 4158 {
4059 process_alert_core(buffer, modal); 4159 // set the preference to the maturity of the region we're calling
4160 int preferredMaturity = notification["payload"]["_region_access"].asInteger();
4161 gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
4162 gAgent.sendMaturityPreferenceToServer(preferredMaturity);
4163
4164 }
4165
4166 return false;
4060} 4167}
4061 4168
4062void process_alert_message(LLMessageSystem *msgsystem, void **user_data) 4169// some of the server notifications need special handling. This is where we do that.
4170bool handle_special_notification(std::string notificationID, LLSD& llsdBlock)
4063{ 4171{
4064 std::string buffer; 4172 int regionAccess = llsdBlock["_region_access"].asInteger();
4065 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer); 4173 llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess);
4066 BOOL modal = FALSE; 4174
4067 process_alert_core(buffer, modal); 4175 // we're going to throw the LLSD in there in case anyone ever wants to use it
4176 LLNotifications::instance().add(notificationID+"_Notify", llsdBlock);
4177
4178 if (regionAccess == SIM_ACCESS_MATURE)
4179 {
4180 if (gAgent.isTeen())
4181 {
4182 LLNotifications::instance().add(notificationID+"_KB", llsdBlock);
4183 return true;
4184 }
4185 else if (gAgent.prefersPG())
4186 {
4187 LLNotifications::instance().add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
4188 return true;
4189 }
4190 }
4191 else if (regionAccess == SIM_ACCESS_ADULT)
4192 {
4193 if (!gAgent.isAdult())
4194 {
4195 LLNotifications::instance().add(notificationID+"_KB", llsdBlock);
4196 return true;
4197 }
4198 else if (gAgent.prefersPG() || gAgent.prefersMature())
4199 {
4200 LLNotifications::instance().add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback);
4201 return true;
4202 }
4203 }
4204 return false;
4068} 4205}
4069 4206
4070void process_alert_core(const std::string& message, BOOL modal) 4207bool attempt_standard_notification(LLMessageSystem* msgsystem)
4208{
4209 // if we have additional alert data
4210 if (msgsystem->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
4211 {
4212 // notification was specified using the new mechanism, so we can just handle it here
4213 std::string notificationID;
4214 std::string llsdRaw;
4215 LLSD llsdBlock;
4216 msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
4217 msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsdRaw);
4218 if (llsdRaw.length())
4219 {
4220 std::istringstream llsdData(llsdRaw);
4221 if (!LLSDSerialize::deserialize(llsdBlock, llsdData, llsdRaw.length()))
4222 {
4223 llwarns << "attempt_standard_notification: Attempted to read notification parameter data into LLSD but failed:" << llsdRaw << llendl;
4224 }
4225 }
4226
4227 if (
4228 (notificationID == "RegionEntryAccessBlocked") ||
4229 (notificationID == "LandClaimAccessBlocked") ||
4230 (notificationID == "LandBuyAccessBlocked")
4231 )
4232 {
4233 /*---------------------------------------------------------------------
4234 (Commented so a grep will find the notification strings, since
4235 we construct them on the fly; if you add additional notifications,
4236 please update the comment.)
4237
4238 Could throw any of the following notifications:
4239
4240 RegionEntryAccessBlocked
4241 RegionEntryAccessBlocked_Notify
4242 RegionEntryAccessBlocked_Change
4243 RegionEntryAccessBlocked_KB
4244 LandClaimAccessBlocked
4245 LandClaimAccessBlocked_Notify
4246 LandClaimAccessBlocked_Change
4247 LandClaimAccessBlocked_KB
4248 LandBuyAccessBlocked
4249 LandBuyAccessBlocked_Notify
4250 LandBuyAccessBlocked_Change
4251 LandBuyAccessBlocked_KB
4252
4253 -----------------------------------------------------------------------*/
4254 if (handle_special_notification(notificationID, llsdBlock))
4255 {
4256 return true;
4257 }
4258 }
4259
4260 LLNotifications::instance().add(notificationID, llsdBlock);
4261 return true;
4262 }
4263 return false;
4264}
4265
4266
4267void process_agent_alert_message(LLMessageSystem* msgsystem, void** user_data)
4071{ 4268{
4072 // make sure the cursor is back to the usual default since the 4269 // make sure the cursor is back to the usual default since the
4073 // alert is probably due to some kind of error. 4270 // alert is probably due to some kind of error.
4074 gViewerWindow->getWindow()->resetBusyCount(); 4271 gViewerWindow->getWindow()->resetBusyCount();
4272
4273 if (!attempt_standard_notification(msgsystem))
4274 {
4275 BOOL modal = FALSE;
4276 msgsystem->getBOOL("AlertData", "Modal", modal);
4277 std::string buffer;
4278 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
4279 process_alert_core(buffer, modal);
4280 }
4281}
4282
4283// The only difference between this routine and the previous is the fact that
4284// for this routine, the modal parameter is always false. Sadly, for the message
4285// handled by this routine, there is no "Modal" parameter on the message, and
4286// there's no API to tell if a message has the given parameter or not.
4287// So we can't handle the messages with the same handler.
4288void process_alert_message(LLMessageSystem *msgsystem, void **user_data)
4289{
4290 // make sure the cursor is back to the usual default since the
4291 // alert is probably due to some kind of error.
4292 gViewerWindow->getWindow()->resetBusyCount();
4293
4294 if (!attempt_standard_notification(msgsystem))
4295 {
4296 BOOL modal = FALSE;
4297 std::string buffer;
4298 msgsystem->getStringFast(_PREHASH_AlertData, _PREHASH_Message, buffer);
4299 process_alert_core(buffer, modal);
4300 }
4301}
4075 4302
4303void process_alert_core(const std::string& message, BOOL modal)
4304{
4076 // HACK -- handle callbacks for specific alerts 4305 // HACK -- handle callbacks for specific alerts
4077 if ( message == "You died and have been teleported to your home location") 4306 if ( message == "You died and have been teleported to your home location")
4078 { 4307 {
@@ -4094,54 +4323,54 @@ void process_alert_core(const std::string& message, BOOL modal)
4094 // Allow the server to spawn a named alert so that server alerts can be 4323 // Allow the server to spawn a named alert so that server alerts can be
4095 // translated out of English. 4324 // translated out of English.
4096 std::string alert_name(message.substr(ALERT_PREFIX.length())); 4325 std::string alert_name(message.substr(ALERT_PREFIX.length()));
4097 LLAlertDialog::showXml(alert_name); 4326 LLNotifications::instance().add(alert_name);
4098 } 4327 }
4099 else if (message.find(NOTIFY_PREFIX) == 0) 4328 else if (message.find(NOTIFY_PREFIX) == 0)
4100 { 4329 {
4101 // Allow the server to spawn a named notification so that server notifications can be 4330 // Allow the server to spawn a named notification so that server notifications can be
4102 // translated out of English. 4331 // translated out of English.
4103 std::string notify_name(message.substr(NOTIFY_PREFIX.length())); 4332 std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
4104 LLNotifyBox::showXml(notify_name); 4333 LLNotifications::instance().add(notify_name);
4105 } 4334 }
4106 else if (message[0] == '/') 4335 else if (message[0] == '/')
4107 { 4336 {
4108 // System message is important, show in upper-right box not tip 4337 // System message is important, show in upper-right box not tip
4109 std::string text(message.substr(1)); 4338 std::string text(message.substr(1));
4110 LLStringUtil::format_map_t args; 4339 LLSD args;
4111 if (text.substr(0,17) == "RESTART_X_MINUTES") 4340 if (text.substr(0,17) == "RESTART_X_MINUTES")
4112 { 4341 {
4113 S32 mins = 0; 4342 S32 mins = 0;
4114 LLStringUtil::convertToS32(text.substr(18), mins); 4343 LLStringUtil::convertToS32(text.substr(18), mins);
4115 args["[MINUTES]"] = llformat("%d",mins); 4344 args["MINUTES"] = llformat("%d",mins);
4116 LLNotifyBox::showXml("RegionRestartMinutes", args); 4345 LLNotifications::instance().add("RegionRestartMinutes", args);
4117 } 4346 }
4118 else if (text.substr(0,17) == "RESTART_X_SECONDS") 4347 else if (text.substr(0,17) == "RESTART_X_SECONDS")
4119 { 4348 {
4120 S32 secs = 0; 4349 S32 secs = 0;
4121 LLStringUtil::convertToS32(text.substr(18), secs); 4350 LLStringUtil::convertToS32(text.substr(18), secs);
4122 args["[SECONDS]"] = llformat("%d",secs); 4351 args["SECONDS"] = llformat("%d",secs);
4123 LLNotifyBox::showXml("RegionRestartSeconds", args); 4352 LLNotifications::instance().add("RegionRestartSeconds", args);
4124 } 4353 }
4125 else 4354 else
4126 { 4355 {
4127 // *TODO:translate 4356 // *TODO:translate
4128 args["[MESSAGE]"] = text; 4357 args["MESSAGE"] = text;
4129 LLNotifyBox::showXml("SystemMessage", args); 4358 LLNotifications::instance().add("SystemMessage", args);
4130 } 4359 }
4131 } 4360 }
4132 else if (modal) 4361 else if (modal)
4133 { 4362 {
4134 // *TODO:translate 4363 // *TODO:translate
4135 LLStringUtil::format_map_t args; 4364 LLSD args;
4136 args["[ERROR_MESSAGE]"] = message; 4365 args["ERROR_MESSAGE"] = message;
4137 gViewerWindow->alertXml("ErrorMessage", args); 4366 LLNotifications::instance().add("ErrorMessage", args);
4138 } 4367 }
4139 else 4368 else
4140 { 4369 {
4141 // *TODO:translate 4370 // *TODO:translate
4142 LLStringUtil::format_map_t args; 4371 LLSD args;
4143 args["[MESSAGE]"] = message; 4372 args["MESSAGE"] = message;
4144 LLNotifyBox::showXml("SystemMessageTip", args); 4373 LLNotifications::instance().add("SystemMessageTip", args);
4145 } 4374 }
4146} 4375}
4147 4376
@@ -4190,7 +4419,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
4190{ 4419{
4191 if (gAgent.inPrelude()) 4420 if (gAgent.inPrelude())
4192 { 4421 {
4193 // JC: In prelude, bumping is OK. This dialog is rather confusing to 4422 // In prelude, bumping is OK. This dialog is rather confusing to
4194 // newbies, so we don't show it. Drop the packet on the floor. 4423 // newbies, so we don't show it. Drop the packet on the floor.
4195 return; 4424 return;
4196 } 4425 }
@@ -4265,7 +4494,11 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
4265 LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance()); 4494 LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
4266 4495
4267 S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); 4496 S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
4497
4498 LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
4499
4268 LLFloaterImagePreview::setUploadAmount(upload_cost); 4500 LLFloaterImagePreview::setUploadAmount(upload_cost);
4501 LLFloaterAnimPreview::setUploadAmount(upload_cost);
4269 4502
4270 gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost)); 4503 gMenuHolder->childSetLabelArg("Upload Image", "[COST]", llformat("%d", upload_cost));
4271 gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost)); 4504 gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", llformat("%d", upload_cost));
@@ -4273,23 +4506,7 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
4273 gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost)); 4506 gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost));
4274} 4507}
4275 4508
4276class LLScriptQuestionCBData 4509void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
4277{
4278public:
4279 LLScriptQuestionCBData(const LLUUID &taskid, const LLUUID &itemid, const LLHost &sender, S32 questions, const std::string& object_name, const std::string& owner_name)
4280 : mTaskID(taskid), mItemID(itemid), mSender(sender), mQuestions(questions), mObjectName(object_name), mOwnerName(owner_name)
4281 {
4282 }
4283
4284 LLUUID mTaskID;
4285 LLUUID mItemID;
4286 LLHost mSender;
4287 S32 mQuestions;
4288 std::string mObjectName;
4289 std::string mOwnerName;
4290};
4291
4292void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_questions, BOOL granted)
4293{ 4510{
4294 // only continue if at least some permissions were requested 4511 // only continue if at least some permissions were requested
4295 if (orig_questions) 4512 if (orig_questions)
@@ -4300,16 +4517,16 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4300 // located in [REGIONNAME] at [REGIONPOS], 4517 // located in [REGIONNAME] at [REGIONPOS],
4301 // has been <granted|denied> permission to: [PERMISSIONS]." 4518 // has been <granted|denied> permission to: [PERMISSIONS]."
4302 4519
4303 LLUIString notice(LLNotifyBox::getTemplateMessage(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied")); 4520 LLUIString notice(LLFloaterChat::getInstance()->getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
4304 4521
4305 // always include the object name and owner name 4522 // always include the object name and owner name
4306 notice.setArg("[OBJECTNAME]", cbdata->mObjectName); 4523 notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
4307 notice.setArg("[OWNERNAME]", cbdata->mOwnerName); 4524 notice.setArg("[OWNERNAME]", notification["payload"]["owner_name"].asString());
4308 4525
4309 // try to lookup viewerobject that corresponds to the object that 4526 // try to lookup viewerobject that corresponds to the object that
4310 // requested permissions (here, taskid->requesting object id) 4527 // requested permissions (here, taskid->requesting object id)
4311 BOOL foundpos = FALSE; 4528 BOOL foundpos = FALSE;
4312 LLViewerObject* viewobj = gObjectList.findObject(cbdata->mTaskID); 4529 LLViewerObject* viewobj = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
4313 if (viewobj) 4530 if (viewobj)
4314 { 4531 {
4315 // found the viewerobject, get it's position in its region 4532 // found the viewerobject, get it's position in its region
@@ -4342,7 +4559,7 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4342 std::string perms; 4559 std::string perms;
4343 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) 4560 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
4344 { 4561 {
4345 if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i])) 4562 if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
4346 { 4563 {
4347 count++; 4564 count++;
4348 caution = TRUE; 4565 caution = TRUE;
@@ -4354,7 +4571,7 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4354 perms.append(", "); 4571 perms.append(", ");
4355 } 4572 }
4356 4573
4357 perms.append(LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i])); 4574 perms.append(LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]));
4358 } 4575 }
4359 } 4576 }
4360 4577
@@ -4370,43 +4587,12 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
4370 } 4587 }
4371} 4588}
4372 4589
4373void script_question_decline_cb(S32 option, void* user_data) 4590bool script_question_cb(const LLSD& notification, const LLSD& response)
4374{ 4591{
4592 S32 option = LLNotification::getSelectedOption(notification, response);
4375 LLMessageSystem *msg = gMessageSystem; 4593 LLMessageSystem *msg = gMessageSystem;
4376 LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data; 4594 S32 orig = notification["payload"]["questions"].asInteger();
4377 4595 S32 new_questions = orig;
4378 // remember the permissions requested so they can be checked
4379 // when it comes time to log a chat message
4380 S32 orig = cbdata->mQuestions;
4381
4382 // this callback will always decline all permissions requested
4383 // (any question flags set in the ScriptAnswerYes message
4384 // will be interpreted as having been granted, so clearing all
4385 // the bits will deny every permission)
4386 cbdata->mQuestions = 0;
4387
4388 // respond with the permissions denial
4389 msg->newMessageFast(_PREHASH_ScriptAnswerYes);
4390 msg->nextBlockFast(_PREHASH_AgentData);
4391 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4392 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4393 msg->nextBlockFast(_PREHASH_Data);
4394 msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID);
4395 msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID);
4396 msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions);
4397 msg->sendReliable(cbdata->mSender);
4398
4399 // log a chat message, if appropriate
4400 notify_cautioned_script_question(cbdata, orig, FALSE);
4401
4402 delete cbdata;
4403}
4404
4405void script_question_cb(S32 option, void* user_data)
4406{
4407 LLMessageSystem *msg = gMessageSystem;
4408 LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data;
4409 S32 orig = cbdata->mQuestions;
4410 4596
4411 // check whether permissions were granted or denied 4597 // check whether permissions were granted or denied
4412 BOOL allowed = TRUE; 4598 BOOL allowed = TRUE;
@@ -4414,48 +4600,68 @@ void script_question_cb(S32 option, void* user_data)
4414 // if any other button was clicked, the permissions were denied 4600 // if any other button was clicked, the permissions were denied
4415 if (option != 0) 4601 if (option != 0)
4416 { 4602 {
4417 cbdata->mQuestions = 0; 4603 new_questions = 0;
4418 allowed = FALSE; 4604 allowed = FALSE;
4419 } 4605 }
4420 4606
4607 LLUUID task_id = notification["payload"]["task_id"].asUUID();
4608 LLUUID item_id = notification["payload"]["item_id"].asUUID();
4609
4421 // reply with the permissions granted or denied 4610 // reply with the permissions granted or denied
4422 msg->newMessageFast(_PREHASH_ScriptAnswerYes); 4611 msg->newMessageFast(_PREHASH_ScriptAnswerYes);
4423 msg->nextBlockFast(_PREHASH_AgentData); 4612 msg->nextBlockFast(_PREHASH_AgentData);
4424 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); 4613 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4425 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 4614 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4426 msg->nextBlockFast(_PREHASH_Data); 4615 msg->nextBlockFast(_PREHASH_Data);
4427 msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID); 4616 msg->addUUIDFast(_PREHASH_TaskID, task_id);
4428 msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID); 4617 msg->addUUIDFast(_PREHASH_ItemID, item_id);
4429 msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions); 4618 msg->addS32Fast(_PREHASH_Questions, new_questions);
4430 msg->sendReliable(cbdata->mSender); 4619 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
4431 4620
4432 // only log a chat message if caution prompts are enabled 4621 // only log a chat message if caution prompts are enabled
4433 if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) 4622 if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
4434 { 4623 {
4435 // log a chat message, if appropriate 4624 // log a chat message, if appropriate
4436 notify_cautioned_script_question(cbdata, orig, allowed); 4625 notify_cautioned_script_question(notification, response, orig, allowed);
4437 } 4626 }
4438 4627
4439 if ( option == 2 ) // mute 4628 if ( response["Mute"] ) // mute
4440 { 4629 {
4441 LLMuteList::getInstance()->add(LLMute(cbdata->mItemID, cbdata->mObjectName, LLMute::OBJECT)); 4630 LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
4442 4631
4443 // purge the message queue of any previously queued requests from the same source. DEV-4879 4632 // purge the message queue of any previously queued requests from the same source. DEV-4879
4444 class OfferMatcher : public LLNotifyBoxView::Matcher 4633 class OfferMatcher : public LLNotifyBoxView::Matcher
4445 { 4634 {
4446 public: 4635 public:
4447 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {} 4636 OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
4448 BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const 4637 BOOL matches(const LLNotificationPtr notification) const
4449 { 4638 {
4450 return callback == script_question_cb && ((LLScriptQuestionCBData*)cb_data)->mItemID == blocked_id; 4639 if (notification->getName() == "ScriptQuestionCaution"
4640 || notification->getName() == "ScriptQuestion")
4641 {
4642 return (notification->getPayload()["item_id"].asUUID() == blocked_id);
4643 }
4644 return FALSE;
4451 } 4645 }
4452 private: 4646 private:
4453 const LLUUID& blocked_id; 4647 const LLUUID& blocked_id;
4454 }; 4648 };
4455 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(cbdata->mItemID)); 4649 // should do this via the channel
4650 gNotifyBoxView->purgeMessagesMatching(OfferMatcher(item_id));
4456 } 4651 }
4457 delete cbdata; 4652
4653 if (response["Details"])
4654 {
4655 // respawn notification...
4656 LLNotifications::instance().add(notification["name"], notification["substitutions"], notification["payload"]);
4657
4658 // ...with description on top
4659 LLNotifications::instance().add("DebitPermissionDetails");
4660 }
4661 return false;
4458} 4662}
4663static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
4664static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
4459 4665
4460void process_script_question(LLMessageSystem *msg, void **user_data) 4666void process_script_question(LLMessageSystem *msg, void **user_data)
4461{ 4667{
@@ -4477,14 +4683,26 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4477 msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name); 4683 msg->getStringFast(_PREHASH_Data, _PREHASH_ObjectOwner, owner_name);
4478 msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions ); 4684 msg->getS32Fast(_PREHASH_Data, _PREHASH_Questions, questions );
4479 4685
4480 // don't display permission requests if this object is muted - JS. 4686 // Special case. If the objects are owned by this agent, throttle per-object instead
4687 // of per-owner. It's common for residents to reset a ton of scripts that re-request
4688 // permissions, as with tier boxes. UUIDs can't be valid agent names and vice-versa,
4689 // so we'll reuse the same namespace for both throttle types.
4690 std::string throttle_name = owner_name;
4691 std::string self_name;
4692 gAgent.getName( self_name );
4693 if( owner_name == self_name )
4694 {
4695 throttle_name = taskid.getString();
4696 }
4697
4698 // don't display permission requests if this object is muted
4481 if (LLMuteList::getInstance()->isMuted(taskid)) return; 4699 if (LLMuteList::getInstance()->isMuted(taskid)) return;
4482 4700
4483 // throttle excessive requests from any specific user's scripts 4701 // throttle excessive requests from any specific user's scripts
4484 typedef LLKeyThrottle<std::string> LLStringThrottle; 4702 typedef LLKeyThrottle<std::string> LLStringThrottle;
4485 static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL ); 4703 static LLStringThrottle question_throttle( LLREQUEST_PERMISSION_THROTTLE_LIMIT, LLREQUEST_PERMISSION_THROTTLE_INTERVAL );
4486 4704
4487 switch (question_throttle.noteAction(owner_name)) 4705 switch (question_throttle.noteAction(throttle_name))
4488 { 4706 {
4489 case LLStringThrottle::THROTTLE_NEWLY_BLOCKED: 4707 case LLStringThrottle::THROTTLE_NEWLY_BLOCKED:
4490 LL_INFOS("Messaging") << "process_script_question throttled" 4708 LL_INFOS("Messaging") << "process_script_question throttled"
@@ -4505,9 +4723,9 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4505 { 4723 {
4506 BOOL caution = FALSE; 4724 BOOL caution = FALSE;
4507 S32 count = 0; 4725 S32 count = 0;
4508 LLStringUtil::format_map_t args; 4726 LLSD args;
4509 args["[OBJECTNAME]"] = object_name; 4727 args["OBJECTNAME"] = object_name;
4510 args["[NAME]"] = owner_name; 4728 args["NAME"] = owner_name;
4511 4729
4512 // check the received permission flags against each permission 4730 // check the received permission flags against each permission
4513 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) 4731 for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
@@ -4515,34 +4733,32 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
4515 if (questions & LSCRIPTRunTimePermissionBits[i]) 4733 if (questions & LSCRIPTRunTimePermissionBits[i])
4516 { 4734 {
4517 count++; 4735 count++;
4518 script_question += " " + LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i]) + "\n"; 4736 script_question += " " + LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]) + "\n";
4519 4737
4520 // check whether permission question should cause special caution dialog 4738 // check whether permission question should cause special caution dialog
4521 caution |= LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i]); 4739 caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
4522 } 4740 }
4523 } 4741 }
4524 args["[QUESTIONS]"] = script_question; 4742 args["QUESTIONS"] = script_question;
4525 4743
4526 LLScriptQuestionCBData *cbdata = new LLScriptQuestionCBData(taskid, itemid, sender, questions, object_name, owner_name); 4744 LLSD payload;
4745 payload["task_id"] = taskid;
4746 payload["item_id"] = itemid;
4747 payload["sender"] = sender.getIPandPort();
4748 payload["questions"] = questions;
4749 payload["object_name"] = object_name;
4750 payload["owner_name"] = owner_name;
4527 4751
4528 // check whether cautions are even enabled or not 4752 // check whether cautions are even enabled or not
4529 if (gSavedSettings.getBOOL("PermissionsCautionEnabled")) 4753 if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
4530 { 4754 {
4531 if (caution) 4755 // display the caution permissions prompt
4532 { 4756 LLNotifications::instance().add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
4533 // display the caution permissions prompt
4534 LLNotifyBox::showXml("ScriptQuestionCaution", args, TRUE, script_question_cb, cbdata);
4535 }
4536 else
4537 {
4538 // display the permissions request normally
4539 LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata);
4540 }
4541 } 4757 }
4542 else 4758 else
4543 { 4759 {
4544 // fall back to default behavior if cautions are entirely disabled 4760 // fall back to default behavior if cautions are entirely disabled
4545 LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata); 4761 LLNotifications::instance().add("ScriptQuestion", args, payload);
4546 } 4762 }
4547 4763
4548 } 4764 }
@@ -4677,20 +4893,66 @@ std::string formatted_time(const time_t& the_time)
4677void process_teleport_failed(LLMessageSystem *msg, void**) 4893void process_teleport_failed(LLMessageSystem *msg, void**)
4678{ 4894{
4679 std::string reason; 4895 std::string reason;
4680 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason); 4896 std::string big_reason;
4897 LLSD args;
4898
4899 // if we have additional alert data
4900 if (msg->getNumberOfBlocksFast(_PREHASH_AlertInfo) > 0)
4901 {
4902 // Get the message ID
4903 msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, reason);
4904 big_reason = LLAgent::sTeleportErrorMessages[reason];
4905 if ( big_reason.size() > 0 )
4906 { // Substitute verbose reason from the local map
4907 args["REASON"] = big_reason;
4908 }
4909 else
4910 { // Nothing found in the map - use what the server returned in the original message block
4911 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
4912 args["REASON"] = reason;
4913 }
4914
4915 LLSD llsd_block;
4916 std::string llsd_raw;
4917 msg->getStringFast(_PREHASH_AlertInfo, _PREHASH_ExtraParams, llsd_raw);
4918 if (llsd_raw.length())
4919 {
4920 std::istringstream llsd_data(llsd_raw);
4921 if (!LLSDSerialize::deserialize(llsd_block, llsd_data, llsd_raw.length()))
4922 {
4923 llwarns << "process_teleport_failed: Attempted to read alert parameter data into LLSD but failed:" << llsd_raw << llendl;
4924 }
4925 else
4926 {
4927 // change notification name in this special case
4928 if (handle_special_notification("RegionEntryAccessBlocked", llsd_block))
4929 {
4930 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
4931 {
4932 gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
4933 }
4934 return;
4935 }
4936 }
4937 }
4681 4938
4682 LLStringUtil::format_map_t args;
4683 std::string big_reason = LLAgent::sTeleportErrorMessages[reason];
4684 if ( big_reason.size() > 0 )
4685 { // Substitute verbose reason from the local map
4686 args["[REASON]"] = big_reason;
4687 } 4939 }
4688 else 4940 else
4689 { // Nothing found in the map - use what the server returned 4941 {
4690 args["[REASON]"] = reason; 4942 msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
4943
4944 big_reason = LLAgent::sTeleportErrorMessages[reason];
4945 if ( big_reason.size() > 0 )
4946 { // Substitute verbose reason from the local map
4947 args["REASON"] = big_reason;
4948 }
4949 else
4950 { // Nothing found in the map - use what the server returned
4951 args["REASON"] = reason;
4952 }
4691 } 4953 }
4692 4954
4693 gViewerWindow->alertXml("CouldNotTeleportReason", args); 4955 LLNotifications::instance().add("CouldNotTeleportReason", args);
4694 4956
4695 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) 4957 if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
4696 { 4958 {
@@ -4812,9 +5074,10 @@ void send_group_notice(const LLUUID& group_id,
4812 bin_bucket_size); 5074 bin_bucket_size);
4813} 5075}
4814 5076
4815void handle_lure_callback(S32 option, const std::string& text, void* userdata) 5077bool handle_lure_callback(const LLSD& notification, const LLSD& response)
4816{ 5078{
4817 LLDynamicArray<LLUUID>* invitees = (LLDynamicArray<LLUUID>*)userdata; 5079 std::string text = response["message"].asString();
5080 S32 option = LLNotification::getSelectedOption(notification, response);
4818 5081
4819 if(0 == option) 5082 if(0 == option)
4820 { 5083 {
@@ -4826,21 +5089,17 @@ void handle_lure_callback(S32 option, const std::string& text, void* userdata)
4826 msg->nextBlockFast(_PREHASH_Info); 5089 msg->nextBlockFast(_PREHASH_Info);
4827 msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in. 5090 msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
4828 msg->addStringFast(_PREHASH_Message, text); 5091 msg->addStringFast(_PREHASH_Message, text);
4829 for(LLDynamicArray<LLUUID>::iterator itr = invitees->begin(); itr != invitees->end(); ++itr) 5092 for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
5093 it != notification["payload"]["ids"].endArray();
5094 ++it)
4830 { 5095 {
4831 msg->nextBlockFast(_PREHASH_TargetData); 5096 msg->nextBlockFast(_PREHASH_TargetData);
4832 msg->addUUIDFast(_PREHASH_TargetID, *itr); 5097 msg->addUUIDFast(_PREHASH_TargetID, it->asUUID());
4833 } 5098 }
4834 gAgent.sendReliableMessage(); 5099 gAgent.sendReliableMessage();
4835 } 5100 }
4836 5101
4837 delete invitees; 5102 return false;
4838 invitees = NULL;
4839}
4840
4841void handle_lure_callback_godlike(S32 option, void* userdata)
4842{
4843 handle_lure_callback(option, LLStringUtil::null, userdata);
4844} 5103}
4845 5104
4846void handle_lure(const LLUUID& invitee) 5105void handle_lure(const LLUUID& invitee)
@@ -4853,21 +5112,23 @@ void handle_lure(const LLUUID& invitee)
4853// Prompt for a message to the invited user. 5112// Prompt for a message to the invited user.
4854void handle_lure(LLDynamicArray<LLUUID>& ids) 5113void handle_lure(LLDynamicArray<LLUUID>& ids)
4855{ 5114{
4856 LLDynamicArray<LLUUID>* userdata = new LLDynamicArray<LLUUID>(ids); 5115 LLSD edit_args;
5116 edit_args["REGION"] = gAgent.getRegion()->getName();
4857 5117
4858 LLStringUtil::format_map_t edit_args; 5118 LLSD payload;
4859 edit_args["[REGION]"] = gAgent.getRegion()->getName(); 5119 for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
5120 it != ids.end();
5121 ++it)
5122 {
5123 payload["ids"].append(*it);
5124 }
4860 if (gAgent.isGodlike()) 5125 if (gAgent.isGodlike())
4861 { 5126 {
4862 gViewerWindow->alertXmlEditText("OfferTeleportFromGod", edit_args, 5127 LLNotifications::instance().add("OfferTeleportFromGod", edit_args, payload, handle_lure_callback);
4863 &handle_lure_callback_godlike, userdata,
4864 NULL, NULL, edit_args);
4865 } 5128 }
4866 else 5129 else
4867 { 5130 {
4868 gViewerWindow->alertXmlEditText("OfferTeleport", edit_args, 5131 LLNotifications::instance().add("OfferTeleport", edit_args, payload, handle_lure_callback);
4869 NULL, NULL,
4870 handle_lure_callback, userdata, edit_args);
4871 } 5132 }
4872} 5133}
4873 5134
@@ -4959,21 +5220,13 @@ const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
4959const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512; 5220const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
4960const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n"; 5221const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
4961 5222
4962struct ScriptDialogInfo 5223bool callback_script_dialog(const LLSD& notification, const LLSD& response)
4963{
4964 LLHost mSender;
4965 LLUUID mObjectID;
4966 S32 mChatChannel;
4967 std::vector<std::string> mButtons;
4968};
4969
4970void callback_script_dialog(S32 option, void* data)
4971{ 5224{
4972 ScriptDialogInfo* info = (ScriptDialogInfo*)data; 5225 LLNotificationForm form(notification["form"]);
4973 if (!info) return; 5226 std::string button = LLNotification::getSelectedOptionName(response);
4974 5227 S32 button_idx = LLNotification::getSelectedOption(notification, response);
4975 // Didn't click "Ignore" 5228 // Didn't click "Ignore"
4976 if (0 != option) 5229 if (button_idx != -1)
4977 { 5230 {
4978 LLMessageSystem* msg = gMessageSystem; 5231 LLMessageSystem* msg = gMessageSystem;
4979 msg->newMessage("ScriptDialogReply"); 5232 msg->newMessage("ScriptDialogReply");
@@ -4981,112 +5234,109 @@ void callback_script_dialog(S32 option, void* data)
4981 msg->addUUID("AgentID", gAgent.getID()); 5234 msg->addUUID("AgentID", gAgent.getID());
4982 msg->addUUID("SessionID", gAgent.getSessionID()); 5235 msg->addUUID("SessionID", gAgent.getSessionID());
4983 msg->nextBlock("Data"); 5236 msg->nextBlock("Data");
4984 msg->addUUID("ObjectID", info->mObjectID); 5237 msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
4985 msg->addS32("ChatChannel", info->mChatChannel); 5238 msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
4986 msg->addS32("ButtonIndex", option); 5239 msg->addS32("ButtonIndex", button_idx);
4987 msg->addString("ButtonLabel", info->mButtons[option-1]); 5240 msg->addString("ButtonLabel", button);
4988 msg->sendReliable(info->mSender); 5241 msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
4989 } 5242 }
4990 5243
4991 delete info; 5244 return false;
4992} 5245}
5246static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog);
5247static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog);
4993 5248
4994void process_script_dialog(LLMessageSystem* msg, void**) 5249void process_script_dialog(LLMessageSystem* msg, void**)
4995{ 5250{
4996 S32 i; 5251 S32 i;
4997 5252
4998 ScriptDialogInfo* info = new ScriptDialogInfo; 5253 LLSD payload;
4999 5254
5000 std::string message; // Account for size of "Script Dialog:\n" 5255 std::string message;
5001 std::string first_name; 5256 std::string first_name;
5002 std::string last_name; 5257 std::string last_name;
5003 std::string title; 5258 std::string title;
5004 info->mSender = msg->getSender();
5005 5259
5006 msg->getUUID("Data", "ObjectID", info->mObjectID); 5260 LLUUID object_id;
5261 S32 chat_channel;
5262 msg->getUUID("Data", "ObjectID", object_id);
5007 msg->getString("Data", "FirstName", first_name); 5263 msg->getString("Data", "FirstName", first_name);
5008 msg->getString("Data", "LastName", last_name); 5264 msg->getString("Data", "LastName", last_name);
5009 msg->getString("Data", "ObjectName", title); 5265 msg->getString("Data", "ObjectName", title);
5010 msg->getString("Data", "Message", message); 5266 msg->getString("Data", "Message", message);
5011 msg->getS32("Data", "ChatChannel", info->mChatChannel); 5267 msg->getS32("Data", "ChatChannel", chat_channel);
5012 5268
5013 // unused for now 5269 // unused for now
5014 LLUUID image_id; 5270 LLUUID image_id;
5015 msg->getUUID("Data", "ImageID", image_id); 5271 msg->getUUID("Data", "ImageID", image_id);
5016 5272
5273 payload["sender"] = msg->getSender().getIPandPort();
5274 payload["object_id"] = object_id;
5275 payload["chat_channel"] = chat_channel;
5276
5277 // build up custom form
5017 S32 button_count = msg->getNumberOfBlocks("Buttons"); 5278 S32 button_count = msg->getNumberOfBlocks("Buttons");
5018 if (button_count > SCRIPT_DIALOG_MAX_BUTTONS) 5279 if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
5019 { 5280 {
5281 llwarns << "Too many script dialog buttons - omitting some" << llendl;
5020 button_count = SCRIPT_DIALOG_MAX_BUTTONS; 5282 button_count = SCRIPT_DIALOG_MAX_BUTTONS;
5021 } 5283 }
5022 5284
5285 LLNotificationForm form;
5023 for (i = 0; i < button_count; i++) 5286 for (i = 0; i < button_count; i++)
5024 { 5287 {
5025 std::string tdesc; 5288 std::string tdesc;
5026 msg->getString("Buttons", "ButtonLabel", tdesc, i); 5289 msg->getString("Buttons", "ButtonLabel", tdesc, i);
5027 info->mButtons.push_back(tdesc); 5290 form.addElement("button", std::string(tdesc));
5028 } 5291 }
5029 5292
5030 LLStringUtil::format_map_t args; 5293 LLSD args;
5031 args["[TITLE]"] = title; 5294 args["TITLE"] = title;
5032 args["[MESSAGE]"] = message; 5295 args["MESSAGE"] = message;
5296 LLNotificationPtr notification;
5033 if (!first_name.empty()) 5297 if (!first_name.empty())
5034 { 5298 {
5035 args["[FIRST]"] = first_name; 5299 args["FIRST"] = first_name;
5036 args["[LAST]"] = last_name; 5300 args["LAST"] = last_name;
5037 LLNotifyBox::showXml("ScriptDialog", args, 5301 notification = LLNotifications::instance().add(
5038 callback_script_dialog, info, 5302 LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));
5039 info->mButtons,
5040 TRUE);
5041 } 5303 }
5042 else 5304 else
5043 { 5305 {
5044 args["[GROUPNAME]"] = last_name; 5306 args["GROUPNAME"] = last_name;
5045 LLNotifyBox::showXml("ScriptDialogGroup", args, 5307 notification = LLNotifications::instance().add(
5046 callback_script_dialog, info, 5308 LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
5047 info->mButtons,
5048 TRUE);
5049 } 5309 }
5050} 5310}
5051 5311
5052//--------------------------------------------------------------------------- 5312//---------------------------------------------------------------------------
5053 5313
5054struct LoadUrlInfo
5055{
5056 LLUUID mObjectID;
5057 LLUUID mOwnerID;
5058 BOOL mOwnerIsGroup;
5059 std::string mObjectName;
5060 std::string mMessage;
5061 std::string mUrl;
5062};
5063 5314
5064std::vector<LoadUrlInfo*> gLoadUrlList; 5315std::vector<LLSD> gLoadUrlList;
5065 5316
5066void callback_load_url(S32 option, void* data) 5317bool callback_load_url(const LLSD& notification, const LLSD& response)
5067{ 5318{
5068 LoadUrlInfo* infop = (LoadUrlInfo*)data; 5319 S32 option = LLNotification::getSelectedOption(notification, response);
5069 if (!infop) return;
5070 5320
5071 if (0 == option) 5321 if (0 == option)
5072 { 5322 {
5073 LLWeb::loadURL(infop->mUrl); 5323 LLWeb::loadURL(notification["payload"]["url"].asString());
5074 } 5324 }
5075 5325
5076 delete infop; 5326 return false;
5077 infop = NULL;
5078} 5327}
5328static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
5079 5329
5080 5330
5081// We've got the name of the person who owns the object hurling the url. 5331// We've got the name of the person who owns the object hurling the url.
5082// Display confirmation dialog. 5332// Display confirmation dialog.
5083void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data) 5333void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
5084{ 5334{
5085 std::vector<LoadUrlInfo*>::iterator it; 5335 std::vector<LLSD>::iterator it;
5086 for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); ) 5336 for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
5087 { 5337 {
5088 LoadUrlInfo* infop = *it; 5338 LLSD load_url_info = *it;
5089 if (infop->mOwnerID == id) 5339 if (load_url_info["owner_id"].asUUID() == id)
5090 { 5340 {
5091 it = gLoadUrlList.erase(it); 5341 it = gLoadUrlList.erase(it);
5092 5342
@@ -5103,16 +5353,15 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
5103 // For legacy name-only mutes. 5353 // For legacy name-only mutes.
5104 if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name)) 5354 if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
5105 { 5355 {
5106 delete infop;
5107 infop = NULL;
5108 continue; 5356 continue;
5109 } 5357 }
5110 LLStringUtil::format_map_t args; 5358 LLSD args;
5111 args["[URL]"] = infop->mUrl; 5359 args["URL"] = load_url_info["url"].asString();
5112 args["[MESSAGE]"] = infop->mMessage; 5360 args["MESSAGE"] = load_url_info["message"].asString();;
5113 args["[OBJECTNAME]"] = infop->mObjectName; 5361 args["OBJECTNAME"] = load_url_info["object_name"].asString();
5114 args["[NAME]"] = owner_name; 5362 args["NAME"] = owner_name;
5115 LLNotifyBox::showXml("LoadWebPage", args, callback_load_url, infop); 5363
5364 LLNotifications::instance().add("LoadWebPage", args, load_url_info);
5116 } 5365 }
5117 else 5366 else
5118 { 5367 {
@@ -5123,40 +5372,51 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
5123 5372
5124void process_load_url(LLMessageSystem* msg, void**) 5373void process_load_url(LLMessageSystem* msg, void**)
5125{ 5374{
5126 LoadUrlInfo* infop = new LoadUrlInfo; 5375 LLUUID object_id;
5127 5376 LLUUID owner_id;
5128 msg->getString("Data", "ObjectName", infop->mObjectName); 5377 BOOL owner_is_group;
5129 msg->getUUID( "Data", "ObjectID", infop->mObjectID); 5378 char object_name[256]; /* Flawfinder: ignore */
5130 msg->getUUID( "Data", "OwnerID", infop->mOwnerID); 5379 char message[256]; /* Flawfinder: ignore */
5131 msg->getBOOL( "Data", "OwnerIsGroup", infop->mOwnerIsGroup); 5380 char url[256]; /* Flawfinder: ignore */
5132 msg->getString("Data", "Message", infop->mMessage); 5381
5133 msg->getString("Data", "URL", infop->mUrl); 5382 msg->getString("Data", "ObjectName", 256, object_name);
5383 msg->getUUID( "Data", "ObjectID", object_id);
5384 msg->getUUID( "Data", "OwnerID", owner_id);
5385 msg->getBOOL( "Data", "OwnerIsGroup", owner_is_group);
5386 msg->getString("Data", "Message", 256, message);
5387 msg->getString("Data", "URL", 256, url);
5388
5389 LLSD payload;
5390 payload["object_id"] = object_id;
5391 payload["owner_id"] = owner_id;
5392 payload["owner_is_group"] = owner_is_group;
5393 payload["object_name"] = object_name;
5394 payload["message"] = message;
5395 payload["url"] = url;
5134 5396
5135 // URL is safety checked in load_url above 5397 // URL is safety checked in load_url above
5136 5398
5137 // Check if object or owner is muted 5399 // Check if object or owner is muted
5138 if (LLMuteList::getInstance()->isMuted(infop->mObjectID, infop->mObjectName) || 5400 if (LLMuteList::getInstance()->isMuted(object_id, object_name) ||
5139 LLMuteList::getInstance()->isMuted(infop->mOwnerID)) 5401 LLMuteList::getInstance()->isMuted(owner_id))
5140 { 5402 {
5141 LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL; 5403 LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
5142 delete infop;
5143 infop = NULL;
5144 return; 5404 return;
5145 } 5405 }
5146 5406
5147 // Add to list of pending name lookups 5407 // Add to list of pending name lookups
5148 gLoadUrlList.push_back(infop); 5408 gLoadUrlList.push_back(payload);
5149 5409
5150 gCacheName->get(infop->mOwnerID, infop->mOwnerIsGroup, callback_load_url_name); 5410 gCacheName->get(owner_id, owner_is_group, callback_load_url_name);
5151} 5411}
5152 5412
5153 5413
5154void callback_download_complete(void** data, S32 result, LLExtStat ext_status) 5414void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
5155{ 5415{
5156 std::string* filepath = (std::string*)data; 5416 std::string* filepath = (std::string*)data;
5157 LLStringUtil::format_map_t args; 5417 LLSD args;
5158 args["[DOWNLOAD_PATH]"] = *filepath; 5418 args["DOWNLOAD_PATH"] = *filepath;
5159 gViewerWindow->alertXml("FinishedRawDownload", args); 5419 LLNotifications::instance().add("FinishedRawDownload", args);
5160 delete filepath; 5420 delete filepath;
5161} 5421}
5162 5422
@@ -5227,7 +5487,15 @@ void process_covenant_reply(LLMessageSystem* msg, void**)
5227 LLFloaterBuyLand::updateEstateName(estate_name); 5487 LLFloaterBuyLand::updateEstateName(estate_name);
5228 5488
5229 // standard message, not from system 5489 // standard message, not from system
5230 std::string last_modified = std::string("Last Modified ") + formatted_time((time_t)covenant_timestamp); 5490 std::string last_modified;
5491 if (covenant_timestamp == 0)
5492 {
5493 last_modified = LLTrans::getString("covenant_never_modified");
5494 }
5495 else
5496 {
5497 last_modified = LLTrans::getString("covenant_modified") + " " + formatted_time((time_t)covenant_timestamp);
5498 }
5231 5499
5232 LLPanelEstateCovenant::updateLastModified(last_modified); 5500 LLPanelEstateCovenant::updateLastModified(last_modified);
5233 LLPanelLandCovenant::updateLastModified(last_modified); 5501 LLPanelLandCovenant::updateLastModified(last_modified);
@@ -5387,4 +5655,11 @@ void invalid_message_callback(LLMessageSystem* msg,
5387} 5655}
5388 5656
5389// Please do not add more message handlers here. This file is huge. 5657// Please do not add more message handlers here. This file is huge.
5390// Put them in a file related to the functionality you are implementing. JC 5658// Put them in a file related to the functionality you are implementing.
5659
5660void LLOfferInfo::forceResponse(InventoryOfferResponse response)
5661{
5662 LLNotification::Params params("UserGiveItem");
5663 params.functor(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
5664 LLNotifications::instance().forceResponse(params, response);
5665}