summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt99
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/build_win32_appConfig.py28
-rw-r--r--indra/newview/character/avatar_eye.llmbin0 -> 16011 bytes
-rw-r--r--indra/newview/character/avatar_eye_1.llmbin0 -> 5591 bytes
-rw-r--r--indra/newview/character/avatar_eyelashes.llmbin0 -> 65637 bytes
-rw-r--r--indra/newview/character/avatar_hair.llmbin0 -> 690581 bytes
-rw-r--r--indra/newview/character/avatar_hair_1.llmbin0 -> 5031 bytes
-rw-r--r--indra/newview/character/avatar_hair_2.llmbin0 -> 3261 bytes
-rw-r--r--indra/newview/character/avatar_hair_3.llmbin0 -> 1845 bytes
-rw-r--r--indra/newview/character/avatar_hair_4.llmbin0 -> 927 bytes
-rw-r--r--indra/newview/character/avatar_hair_5.llmbin0 -> 927 bytes
-rw-r--r--indra/newview/character/avatar_head.llmbin0 -> 1665493 bytes
-rw-r--r--indra/newview/character/avatar_head_1.llmbin0 -> 7875 bytes
-rw-r--r--indra/newview/character/avatar_head_2.llmbin0 -> 3675 bytes
-rw-r--r--indra/newview/character/avatar_head_3.llmbin0 -> 1797 bytes
-rw-r--r--indra/newview/character/avatar_head_4.llmbin0 -> 1239 bytes
-rw-r--r--indra/newview/character/avatar_lower_body.llmbin0 -> 337125 bytes
-rw-r--r--indra/newview/character/avatar_lower_body_1.llmbin0 -> 7083 bytes
-rw-r--r--indra/newview/character/avatar_lower_body_2.llmbin0 -> 4107 bytes
-rw-r--r--indra/newview/character/avatar_lower_body_3.llmbin0 -> 2115 bytes
-rw-r--r--indra/newview/character/avatar_lower_body_4.llmbin0 -> 1629 bytes
-rw-r--r--indra/newview/character/avatar_skirt.llmbin0 -> 72497 bytes
-rw-r--r--indra/newview/character/avatar_skirt_1.llmbin0 -> 1899 bytes
-rw-r--r--indra/newview/character/avatar_skirt_2.llmbin0 -> 1551 bytes
-rw-r--r--indra/newview/character/avatar_skirt_3.llmbin0 -> 1191 bytes
-rw-r--r--indra/newview/character/avatar_skirt_4.llmbin0 -> 843 bytes
-rw-r--r--indra/newview/character/avatar_upper_body.llmbin0 -> 929297 bytes
-rw-r--r--indra/newview/character/avatar_upper_body_1.llmbin0 -> 15627 bytes
-rw-r--r--indra/newview/character/avatar_upper_body_2.llmbin0 -> 8991 bytes
-rw-r--r--indra/newview/character/avatar_upper_body_3.llmbin0 -> 4557 bytes
-rw-r--r--indra/newview/character/avatar_upper_body_4.llmbin0 -> 3453 bytes
-rw-r--r--indra/newview/character/blush_alpha.tgabin0 -> 17352 bytes
-rw-r--r--indra/newview/character/body_skingrain.tgabin0 -> 262188 bytes
-rw-r--r--indra/newview/character/bodyfreckles_alpha.tgabin0 -> 257249 bytes
-rw-r--r--indra/newview/character/bump_face_wrinkles.tgabin0 -> 25243 bytes
-rw-r--r--indra/newview/character/bump_head_base.tgabin0 -> 105525 bytes
-rw-r--r--indra/newview/character/bump_lowerbody_base.tgabin0 -> 112782 bytes
-rw-r--r--indra/newview/character/bump_pants_wrinkles.tgabin0 -> 83183 bytes
-rw-r--r--indra/newview/character/bump_shirt_wrinkles.tgabin0 -> 81501 bytes
-rw-r--r--indra/newview/character/bump_upperbody_base.tgabin0 -> 147581 bytes
-rw-r--r--indra/newview/character/eyebrows_alpha.tgabin0 -> 9469 bytes
-rw-r--r--indra/newview/character/eyeliner_alpha.tgabin0 -> 4720 bytes
-rw-r--r--indra/newview/character/eyeshadow_inner_alpha.tgabin0 -> 5466 bytes
-rw-r--r--indra/newview/character/eyeshadow_outer_alpha.tgabin0 -> 7382 bytes
-rw-r--r--indra/newview/character/eyewhite.tgabin0 -> 42353 bytes
-rw-r--r--indra/newview/character/facehair_chincurtains_alpha.tgabin0 -> 34610 bytes
-rw-r--r--indra/newview/character/facehair_moustache_alpha.tgabin0 -> 14017 bytes
-rw-r--r--indra/newview/character/facehair_sideburns_alpha.tgabin0 -> 27328 bytes
-rw-r--r--indra/newview/character/facehair_soulpatch_alpha.tgabin0 -> 11277 bytes
-rw-r--r--indra/newview/character/freckles_alpha.tgabin0 -> 140558 bytes
-rw-r--r--indra/newview/character/glove_length_alpha.tgabin0 -> 49745 bytes
-rw-r--r--indra/newview/character/gloves_fingers_alpha.tgabin0 -> 39616 bytes
-rw-r--r--indra/newview/character/head_alpha.tgabin0 -> 6066 bytes
-rw-r--r--indra/newview/character/head_color.tgabin0 -> 70715 bytes
-rw-r--r--indra/newview/character/head_hair.tgabin0 -> 75600 bytes
-rw-r--r--indra/newview/character/head_highlights_alpha.tgabin0 -> 20503 bytes
-rw-r--r--indra/newview/character/head_shading_alpha.tgabin0 -> 35304 bytes
-rw-r--r--indra/newview/character/head_skingrain.tgabin0 -> 262376 bytes
-rw-r--r--indra/newview/character/jacket_length_lower_alpha.tgabin0 -> 9768 bytes
-rw-r--r--indra/newview/character/jacket_length_upper_alpha.tgabin0 -> 14617 bytes
-rw-r--r--indra/newview/character/jacket_open_lower_alpha.tgabin0 -> 19732 bytes
-rw-r--r--indra/newview/character/jacket_open_upper_alpha.tgabin0 -> 41606 bytes
-rw-r--r--indra/newview/character/lipgloss_alpha.tgabin0 -> 4738 bytes
-rw-r--r--indra/newview/character/lips_mask.tgabin0 -> 6110 bytes
-rw-r--r--indra/newview/character/lipstick_alpha.tgabin0 -> 7966 bytes
-rw-r--r--indra/newview/character/lowerbody_color.tgabin0 -> 135395 bytes
-rw-r--r--indra/newview/character/lowerbody_highlights_alpha.tgabin0 -> 8695 bytes
-rw-r--r--indra/newview/character/lowerbody_shading_alpha.tgabin0 -> 41766 bytes
-rw-r--r--indra/newview/character/nailpolish_alpha.tgabin0 -> 4656 bytes
-rw-r--r--indra/newview/character/pants_length_alpha.tgabin0 -> 26843 bytes
-rw-r--r--indra/newview/character/pants_waist_alpha.tgabin0 -> 10487 bytes
-rw-r--r--indra/newview/character/rosyface_alpha.tgabin0 -> 44382 bytes
-rw-r--r--indra/newview/character/rouge_alpha.tgabin0 -> 44382 bytes
-rw-r--r--indra/newview/character/shirt_bottom_alpha.tgabin0 -> 32242 bytes
-rw-r--r--indra/newview/character/shirt_collar_alpha.tgabin0 -> 14417 bytes
-rw-r--r--indra/newview/character/shirt_collar_back_alpha.tgabin0 -> 12789 bytes
-rw-r--r--indra/newview/character/shirt_sleeve_alpha.tgabin0 -> 72196 bytes
-rw-r--r--indra/newview/character/shoe_height_alpha.tgabin0 -> 24461 bytes
-rw-r--r--indra/newview/character/skirt_length_alpha.tgabin0 -> 4114 bytes
-rw-r--r--indra/newview/character/skirt_slit_back_alpha.tgabin0 -> 90350 bytes
-rw-r--r--indra/newview/character/skirt_slit_front_alpha.tgabin0 -> 90350 bytes
-rw-r--r--indra/newview/character/skirt_slit_left_alpha.tgabin0 -> 82006 bytes
-rw-r--r--indra/newview/character/skirt_slit_right_alpha.tgabin0 -> 91410 bytes
-rw-r--r--indra/newview/character/underpants_trial_female.tgabin0 -> 48063 bytes
-rw-r--r--indra/newview/character/underpants_trial_male.tgabin0 -> 144983 bytes
-rw-r--r--indra/newview/character/undershirt_trial_female.tgabin0 -> 81390 bytes
-rw-r--r--indra/newview/character/upperbody_color.tgabin0 -> 23348 bytes
-rw-r--r--indra/newview/character/upperbody_highlights_alpha.tgabin0 -> 6509 bytes
-rw-r--r--indra/newview/character/upperbody_shading_alpha.tgabin0 -> 25297 bytes
-rw-r--r--indra/newview/character/upperbodyfreckles_alpha.tgabin0 -> 180104 bytes
-rw-r--r--indra/newview/da.lproj/language.txt1
-rw-r--r--indra/newview/es.lproj/language.txt1
-rw-r--r--indra/newview/featuretable.txt3
-rw-r--r--indra/newview/featuretable_linux.txt2
-rw-r--r--indra/newview/featuretable_mac.txt2
-rw-r--r--indra/newview/fr.lproj/language.txt1
-rw-r--r--indra/newview/hu.lproj/language.txt1
-rw-r--r--indra/newview/installers/windows/lang_fr.nsibin8118 -> 8114 bytes
-rw-r--r--indra/newview/it.lproj/language.txt1
-rw-r--r--indra/newview/llagent.cpp4
-rw-r--r--indra/newview/llagent.h4
-rw-r--r--indra/newview/llagentlistener.cpp78
-rw-r--r--indra/newview/llagentlistener.h36
-rw-r--r--indra/newview/llappviewer.cpp209
-rw-r--r--indra/newview/llappviewer.h14
-rw-r--r--indra/newview/llappviewerlistener.cpp37
-rw-r--r--indra/newview/llappviewerlistener.h34
-rw-r--r--indra/newview/llappviewermacosx.h1
-rw-r--r--indra/newview/llcapabilitylistener.cpp1
-rw-r--r--indra/newview/llclassifiedinfo.cpp36
-rw-r--r--indra/newview/llclassifiedinfo.h3
-rw-r--r--indra/newview/lldrawpoolsky.h4
-rw-r--r--indra/newview/lleventinfo.cpp36
-rw-r--r--indra/newview/lleventinfo.h3
-rw-r--r--indra/newview/lleventnotifier.cpp79
-rw-r--r--indra/newview/lleventnotifier.h5
-rw-r--r--indra/newview/llfasttimerview.cpp8
-rw-r--r--indra/newview/llfeaturemanager.cpp6
-rw-r--r--indra/newview/llfloaterabout.cpp533
-rw-r--r--indra/newview/llfloaterfriends.h3
-rw-r--r--indra/newview/llfloatertos.cpp37
-rw-r--r--indra/newview/llfloatertos.h4
-rw-r--r--indra/newview/llimview.cpp2
-rw-r--r--indra/newview/llinventoryactions.h47
-rw-r--r--indra/newview/llinventorymodel.cpp216
-rw-r--r--indra/newview/llinventorymodel.h6
-rw-r--r--indra/newview/lllogininstance.cpp468
-rw-r--r--indra/newview/lllogininstance.h111
-rw-r--r--indra/newview/llmenucommands.cpp1
-rw-r--r--indra/newview/llpanelplace.cpp1
-rw-r--r--indra/newview/llpanelplaceinfo.cpp1
-rw-r--r--indra/newview/llstartup.cpp1394
-rw-r--r--indra/newview/llstartup.h6
-rw-r--r--indra/newview/lluilistener.cpp50
-rw-r--r--indra/newview/lluilistener.h29
-rw-r--r--indra/newview/llviewercontrollistener.cpp102
-rw-r--r--indra/newview/llviewercontrollistener.h33
-rw-r--r--indra/newview/llviewermedia.cpp5
-rw-r--r--indra/newview/llviewermenu.cpp5
-rw-r--r--indra/newview/llviewernetwork.cpp6
-rw-r--r--indra/newview/llviewernetwork.h4
-rw-r--r--indra/newview/llviewerparcelmgr.cpp1
-rw-r--r--indra/newview/llviewerwindow.cpp8
-rw-r--r--indra/newview/llviewerwindow.h5
-rw-r--r--indra/newview/llviewerwindowlistener.cpp87
-rw-r--r--indra/newview/llviewerwindowlistener.h35
-rw-r--r--indra/newview/llxmlrpclistener.cpp496
-rw-r--r--indra/newview/llxmlrpclistener.h35
-rw-r--r--indra/newview/llxmlrpctransaction.cpp13
-rw-r--r--indra/newview/nl.lproj/language.txt1
-rw-r--r--indra/newview/pl.lproj/language.txt1
-rw-r--r--indra/newview/pt.lproj/language.txt1
-rw-r--r--indra/newview/ru.lproj/language.txt1
-rw-r--r--indra/newview/skins/default/xui/de/floater_snapshot.xml108
-rw-r--r--indra/newview/skins/default/xui/de/panel_preferences_general.xml72
-rw-r--r--indra/newview/skins/default/xui/es/floater_about_land.xml68
-rw-r--r--indra/newview/skins/default/xui/es/panel_preferences_general.xml72
-rw-r--r--indra/newview/skins/default/xui/fr/panel_preferences_general.xml80
-rw-r--r--indra/newview/skins/default/xui/it/floater_about_land.xml68
-rw-r--r--indra/newview/skins/default/xui/it/panel_preferences_general.xml72
-rw-r--r--indra/newview/skins/default/xui/ja/floater_about_land.xml68
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_general.xml80
-rw-r--r--indra/newview/skins/default/xui/nl/floater_about_land.xml68
-rwxr-xr-xindra/newview/skins/default/xui/pl/floater_about_land.xml68
-rw-r--r--indra/newview/skins/default/xui/pt/floater_about_land.xml68
-rw-r--r--indra/newview/skins/default/xui/pt/panel_preferences_general.xml72
-rw-r--r--indra/newview/tests/llagentaccess_test.cpp2
-rw-r--r--indra/newview/tests/llcapabilitylistener_test.cpp36
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp416
-rw-r--r--indra/newview/tests/llxmlrpclistener_test.cpp230
-rw-r--r--indra/newview/tests/test_llxmlrpc_peer.py59
-rw-r--r--indra/newview/tr.lproj/language.txt1
-rw-r--r--indra/newview/uk.lproj/language.txt1
-rwxr-xr-xindra/newview/viewer_manifest.py1502
-rw-r--r--indra/newview/zh-Hans.lproj/language.txt1
176 files changed, 4722 insertions, 2986 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ae3fa9a324..d7bb68a006 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -36,10 +36,7 @@ include(UI)
include(UnixInstall)
include(LLKDU)
include(ViewerMiscLibs)
-
-if (WINDOWS)
- include(CopyWinLibs)
-endif (WINDOWS)
+include(LLLogin)
include_directories(
${DBUSGLIB_INCLUDE_DIRS}
@@ -61,6 +58,7 @@ include_directories(
${LLXUIXML_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}/lscript_compile
+ ${LLLOGIN_INCLUDE_DIRS}
)
set(viewer_SOURCE_FILES
@@ -68,6 +66,7 @@ set(viewer_SOURCE_FILES
llaccordionctrl.cpp
llactiveimwindow.cpp
llagent.cpp
+ llagentlistener.cpp
llagentaccess.cpp
llagentdata.cpp
llagentlanguage.cpp
@@ -76,6 +75,7 @@ set(viewer_SOURCE_FILES
llagentwearables.cpp
llanimstatelabels.cpp
llappviewer.cpp
+ llappviewerlistener.cpp
llassetuploadresponders.cpp
llassetuploadqueue.cpp
llaudiosourcevo.cpp
@@ -253,6 +253,7 @@ set(viewer_SOURCE_FILES
llurllineeditorctrl.cpp
lllogchat.cpp
llloginhandler.cpp
+ lllogininstance.cpp
llmanip.cpp
llmaniprotate.cpp
llmanipscale.cpp
@@ -324,6 +325,7 @@ set(viewer_SOURCE_FILES
llpanelpicks.cpp
llpanelplace.cpp
llpanelplaceinfo.cpp
+ llpanelshower.cpp
llpanelplaces.cpp
llpanelplacestab.cpp
llpanelprofile.cpp
@@ -356,7 +358,6 @@ set(viewer_SOURCE_FILES
llspatialpartition.cpp
llsplitbutton.cpp
llsprite.cpp
- llsrv.cpp
llstartup.cpp
llstatusbar.cpp
llstylemap.cpp
@@ -400,19 +401,20 @@ set(viewer_SOURCE_FILES
lltoolselectland.cpp
lltoolselectrect.cpp
lltracker.cpp
+ lluilistener.cpp
lluploaddialog.cpp
llurl.cpp
llurldispatcher.cpp
llurlhistory.cpp
llurlsimstring.cpp
llurlwhitelist.cpp
- lluserauth.cpp
llvectorperfoptions.cpp
llviewchildren.cpp
llviewerassetstorage.cpp
llvieweraudio.cpp
llviewercamera.cpp
llviewercontrol.cpp
+ llviewercontrollistener.cpp
llviewerdisplay.cpp
llviewerfloaterreg.cpp
llviewergenericmessage.cpp
@@ -452,6 +454,7 @@ set(viewer_SOURCE_FILES
llviewerthrottle.cpp
llviewervisualparam.cpp
llviewerwindow.cpp
+ llviewerwindowlistener.cpp
llvlcomposition.cpp
llvlmanager.cpp
llvoavatar.cpp
@@ -490,6 +493,7 @@ set(viewer_SOURCE_FILES
llworld.cpp
llworldmap.cpp
llworldmapview.cpp
+ llxmlrpclistener.cpp
llxmlrpctransaction.cpp
noise.cpp
pipeline.cpp
@@ -519,6 +523,7 @@ set(viewer_HEADER_FILES
llaccordionctrl.h
llactiveimwindow.h
llagent.h
+ llagentlistener.h
llagentaccess.h
llagentdata.h
llagentlanguage.h
@@ -528,6 +533,7 @@ set(viewer_HEADER_FILES
llanimstatelabels.h
llappearance.h
llappviewer.h
+ llappviewerlistener.h
llassetuploadresponders.h
llassetuploadqueue.h
llaudiosourcevo.h
@@ -707,6 +713,7 @@ set(viewer_HEADER_FILES
llurllineeditorctrl.h
lllogchat.h
llloginhandler.h
+ lllogininstance.h
llmanip.h
llmaniprotate.h
llmanipscale.h
@@ -776,6 +783,7 @@ set(viewer_HEADER_FILES
llpanelpicks.h
llpanelplace.h
llpanelplaceinfo.h
+ llpanelshower.h
llpanelplaces.h
llpanelplacestab.h
llpanelprofile.h
@@ -810,7 +818,6 @@ set(viewer_HEADER_FILES
llspatialpartition.h
llsplitbutton.h
llsprite.h
- llsrv.h
llstartup.h
llstatusbar.h
llstylemap.h
@@ -856,13 +863,13 @@ set(viewer_HEADER_FILES
lltoolselectrect.h
lltracker.h
lluiconstants.h
+ lluilistener.h
lluploaddialog.h
llurl.h
llurldispatcher.h
llurlhistory.h
llurlsimstring.h
llurlwhitelist.h
- lluserauth.h
llvectorperfoptions.h
llviewchildren.h
llviewerassetstorage.h
@@ -870,6 +877,7 @@ set(viewer_HEADER_FILES
llviewerbuild.h
llviewercamera.h
llviewercontrol.h
+ llviewercontrollistener.h
llviewerdisplay.h
llviewerfloaterreg.h
llviewergenericmessage.h
@@ -907,6 +915,7 @@ set(viewer_HEADER_FILES
llviewerthrottle.h
llviewervisualparam.h
llviewerwindow.h
+ llviewerwindowlistener.h
llvlcomposition.h
llvlmanager.h
llvoavatar.h
@@ -947,6 +956,7 @@ set(viewer_HEADER_FILES
llworld.h
llworldmap.h
llworldmapview.h
+ llxmlrpclistener.h
llxmlrpctransaction.h
macmain.h
noise.h
@@ -1149,6 +1159,15 @@ file(GLOB DEFAULT_WIDGET_FILE_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/skins/default/xui/en/widgets/*.xml)
list(APPEND viewer_XUI_FILES ${DEFAULT_WIDGET_FILE_GLOB_LIST})
+file(GLOB SILVER_XUI_FILE_GLOB_LIST
+ ${CMAKE_CURRENT_SOURCE_DIR}/skins/silver/xui/en-us/*.xml)
+list(APPEND viewer_XUI_FILES ${SILVER_XUI_FILE_GLOB_LIST})
+
+# Cannot append empty lists in CMake, wait until we have files here.
+#file(GLOB SILVER_WIDGET_FILE_GLOB_LIST
+# ${CMAKE_CURRENT_SOURCE_DIR}/skins/silver/xui/en-us/widgets/*.xml)
+#list(APPEND viewer_XUI_FILES ${SILVER_WIDGET_FILE_GLOB_LIST})
+
list(SORT viewer_XUI_FILES)
source_group("XUI Files" FILES ${viewer_XUI_FILES})
@@ -1259,6 +1278,11 @@ if (LLKDU_LIBRARY)
add_dependencies(${VIEWER_BINARY_NAME} ${LLKDU_LIBRARY})
endif (LLKDU_LIBRARY)
+# add package files
+file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
+ ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
+list(APPEND EVENT_HOST_SCRIPTS ${EVENT_HOST_SCRIPT_GLOB_LIST})
+
set(PACKAGE OFF CACHE BOOL
"Add a package target that builds an installer package.")
@@ -1315,7 +1339,41 @@ if (WINDOWS)
COMMENT "Copying message.xml to the runtime folder."
)
- add_dependencies(${VIEWER_BINARY_NAME} copy_win_libs)
+ if(WINDOWS)
+ # Copy Win Libs...
+ # This happens at build time, not config time. We can't glob files in this cmake.
+ # *FIX:Mani Write a sub script to glob the files...
+ add_custom_command(
+ TARGET ${VIEWER_BINARY_NAME} PRE_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ ARGS
+ -E
+ copy_directory
+ ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+ COMMENT "Copying staged dlls."
+ )
+
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${VIEWER_BINARY_NAME}.exe.config
+ COMMAND ${PYTHON_EXECUTABLE}
+ ARGS
+ ${CMAKE_CURRENT_SOURCE_DIR}/build_win32_appConfig.py
+ ${CMAKE_CFG_INTDIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+ ${VIEWER_BINARY_NAME}.exe.config
+ COMMENT "Creating app.config file"
+ )
+
+ add_custom_target(create_app_config_file ALL
+ DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${VIEWER_BINARY_NAME}.exe.config
+ )
+
+ add_dependencies(${VIEWER_BINARY_NAME} create_app_config_file)
+
+ endif(WINDOWS)
if (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts)
@@ -1341,8 +1399,27 @@ if (WINDOWS)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit media_plugin_flash_activex media_plugin_awesomium)
if (PACKAGE)
- add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat)
+ add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
+ COMMAND ${PYTHON_EXECUTABLE}
+ ARGS
+ ${CMAKE_CURRENT_SOURCE_DIR}/event_host_manifest.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CFG_INTDIR}
+
+ DEPENDS
+ lleventhost
+ ${EVENT_HOST_SCRIPTS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/event_host_manifest.py)
+
+ add_custom_target(package ALL
+ DEPENDS
+ ${CMAKE_CFG_INTDIR}/touched.bat
+ ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2)
add_dependencies(package windows-updater windows-crash-logger)
+
+
endif (PACKAGE)
endif (WINDOWS)
@@ -1379,6 +1456,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${WINDOWS_LIBRARIES}
${XMLRPCEPI_LIBRARIES}
${ELFIO_LIBRARIES}
+ ${LLLOGIN_LIBRARIES}
${GOOGLE_PERFTOOLS_LIBRARIES}
)
@@ -1509,6 +1587,7 @@ endif (INSTALL)
include(LLAddBuildTest)
SET(viewer_TEST_SOURCE_FILES
llagentaccess.cpp
+ lllogininstance.cpp
# Not *actually* a unit test, it's an integration test.
# Because it won't work in the new unit test iface, i've commented out
# and notified Nat. Delete this when it's replaced!
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4e64b8662c..2fe8fd5b00 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5337,6 +5337,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>QAModeEventHostPort</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable Testing Features.</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>-1</integer>
+ </map>
<key>QuietSnapshotsToDisk</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/build_win32_appConfig.py b/indra/newview/build_win32_appConfig.py
index fb6a0258bc..8eadf0068f 100644
--- a/indra/newview/build_win32_appConfig.py
+++ b/indra/newview/build_win32_appConfig.py
@@ -31,11 +31,7 @@
import sys, os, re
from xml.dom.minidom import parse
-def main():
- src_manifest_name = sys.argv[1]
- src_config_name = sys.argv[2]
- dst_config_name = sys.argv[3]
-
+def munge_binding_redirect_version(src_manifest_name, src_config_name, dst_config_name):
manifest_dom = parse(src_manifest_name)
node = manifest_dom.getElementsByTagName('assemblyIdentity')[0]
manifest_assm_ver = node.getAttribute('version')
@@ -47,11 +43,31 @@ def main():
node.setAttribute('oldVersion', src_old_ver + manifest_assm_ver)
comment = config_dom.createComment("This file is automatically generated by the build. see indra/newview/build_win32_appConfig.py")
config_dom.insertBefore(comment, config_dom.childNodes[0])
-
+
+ print "Writing: " + dst_config_name
f = open(dst_config_name, 'w')
config_dom.writexml(f)
f.close()
+
+
+
+def main():
+ config = sys.argv[1]
+ src_dir = sys.argv[2]
+ dst_dir = sys.argv[3]
+ dst_name = sys.argv[4]
+
+ if config.lower() == 'debug':
+ src_manifest_name = dst_dir + '/Microsoft.VC80.DebugCRT.manifest'
+ src_config_name = src_dir + '/SecondLifeDebug.exe.config'
+ else:
+ src_manifest_name = dst_dir + '/Microsoft.VC80.CRT.manifest'
+ src_config_name = src_dir + '/SecondLife.exe.config'
+
+ dst_config_name = dst_dir + '/' + dst_name
+ munge_binding_redirect_version(src_manifest_name, src_config_name, dst_config_name)
+
return 0
if __name__ == "__main__":
diff --git a/indra/newview/character/avatar_eye.llm b/indra/newview/character/avatar_eye.llm
new file mode 100644
index 0000000000..8c6e74e1de
--- /dev/null
+++ b/indra/newview/character/avatar_eye.llm
Binary files differ
diff --git a/indra/newview/character/avatar_eye_1.llm b/indra/newview/character/avatar_eye_1.llm
new file mode 100644
index 0000000000..7a3b0d6f28
--- /dev/null
+++ b/indra/newview/character/avatar_eye_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_eyelashes.llm b/indra/newview/character/avatar_eyelashes.llm
new file mode 100644
index 0000000000..99995b5758
--- /dev/null
+++ b/indra/newview/character/avatar_eyelashes.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair.llm b/indra/newview/character/avatar_hair.llm
new file mode 100644
index 0000000000..df99de8db7
--- /dev/null
+++ b/indra/newview/character/avatar_hair.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_1.llm b/indra/newview/character/avatar_hair_1.llm
new file mode 100644
index 0000000000..6de31fdc23
--- /dev/null
+++ b/indra/newview/character/avatar_hair_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_2.llm b/indra/newview/character/avatar_hair_2.llm
new file mode 100644
index 0000000000..47d02ba9ce
--- /dev/null
+++ b/indra/newview/character/avatar_hair_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_3.llm b/indra/newview/character/avatar_hair_3.llm
new file mode 100644
index 0000000000..107f9e2a53
--- /dev/null
+++ b/indra/newview/character/avatar_hair_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_4.llm b/indra/newview/character/avatar_hair_4.llm
new file mode 100644
index 0000000000..1b9a12a0ca
--- /dev/null
+++ b/indra/newview/character/avatar_hair_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_hair_5.llm b/indra/newview/character/avatar_hair_5.llm
new file mode 100644
index 0000000000..1b9a12a0ca
--- /dev/null
+++ b/indra/newview/character/avatar_hair_5.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head.llm b/indra/newview/character/avatar_head.llm
new file mode 100644
index 0000000000..8d8b5e0442
--- /dev/null
+++ b/indra/newview/character/avatar_head.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_1.llm b/indra/newview/character/avatar_head_1.llm
new file mode 100644
index 0000000000..26291e6584
--- /dev/null
+++ b/indra/newview/character/avatar_head_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_2.llm b/indra/newview/character/avatar_head_2.llm
new file mode 100644
index 0000000000..c2b808b1a6
--- /dev/null
+++ b/indra/newview/character/avatar_head_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_3.llm b/indra/newview/character/avatar_head_3.llm
new file mode 100644
index 0000000000..a0676b1f1c
--- /dev/null
+++ b/indra/newview/character/avatar_head_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_head_4.llm b/indra/newview/character/avatar_head_4.llm
new file mode 100644
index 0000000000..5035585770
--- /dev/null
+++ b/indra/newview/character/avatar_head_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body.llm b/indra/newview/character/avatar_lower_body.llm
new file mode 100644
index 0000000000..0420899739
--- /dev/null
+++ b/indra/newview/character/avatar_lower_body.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_1.llm b/indra/newview/character/avatar_lower_body_1.llm
new file mode 100644
index 0000000000..1394eb848b
--- /dev/null
+++ b/indra/newview/character/avatar_lower_body_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_2.llm b/indra/newview/character/avatar_lower_body_2.llm
new file mode 100644
index 0000000000..0da9c1249e
--- /dev/null
+++ b/indra/newview/character/avatar_lower_body_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_3.llm b/indra/newview/character/avatar_lower_body_3.llm
new file mode 100644
index 0000000000..f3c49a1568
--- /dev/null
+++ b/indra/newview/character/avatar_lower_body_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_lower_body_4.llm b/indra/newview/character/avatar_lower_body_4.llm
new file mode 100644
index 0000000000..e71721063e
--- /dev/null
+++ b/indra/newview/character/avatar_lower_body_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt.llm b/indra/newview/character/avatar_skirt.llm
new file mode 100644
index 0000000000..08ce3d1700
--- /dev/null
+++ b/indra/newview/character/avatar_skirt.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_1.llm b/indra/newview/character/avatar_skirt_1.llm
new file mode 100644
index 0000000000..88076c321f
--- /dev/null
+++ b/indra/newview/character/avatar_skirt_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_2.llm b/indra/newview/character/avatar_skirt_2.llm
new file mode 100644
index 0000000000..73b3effbc6
--- /dev/null
+++ b/indra/newview/character/avatar_skirt_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_3.llm b/indra/newview/character/avatar_skirt_3.llm
new file mode 100644
index 0000000000..ded546fdea
--- /dev/null
+++ b/indra/newview/character/avatar_skirt_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_skirt_4.llm b/indra/newview/character/avatar_skirt_4.llm
new file mode 100644
index 0000000000..b9d5cb945e
--- /dev/null
+++ b/indra/newview/character/avatar_skirt_4.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body.llm b/indra/newview/character/avatar_upper_body.llm
new file mode 100644
index 0000000000..da7d990540
--- /dev/null
+++ b/indra/newview/character/avatar_upper_body.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_1.llm b/indra/newview/character/avatar_upper_body_1.llm
new file mode 100644
index 0000000000..31e104cc20
--- /dev/null
+++ b/indra/newview/character/avatar_upper_body_1.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_2.llm b/indra/newview/character/avatar_upper_body_2.llm
new file mode 100644
index 0000000000..c1f4199b9c
--- /dev/null
+++ b/indra/newview/character/avatar_upper_body_2.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_3.llm b/indra/newview/character/avatar_upper_body_3.llm
new file mode 100644
index 0000000000..9e89ed8b3e
--- /dev/null
+++ b/indra/newview/character/avatar_upper_body_3.llm
Binary files differ
diff --git a/indra/newview/character/avatar_upper_body_4.llm b/indra/newview/character/avatar_upper_body_4.llm
new file mode 100644
index 0000000000..ec836d1dc3
--- /dev/null
+++ b/indra/newview/character/avatar_upper_body_4.llm
Binary files differ
diff --git a/indra/newview/character/blush_alpha.tga b/indra/newview/character/blush_alpha.tga
new file mode 100644
index 0000000000..05be7e7e3d
--- /dev/null
+++ b/indra/newview/character/blush_alpha.tga
Binary files differ
diff --git a/indra/newview/character/body_skingrain.tga b/indra/newview/character/body_skingrain.tga
new file mode 100644
index 0000000000..7264baac14
--- /dev/null
+++ b/indra/newview/character/body_skingrain.tga
Binary files differ
diff --git a/indra/newview/character/bodyfreckles_alpha.tga b/indra/newview/character/bodyfreckles_alpha.tga
new file mode 100644
index 0000000000..d30ab3d122
--- /dev/null
+++ b/indra/newview/character/bodyfreckles_alpha.tga
Binary files differ
diff --git a/indra/newview/character/bump_face_wrinkles.tga b/indra/newview/character/bump_face_wrinkles.tga
new file mode 100644
index 0000000000..54bf7a55be
--- /dev/null
+++ b/indra/newview/character/bump_face_wrinkles.tga
Binary files differ
diff --git a/indra/newview/character/bump_head_base.tga b/indra/newview/character/bump_head_base.tga
new file mode 100644
index 0000000000..fa3568573a
--- /dev/null
+++ b/indra/newview/character/bump_head_base.tga
Binary files differ
diff --git a/indra/newview/character/bump_lowerbody_base.tga b/indra/newview/character/bump_lowerbody_base.tga
new file mode 100644
index 0000000000..498ea3c721
--- /dev/null
+++ b/indra/newview/character/bump_lowerbody_base.tga
Binary files differ
diff --git a/indra/newview/character/bump_pants_wrinkles.tga b/indra/newview/character/bump_pants_wrinkles.tga
new file mode 100644
index 0000000000..cca72415e8
--- /dev/null
+++ b/indra/newview/character/bump_pants_wrinkles.tga
Binary files differ
diff --git a/indra/newview/character/bump_shirt_wrinkles.tga b/indra/newview/character/bump_shirt_wrinkles.tga
new file mode 100644
index 0000000000..9e0d757a48
--- /dev/null
+++ b/indra/newview/character/bump_shirt_wrinkles.tga
Binary files differ
diff --git a/indra/newview/character/bump_upperbody_base.tga b/indra/newview/character/bump_upperbody_base.tga
new file mode 100644
index 0000000000..e57d6352e6
--- /dev/null
+++ b/indra/newview/character/bump_upperbody_base.tga
Binary files differ
diff --git a/indra/newview/character/eyebrows_alpha.tga b/indra/newview/character/eyebrows_alpha.tga
new file mode 100644
index 0000000000..c363e482e1
--- /dev/null
+++ b/indra/newview/character/eyebrows_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyeliner_alpha.tga b/indra/newview/character/eyeliner_alpha.tga
new file mode 100644
index 0000000000..1611eb3355
--- /dev/null
+++ b/indra/newview/character/eyeliner_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyeshadow_inner_alpha.tga b/indra/newview/character/eyeshadow_inner_alpha.tga
new file mode 100644
index 0000000000..37d7919395
--- /dev/null
+++ b/indra/newview/character/eyeshadow_inner_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyeshadow_outer_alpha.tga b/indra/newview/character/eyeshadow_outer_alpha.tga
new file mode 100644
index 0000000000..00eef9d9f7
--- /dev/null
+++ b/indra/newview/character/eyeshadow_outer_alpha.tga
Binary files differ
diff --git a/indra/newview/character/eyewhite.tga b/indra/newview/character/eyewhite.tga
new file mode 100644
index 0000000000..a720496988
--- /dev/null
+++ b/indra/newview/character/eyewhite.tga
Binary files differ
diff --git a/indra/newview/character/facehair_chincurtains_alpha.tga b/indra/newview/character/facehair_chincurtains_alpha.tga
new file mode 100644
index 0000000000..b10397063c
--- /dev/null
+++ b/indra/newview/character/facehair_chincurtains_alpha.tga
Binary files differ
diff --git a/indra/newview/character/facehair_moustache_alpha.tga b/indra/newview/character/facehair_moustache_alpha.tga
new file mode 100644
index 0000000000..4068c4f2b1
--- /dev/null
+++ b/indra/newview/character/facehair_moustache_alpha.tga
Binary files differ
diff --git a/indra/newview/character/facehair_sideburns_alpha.tga b/indra/newview/character/facehair_sideburns_alpha.tga
new file mode 100644
index 0000000000..acddc2d9bd
--- /dev/null
+++ b/indra/newview/character/facehair_sideburns_alpha.tga
Binary files differ
diff --git a/indra/newview/character/facehair_soulpatch_alpha.tga b/indra/newview/character/facehair_soulpatch_alpha.tga
new file mode 100644
index 0000000000..687091a29f
--- /dev/null
+++ b/indra/newview/character/facehair_soulpatch_alpha.tga
Binary files differ
diff --git a/indra/newview/character/freckles_alpha.tga b/indra/newview/character/freckles_alpha.tga
new file mode 100644
index 0000000000..a9a4ec0735
--- /dev/null
+++ b/indra/newview/character/freckles_alpha.tga
Binary files differ
diff --git a/indra/newview/character/glove_length_alpha.tga b/indra/newview/character/glove_length_alpha.tga
new file mode 100644
index 0000000000..db89ad57e7
--- /dev/null
+++ b/indra/newview/character/glove_length_alpha.tga
Binary files differ
diff --git a/indra/newview/character/gloves_fingers_alpha.tga b/indra/newview/character/gloves_fingers_alpha.tga
new file mode 100644
index 0000000000..dba2eec277
--- /dev/null
+++ b/indra/newview/character/gloves_fingers_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_alpha.tga b/indra/newview/character/head_alpha.tga
new file mode 100644
index 0000000000..8164525353
--- /dev/null
+++ b/indra/newview/character/head_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_color.tga b/indra/newview/character/head_color.tga
new file mode 100644
index 0000000000..74b1b3078b
--- /dev/null
+++ b/indra/newview/character/head_color.tga
Binary files differ
diff --git a/indra/newview/character/head_hair.tga b/indra/newview/character/head_hair.tga
new file mode 100644
index 0000000000..5321f35204
--- /dev/null
+++ b/indra/newview/character/head_hair.tga
Binary files differ
diff --git a/indra/newview/character/head_highlights_alpha.tga b/indra/newview/character/head_highlights_alpha.tga
new file mode 100644
index 0000000000..8dc5239f97
--- /dev/null
+++ b/indra/newview/character/head_highlights_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_shading_alpha.tga b/indra/newview/character/head_shading_alpha.tga
new file mode 100644
index 0000000000..e8ea490109
--- /dev/null
+++ b/indra/newview/character/head_shading_alpha.tga
Binary files differ
diff --git a/indra/newview/character/head_skingrain.tga b/indra/newview/character/head_skingrain.tga
new file mode 100644
index 0000000000..b42dee0809
--- /dev/null
+++ b/indra/newview/character/head_skingrain.tga
Binary files differ
diff --git a/indra/newview/character/jacket_length_lower_alpha.tga b/indra/newview/character/jacket_length_lower_alpha.tga
new file mode 100644
index 0000000000..722bc192a8
--- /dev/null
+++ b/indra/newview/character/jacket_length_lower_alpha.tga
Binary files differ
diff --git a/indra/newview/character/jacket_length_upper_alpha.tga b/indra/newview/character/jacket_length_upper_alpha.tga
new file mode 100644
index 0000000000..e9db7e7b1f
--- /dev/null
+++ b/indra/newview/character/jacket_length_upper_alpha.tga
Binary files differ
diff --git a/indra/newview/character/jacket_open_lower_alpha.tga b/indra/newview/character/jacket_open_lower_alpha.tga
new file mode 100644
index 0000000000..db0c2fb0e3
--- /dev/null
+++ b/indra/newview/character/jacket_open_lower_alpha.tga
Binary files differ
diff --git a/indra/newview/character/jacket_open_upper_alpha.tga b/indra/newview/character/jacket_open_upper_alpha.tga
new file mode 100644
index 0000000000..71b8a0b805
--- /dev/null
+++ b/indra/newview/character/jacket_open_upper_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lipgloss_alpha.tga b/indra/newview/character/lipgloss_alpha.tga
new file mode 100644
index 0000000000..78ceecaf85
--- /dev/null
+++ b/indra/newview/character/lipgloss_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lips_mask.tga b/indra/newview/character/lips_mask.tga
new file mode 100644
index 0000000000..ae1401c006
--- /dev/null
+++ b/indra/newview/character/lips_mask.tga
Binary files differ
diff --git a/indra/newview/character/lipstick_alpha.tga b/indra/newview/character/lipstick_alpha.tga
new file mode 100644
index 0000000000..2795f1bd40
--- /dev/null
+++ b/indra/newview/character/lipstick_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lowerbody_color.tga b/indra/newview/character/lowerbody_color.tga
new file mode 100644
index 0000000000..a63aa12fca
--- /dev/null
+++ b/indra/newview/character/lowerbody_color.tga
Binary files differ
diff --git a/indra/newview/character/lowerbody_highlights_alpha.tga b/indra/newview/character/lowerbody_highlights_alpha.tga
new file mode 100644
index 0000000000..ae3413ac8b
--- /dev/null
+++ b/indra/newview/character/lowerbody_highlights_alpha.tga
Binary files differ
diff --git a/indra/newview/character/lowerbody_shading_alpha.tga b/indra/newview/character/lowerbody_shading_alpha.tga
new file mode 100644
index 0000000000..0242663a7d
--- /dev/null
+++ b/indra/newview/character/lowerbody_shading_alpha.tga
Binary files differ
diff --git a/indra/newview/character/nailpolish_alpha.tga b/indra/newview/character/nailpolish_alpha.tga
new file mode 100644
index 0000000000..91af762902
--- /dev/null
+++ b/indra/newview/character/nailpolish_alpha.tga
Binary files differ
diff --git a/indra/newview/character/pants_length_alpha.tga b/indra/newview/character/pants_length_alpha.tga
new file mode 100644
index 0000000000..3c4f21c0f2
--- /dev/null
+++ b/indra/newview/character/pants_length_alpha.tga
Binary files differ
diff --git a/indra/newview/character/pants_waist_alpha.tga b/indra/newview/character/pants_waist_alpha.tga
new file mode 100644
index 0000000000..35658c0896
--- /dev/null
+++ b/indra/newview/character/pants_waist_alpha.tga
Binary files differ
diff --git a/indra/newview/character/rosyface_alpha.tga b/indra/newview/character/rosyface_alpha.tga
new file mode 100644
index 0000000000..a0c8513da2
--- /dev/null
+++ b/indra/newview/character/rosyface_alpha.tga
Binary files differ
diff --git a/indra/newview/character/rouge_alpha.tga b/indra/newview/character/rouge_alpha.tga
new file mode 100644
index 0000000000..a0c8513da2
--- /dev/null
+++ b/indra/newview/character/rouge_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_bottom_alpha.tga b/indra/newview/character/shirt_bottom_alpha.tga
new file mode 100644
index 0000000000..7cce03dbe0
--- /dev/null
+++ b/indra/newview/character/shirt_bottom_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_collar_alpha.tga b/indra/newview/character/shirt_collar_alpha.tga
new file mode 100644
index 0000000000..f55f635473
--- /dev/null
+++ b/indra/newview/character/shirt_collar_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_collar_back_alpha.tga b/indra/newview/character/shirt_collar_back_alpha.tga
new file mode 100644
index 0000000000..43a6453107
--- /dev/null
+++ b/indra/newview/character/shirt_collar_back_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shirt_sleeve_alpha.tga b/indra/newview/character/shirt_sleeve_alpha.tga
new file mode 100644
index 0000000000..e3b18f4fc6
--- /dev/null
+++ b/indra/newview/character/shirt_sleeve_alpha.tga
Binary files differ
diff --git a/indra/newview/character/shoe_height_alpha.tga b/indra/newview/character/shoe_height_alpha.tga
new file mode 100644
index 0000000000..d08dd750f3
--- /dev/null
+++ b/indra/newview/character/shoe_height_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_length_alpha.tga b/indra/newview/character/skirt_length_alpha.tga
new file mode 100644
index 0000000000..c86799469d
--- /dev/null
+++ b/indra/newview/character/skirt_length_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_back_alpha.tga b/indra/newview/character/skirt_slit_back_alpha.tga
new file mode 100644
index 0000000000..0e49688b14
--- /dev/null
+++ b/indra/newview/character/skirt_slit_back_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_front_alpha.tga b/indra/newview/character/skirt_slit_front_alpha.tga
new file mode 100644
index 0000000000..888bbf71a1
--- /dev/null
+++ b/indra/newview/character/skirt_slit_front_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_left_alpha.tga b/indra/newview/character/skirt_slit_left_alpha.tga
new file mode 100644
index 0000000000..210feac1ea
--- /dev/null
+++ b/indra/newview/character/skirt_slit_left_alpha.tga
Binary files differ
diff --git a/indra/newview/character/skirt_slit_right_alpha.tga b/indra/newview/character/skirt_slit_right_alpha.tga
new file mode 100644
index 0000000000..ce11c64bf6
--- /dev/null
+++ b/indra/newview/character/skirt_slit_right_alpha.tga
Binary files differ
diff --git a/indra/newview/character/underpants_trial_female.tga b/indra/newview/character/underpants_trial_female.tga
new file mode 100644
index 0000000000..96bf732351
--- /dev/null
+++ b/indra/newview/character/underpants_trial_female.tga
Binary files differ
diff --git a/indra/newview/character/underpants_trial_male.tga b/indra/newview/character/underpants_trial_male.tga
new file mode 100644
index 0000000000..095695ca1c
--- /dev/null
+++ b/indra/newview/character/underpants_trial_male.tga
Binary files differ
diff --git a/indra/newview/character/undershirt_trial_female.tga b/indra/newview/character/undershirt_trial_female.tga
new file mode 100644
index 0000000000..e17a309531
--- /dev/null
+++ b/indra/newview/character/undershirt_trial_female.tga
Binary files differ
diff --git a/indra/newview/character/upperbody_color.tga b/indra/newview/character/upperbody_color.tga
new file mode 100644
index 0000000000..85fcc41142
--- /dev/null
+++ b/indra/newview/character/upperbody_color.tga
Binary files differ
diff --git a/indra/newview/character/upperbody_highlights_alpha.tga b/indra/newview/character/upperbody_highlights_alpha.tga
new file mode 100644
index 0000000000..2d8102b583
--- /dev/null
+++ b/indra/newview/character/upperbody_highlights_alpha.tga
Binary files differ
diff --git a/indra/newview/character/upperbody_shading_alpha.tga b/indra/newview/character/upperbody_shading_alpha.tga
new file mode 100644
index 0000000000..b420506b3e
--- /dev/null
+++ b/indra/newview/character/upperbody_shading_alpha.tga
Binary files differ
diff --git a/indra/newview/character/upperbodyfreckles_alpha.tga b/indra/newview/character/upperbodyfreckles_alpha.tga
new file mode 100644
index 0000000000..76c7ce8849
--- /dev/null
+++ b/indra/newview/character/upperbodyfreckles_alpha.tga
Binary files differ
diff --git a/indra/newview/da.lproj/language.txt b/indra/newview/da.lproj/language.txt
new file mode 100644
index 0000000000..316d25d903
--- /dev/null
+++ b/indra/newview/da.lproj/language.txt
@@ -0,0 +1 @@
+da \ No newline at end of file
diff --git a/indra/newview/es.lproj/language.txt b/indra/newview/es.lproj/language.txt
new file mode 100644
index 0000000000..6c4381495c
--- /dev/null
+++ b/indra/newview/es.lproj/language.txt
@@ -0,0 +1 @@
+es \ No newline at end of file
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 05bdf64b42..d557df3d92 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 19
+version 20
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
@@ -245,6 +245,7 @@ RenderVBOEnable 1 0
list Intel
RenderAnisotropic 1 0
RenderLightingDetail 1 0
+RenderUseImpostors 0 0
list GeForce2
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 09105b8d88..57d712ede7 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,4 +1,4 @@
-version 19
+version 20
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index fd2496d8ad..15974c0691 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 19
+version 20
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
diff --git a/indra/newview/fr.lproj/language.txt b/indra/newview/fr.lproj/language.txt
new file mode 100644
index 0000000000..717280ac26
--- /dev/null
+++ b/indra/newview/fr.lproj/language.txt
@@ -0,0 +1 @@
+fr \ No newline at end of file
diff --git a/indra/newview/hu.lproj/language.txt b/indra/newview/hu.lproj/language.txt
new file mode 100644
index 0000000000..6c604cf2a9
--- /dev/null
+++ b/indra/newview/hu.lproj/language.txt
@@ -0,0 +1 @@
+hu \ No newline at end of file
diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi
index d23615de91..008c240ed7 100644
--- a/indra/newview/installers/windows/lang_fr.nsi
+++ b/indra/newview/installers/windows/lang_fr.nsi
Binary files differ
diff --git a/indra/newview/it.lproj/language.txt b/indra/newview/it.lproj/language.txt
new file mode 100644
index 0000000000..c91971434c
--- /dev/null
+++ b/indra/newview/it.lproj/language.txt
@@ -0,0 +1 @@
+it \ No newline at end of file
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 214065f080..a4692dd38b 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -35,6 +35,7 @@
#include "llagent.h"
#include "llagentwearables.h"
+#include "llagentlistener.h"
#include "llanimationstates.h"
#include "llcallingcard.h"
#include "llconsole.h"
@@ -257,6 +258,7 @@ LLAgent::LLAgent() :
mHUDTargetZoom(1.f),
mHUDCurZoom(1.f),
mInitialized(FALSE),
+ mListener(),
mForceMouselook(FALSE),
mDoubleTapRunTimer(),
@@ -385,6 +387,8 @@ LLAgent::LLAgent() :
}
mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
+
+ mListener.reset(new LLAgentListener(*this));
}
// Requires gSavedSettings to be initialized.
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 9f71def63e..7e845cafb7 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -105,6 +105,8 @@ struct LLGroupData
std::string mName;
};
+class LLAgentListener;
+
//------------------------------------------------------------------------
// LLAgent
//------------------------------------------------------------------------
@@ -142,6 +144,8 @@ public:
BOOL mInitialized;
BOOL mFirstLogin;
std::string mMOTD; // Message of the day
+private:
+ boost::shared_ptr<LLAgentListener> mListener;
//--------------------------------------------------------------------
// Session
diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp
new file mode 100644
index 0000000000..0f00078b33
--- /dev/null
+++ b/indra/newview/llagentlistener.cpp
@@ -0,0 +1,78 @@
+/**
+ * @file llagentlistener.cpp
+ * @author Brad Kittenbrink
+ * @date 2009-07-10
+ * @brief Implementation for llagentlistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagentlistener.h"
+
+#include "llagent.h"
+#include "llcommandhandler.h"
+#include "llslurl.h"
+#include "llurldispatcher.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+
+LLAgentListener::LLAgentListener(LLAgent &agent)
+ : LLDispatchListener("LLAgent", "op"),
+ mAgent(agent)
+{
+ add("requestTeleport", &LLAgentListener::requestTeleport);
+ add("requestSit", &LLAgentListener::requestSit);
+ add("requestStand", &LLAgentListener::requestStand);
+}
+
+void LLAgentListener::requestTeleport(LLSD const & event_data) const
+{
+ if(event_data["skip_confirmation"].asBoolean())
+ {
+ LLSD params(LLSD::emptyArray());
+ params.append(event_data["regionname"]);
+ params.append(event_data["x"]);
+ params.append(event_data["y"]);
+ params.append(event_data["z"]);
+ LLCommandDispatcher::dispatch("teleport", params, LLSD(), NULL, true);
+ // *TODO - lookup other LLCommandHandlers for "agent", "classified", "event", "group", "floater", "objectim", "parcel", "login", login_refresh", "balance", "chat"
+ // should we just compose LLCommandHandler and LLDispatchListener?
+ }
+ else
+ {
+ std::string url = LLSLURL::buildSLURL(event_data["regionname"], event_data["x"], event_data["y"], event_data["z"]);
+ LLURLDispatcher::dispatch(url, NULL, false);
+ }
+}
+
+void LLAgentListener::requestSit(LLSD const & event_data) const
+{
+ //mAgent.getAvatarObject()->sitOnObject();
+ // shamelessly ripped from llviewermenu.cpp:handle_sit_or_stand()
+ // *TODO - find a permanent place to share this code properly.
+ LLViewerObject *object = gObjectList.findObject(event_data["obj_uuid"]);
+
+ if (object && object->getPCode() == LL_PCODE_VOLUME)
+ {
+ gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
+ gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+ gMessageSystem->addUUIDFast(_PREHASH_AgentID, mAgent.getID());
+ gMessageSystem->addUUIDFast(_PREHASH_SessionID, mAgent.getSessionID());
+ gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
+ gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
+ gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3(0,0,0));
+
+ object->getRegion()->sendReliableMessage();
+ }
+}
+
+void LLAgentListener::requestStand(LLSD const & event_data) const
+{
+ mAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
+}
+
diff --git a/indra/newview/llagentlistener.h b/indra/newview/llagentlistener.h
new file mode 100644
index 0000000000..6f0b5a54c5
--- /dev/null
+++ b/indra/newview/llagentlistener.h
@@ -0,0 +1,36 @@
+/**
+ * @file llagentlistener.h
+ * @author Brad Kittenbrink
+ * @date 2009-07-09
+ * @brief Event API for subset of LLViewerControl methods
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLAGENTLISTENER_H
+#define LL_LLAGENTLISTENER_H
+
+#include "lleventdispatcher.h"
+
+class LLAgent;
+class LLSD;
+
+class LLAgentListener : public LLDispatchListener
+{
+public:
+ LLAgentListener(LLAgent &agent);
+
+private:
+ void requestTeleport(LLSD const & event_data) const;
+ void requestSit(LLSD const & event_data) const;
+ void requestStand(LLSD const & event_data) const;
+
+private:
+ LLAgent & mAgent;
+};
+
+#endif // LL_LLAGENTLISTENER_H
+
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 76c1d699f6..dd00001cd4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -73,6 +73,7 @@
#include "llurlhistory.h"
#include "llfirstuse.h"
#include "llrender.h"
+#include "llteleporthistory.h"
#include "lllocationhistory.h"
#include "llfasttimerview.h"
#include "llweb.h"
@@ -94,6 +95,10 @@
# include <sys/file.h> // For initMarkerFile support
#endif
+#include "llapr.h"
+#include "apr_dso.h"
+#include <boost/lexical_cast.hpp>
+
#include "llnotify.h"
#include "llviewerkeyboard.h"
#include "lllfsthread.h"
@@ -149,7 +154,6 @@
#include "llfolderview.h"
#include "lltoolbar.h"
#include "llagentpilot.h"
-#include "llsrv.h"
#include "llvovolume.h"
#include "llflexibleobject.h"
#include "llvosurfacepatch.h"
@@ -186,7 +190,10 @@
//----------------------------------------------------------------------------
// llviewernetwork.h
#include "llviewernetwork.h"
+// define a self-registering event API object
+#include "llappviewerlistener.h"
+static LLAppViewerListener sAppViewerListener("LLAppViewer", NULL);
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
//
@@ -212,9 +219,6 @@ BOOL gAllowTapTapHoldRun = TRUE;
BOOL gShowObjectUpdates = FALSE;
BOOL gUseQuickTime = TRUE;
-BOOL gAcceptTOS = FALSE;
-BOOL gAcceptCriticalMessage = FALSE;
-
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
LLSD gDebugInfo;
@@ -560,9 +564,9 @@ LLAppViewer::LLAppViewer() :
mYieldTime(-1),
mMainloopTimeout(NULL),
mAgentRegionLastAlive(false),
- mFastTimerLogThread(NULL),
mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
- mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE))
+ mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
+ mFastTimerLogThread(NULL)
{
if(NULL != sInstance)
{
@@ -863,6 +867,11 @@ bool LLAppViewer::init()
LLViewerJoystick::getInstance()->init(false);
+ if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
+ {
+ loadEventHostModule(gSavedSettings.getS32("QAModeEventHostPort"));
+ }
+
return true;
}
@@ -1156,6 +1165,20 @@ bool LLAppViewer::mainLoop()
bool LLAppViewer::cleanup()
{
+ // *TODO - generalize this and move DSO wrangling to a helper class -brad
+ std::set<struct apr_dso_handle_t *>::const_iterator i;
+ for(i = mPlugins.begin(); i != mPlugins.end(); ++i)
+ {
+ int (*ll_plugin_stop_func)(void) = NULL;
+ apr_status_t rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_stop_func, *i, "ll_plugin_stop");
+ ll_plugin_stop_func();
+
+ // *NOTE - disabled unloading as partial solution to DEV-35406 crash on shutdown
+ //rv = apr_dso_unload(*i);
+ (void)rv;
+ }
+ mPlugins.clear();
+
//----------------------------------------------
//this test code will be removed after the test
//test manual call stack tracer
@@ -3654,6 +3677,17 @@ void LLAppViewer::idleShutdown()
{
return;
}
+
+ // ProductEngine: Try moving this code to where we shut down sTextureCache in cleanup()
+ // *TODO: ugly
+ static bool saved_teleport_history = false;
+ if (!saved_teleport_history)
+ {
+ saved_teleport_history = true;
+ LLTeleportHistory::getInstance()->dump();
+ LLLocationHistory::getInstance()->save(); // *TODO: find a better place for doing this
+ return;
+ }
static bool saved_snapshot = false;
if (!saved_snapshot)
@@ -3952,7 +3986,7 @@ void LLAppViewer::forceErrorBadMemoryAccess()
return;
}
-void LLAppViewer::forceErrorInifiniteLoop()
+void LLAppViewer::forceErrorInfiniteLoop()
{
while(true)
{
@@ -4073,3 +4107,164 @@ void LLAppViewer::handleLoginComplete()
writeDebugInfo();
}
+
+// *TODO - generalize this and move DSO wrangling to a helper class -brad
+void LLAppViewer::loadEventHostModule(S32 listen_port)
+{
+ std::string dso_name =
+#if LL_WINDOWS
+ "lleventhost.dll";
+#elif LL_DARWIN
+ "liblleventhost.dylib";
+#else
+ "liblleventhost.so";
+#endif
+
+ std::string dso_path = gDirUtilp->findFile(dso_name,
+ gDirUtilp->getAppRODataDir(),
+ gDirUtilp->getExecutableDir());
+
+ if(dso_path == "")
+ {
+ llwarns << "QAModeEventHost requested but module \"" << dso_name << "\" not found!" << llendl;
+ return;
+ }
+
+ apr_dso_handle_t * eventhost_dso_handle = NULL;
+ apr_pool_t * eventhost_dso_memory_pool = NULL;
+
+ //attempt to load the shared library
+ apr_pool_create(&eventhost_dso_memory_pool, NULL);
+ apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
+ dso_path.c_str(),
+ eventhost_dso_memory_pool);
+ ll_apr_assert_status(rv);
+ llassert_always(eventhost_dso_handle != NULL);
+
+ int (*ll_plugin_start_func)(LLSD const &) = NULL;
+ rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_start_func, eventhost_dso_handle, "ll_plugin_start");
+
+ ll_apr_assert_status(rv);
+ llassert_always(ll_plugin_start_func != NULL);
+
+ LLSD args;
+ args["listen_port"] = listen_port;
+
+ int status = ll_plugin_start_func(args);
+
+ if(status != 0)
+ {
+ llwarns << "problem loading eventhost plugin, status: " << status << llendl;
+ }
+
+ mPlugins.insert(eventhost_dso_handle);
+}
+
+void LLAppViewer::launchUpdater()
+{
+ LLSD query_map = LLSD::emptyMap();
+ // *TODO place os string in a global constant
+#if LL_WINDOWS
+ query_map["os"] = "win";
+#elif LL_DARWIN
+ query_map["os"] = "mac";
+#elif LL_LINUX
+ query_map["os"] = "lnx";
+#elif LL_SOLARIS
+ query_map["os"] = "sol";
+#endif
+ // *TODO change userserver to be grid on both viewer and sim, since
+ // userserver no longer exists.
+ query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel();
+ query_map["channel"] = gSavedSettings.getString("VersionChannelName");
+ // *TODO constantize this guy
+ // *NOTE: This URL is also used in win_setup/lldownloader.cpp
+ LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
+
+ if(LLAppViewer::sUpdaterInfo)
+ {
+ delete LLAppViewer::sUpdaterInfo;
+ }
+ LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ;
+
+#if LL_WINDOWS
+ LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename();
+ if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty())
+ {
+ delete LLAppViewer::sUpdaterInfo ;
+ LLAppViewer::sUpdaterInfo = NULL ;
+
+ // We're hosed, bail
+ LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL;
+ return;
+ }
+
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe";
+
+ std::string updater_source = gDirUtilp->getAppRODataDir();
+ updater_source += gDirUtilp->getDirDelimiter();
+ updater_source += "updater.exe";
+
+ LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source
+ << " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath
+ << LL_ENDL;
+
+
+ if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE))
+ {
+ delete LLAppViewer::sUpdaterInfo ;
+ LLAppViewer::sUpdaterInfo = NULL ;
+
+ LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
+
+ return;
+ }
+
+ // if a sim name was passed in via command line parameter (typically through a SLURL)
+ if ( LLURLSimString::sInstance.mSimString.length() )
+ {
+ // record the location to start at next time
+ gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
+ };
+
+ LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\"";
+
+ LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
+
+ //Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
+ LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
+
+ // *NOTE:Mani The updater is spawned as the last thing before the WinMain exit.
+ // see LLAppViewerWin32.cpp
+
+#elif LL_DARWIN
+ // if a sim name was passed in via command line parameter (typically through a SLURL)
+ if ( LLURLSimString::sInstance.mSimString.length() )
+ {
+ // record the location to start at next time
+ gSavedSettings.setString( "NextLoginLocation", LLURLSimString::sInstance.mSimString );
+ };
+
+ LLAppViewer::sUpdaterInfo->mUpdateExePath = "'";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \"";
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle();
+ LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &";
+
+ LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
+
+ // Run the auto-updater.
+ system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
+
+#elif LL_LINUX || LL_SOLARIS
+ OSMessageBox("Automatic updating is not yet implemented for Linux.\n"
+ "Please download the latest version from www.secondlife.com.",
+ LLStringUtil::null, OSMB_OK);
+#endif
+
+ // *REMOVE:Mani - Saving for reference...
+ // LLAppViewer::instance()->forceQuit();
+}
+
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 646b677264..f95d7cb412 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -47,6 +47,8 @@ class LLVFS;
class LLWatchdogTimeout;
class LLWorkerThread;
+struct apr_dso_handle_t;
+
class LLAppViewer : public LLApp
{
@@ -124,7 +126,7 @@ public:
virtual void forceErrorLLError();
virtual void forceErrorBreakpoint();
virtual void forceErrorBadMemoryAccess();
- virtual void forceErrorInifiniteLoop();
+ virtual void forceErrorInfiniteLoop();
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
@@ -210,6 +212,8 @@ private:
void sendLogoutRequest();
void disconnectViewer();
+ void loadEventHostModule(S32 listen_port);
+
// *FIX: the app viewer class should be some sort of singleton, no?
// Perhaps its child class is the singleton and this should be an abstract base.
static LLAppViewer* sInstance;
@@ -255,6 +259,8 @@ private:
LLAllocator mAlloc;
+ std::set<struct apr_dso_handle_t*> mPlugins;
+
public:
//some information for updater
typedef struct
@@ -263,6 +269,8 @@ public:
std::ostringstream mParams;
}LLUpdaterInfo ;
static LLUpdaterInfo *sUpdaterInfo ;
+
+ void launchUpdater();
};
// consts from viewer.h
@@ -278,10 +286,6 @@ extern LLSD gDebugInfo;
extern BOOL gAllowTapTapHoldRun;
extern BOOL gShowObjectUpdates;
-extern BOOL gAcceptTOS;
-extern BOOL gAcceptCriticalMessage;
-
-
typedef enum
{
LAST_EXEC_NORMAL = 0,
diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp
new file mode 100644
index 0000000000..a3af251a3c
--- /dev/null
+++ b/indra/newview/llappviewerlistener.cpp
@@ -0,0 +1,37 @@
+/**
+ * @file llappviewerlistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-06-23
+ * @brief Implementation for llappviewerlistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llappviewerlistener.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llappviewer.h"
+
+LLAppViewerListener::LLAppViewerListener(const std::string& pumpname, LLAppViewer* llappviewer):
+ LLDispatchListener(pumpname, "op"),
+ mAppViewer(llappviewer)
+{
+ // add() every method we want to be able to invoke via this event API.
+ add("requestQuit", &LLAppViewerListener::requestQuit);
+}
+
+void LLAppViewerListener::requestQuit(const LLSD& event)
+{
+ if(mAppViewer == NULL)
+ {
+ mAppViewer = LLAppViewer::instance();
+ }
+ mAppViewer->requestQuit();
+}
diff --git a/indra/newview/llappviewerlistener.h b/indra/newview/llappviewerlistener.h
new file mode 100644
index 0000000000..d702f605ef
--- /dev/null
+++ b/indra/newview/llappviewerlistener.h
@@ -0,0 +1,34 @@
+/**
+ * @file llappviewerlistener.h
+ * @author Nat Goodspeed
+ * @date 2009-06-18
+ * @brief Wrap subset of LLAppViewer API in event API
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLAPPVIEWERLISTENER_H)
+#define LL_LLAPPVIEWERLISTENER_H
+
+#include "lleventdispatcher.h"
+
+class LLAppViewer;
+class LLSD;
+
+/// Listen on an LLEventPump with specified name for LLAppViewer request events.
+class LLAppViewerListener: public LLDispatchListener
+{
+public:
+ /// Specify the pump name on which to listen, and bind the LLAppViewer
+ /// instance to use (e.g. LLAppViewer::instance()).
+ LLAppViewerListener(const std::string& pumpname, LLAppViewer* llappviewer);
+
+private:
+ void requestQuit(const LLSD& event);
+
+ LLAppViewer* mAppViewer;
+};
+
+#endif /* ! defined(LL_LLAPPVIEWERLISTENER_H) */
diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h
index 0928916a57..bc841fc3a7 100644
--- a/indra/newview/llappviewermacosx.h
+++ b/indra/newview/llappviewermacosx.h
@@ -55,7 +55,6 @@ protected:
virtual void handleSyncCrashTrace();
std::string generateSerialNumber();
- virtual bool initLogging();
virtual bool initParseCommandLine(LLCommandLineParser& clp);
};
diff --git a/indra/newview/llcapabilitylistener.cpp b/indra/newview/llcapabilitylistener.cpp
index 4134e9e0a4..785a647fa2 100644
--- a/indra/newview/llcapabilitylistener.cpp
+++ b/indra/newview/llcapabilitylistener.cpp
@@ -91,6 +91,7 @@ bool LLCapabilityListener::capListener(const LLSD& request)
// This capability is supported by the region to which we're talking.
LLHTTPClient::post(url, payload,
new LLSDMessage::EventResponder(LLEventPumps::instance(),
+ request,
mProvider.getDescription(),
cap, reply, error),
LLSD(), // headers
diff --git a/indra/newview/llclassifiedinfo.cpp b/indra/newview/llclassifiedinfo.cpp
index 5cf1579d0e..5fcafbeca6 100644
--- a/indra/newview/llclassifiedinfo.cpp
+++ b/indra/newview/llclassifiedinfo.cpp
@@ -38,35 +38,19 @@
LLClassifiedInfo::cat_map LLClassifiedInfo::sCategories;
// static
-void LLClassifiedInfo::loadCategories(LLUserAuth::options_t classified_options)
+void LLClassifiedInfo::loadCategories(const LLSD& options)
{
- LLUserAuth::options_t::iterator resp_it;
- for (resp_it = classified_options.begin();
- resp_it != classified_options.end();
- ++resp_it)
+ for(LLSD::array_const_iterator resp_it = options.beginArray(),
+ end = options.endArray(); resp_it != end; ++resp_it)
{
- const LLUserAuth::response_t& response = *resp_it;
-
- LLUserAuth::response_t::const_iterator option_it;
-
- S32 cat_id = 0;
- option_it = response.find("category_id");
- if (option_it != response.end())
+ LLSD name = (*resp_it)["category_name"];
+ if(name.isDefined())
{
- cat_id = atoi(option_it->second.c_str());
+ LLSD id = (*resp_it)["category_id"];
+ if(id.isDefined())
+ {
+ LLClassifiedInfo::sCategories[id.asInteger()] = name.asString();
+ }
}
- else
- {
- continue;
- }
-
- // Add the category id/name pair
- option_it = response.find("category_name");
- if (option_it != response.end())
- {
- LLClassifiedInfo::sCategories[cat_id] = option_it->second;
- }
-
}
-
}
diff --git a/indra/newview/llclassifiedinfo.h b/indra/newview/llclassifiedinfo.h
index cc5a6bf28f..37134c7e5b 100644
--- a/indra/newview/llclassifiedinfo.h
+++ b/indra/newview/llclassifiedinfo.h
@@ -37,7 +37,6 @@
#include "v3dmath.h"
#include "lluuid.h"
-#include "lluserauth.h"
class LLMessageSystem;
@@ -46,7 +45,7 @@ class LLClassifiedInfo
public:
LLClassifiedInfo() {}
- static void loadCategories(LLUserAuth::options_t event_options);
+ static void loadCategories(const LLSD& options);
typedef std::map<U32, std::string> cat_map;
static cat_map sCategories;
diff --git a/indra/newview/lldrawpoolsky.h b/indra/newview/lldrawpoolsky.h
index f35b114730..8595d73aee 100644
--- a/indra/newview/lldrawpoolsky.h
+++ b/indra/newview/lldrawpoolsky.h
@@ -36,14 +36,12 @@
#include "lldrawpool.h"
class LLSkyTex;
-class LLHeavenBody;
class LLGLSLShader;
class LLDrawPoolSky : public LLFacePool
{
private:
LLSkyTex *mSkyTex;
- LLHeavenBody *mHB[2]; // Sun and Moon
LLGLSLShader *mShader;
public:
@@ -69,8 +67,6 @@ public:
/*virtual*/ void renderForSelect();
/*virtual*/ void endRenderPass(S32 pass);
void setSkyTex(LLSkyTex* const st) { mSkyTex = st; }
- void setSun(LLHeavenBody* sun_flag) { mHB[0] = sun_flag; }
- void setMoon(LLHeavenBody* moon) { mHB[1] = moon; }
void renderSkyCubeFace(U8 side);
void renderHeavenlyBody(U8 hb, LLFace* face);
diff --git a/indra/newview/lleventinfo.cpp b/indra/newview/lleventinfo.cpp
index d4175b6c84..9be45d18fb 100644
--- a/indra/newview/lleventinfo.cpp
+++ b/indra/newview/lleventinfo.cpp
@@ -87,35 +87,19 @@ void LLEventInfo::unpack(LLMessageSystem *msg)
}
// static
-void LLEventInfo::loadCategories(LLUserAuth::options_t event_options)
+void LLEventInfo::loadCategories(const LLSD& options)
{
- LLUserAuth::options_t::iterator resp_it;
- for (resp_it = event_options.begin();
- resp_it != event_options.end();
- ++resp_it)
+ for(LLSD::array_const_iterator resp_it = options.beginArray(),
+ end = options.endArray(); resp_it != end; ++resp_it)
{
- const LLUserAuth::response_t& response = *resp_it;
-
- LLUserAuth::response_t::const_iterator option_it;
-
- S32 cat_id = 0;
- option_it = response.find("category_id");
- if (option_it != response.end())
+ LLSD name = (*resp_it)["category_name"];
+ if(name.isDefined())
{
- cat_id = atoi(option_it->second.c_str());
+ LLSD id = (*resp_it)["category_id"];
+ if(id.isDefined())
+ {
+ LLEventInfo::sCategories[id.asInteger()] = name.asString();
+ }
}
- else
- {
- continue;
- }
-
- // Add the category id/name pair
- option_it = response.find("category_name");
- if (option_it != response.end())
- {
- LLEventInfo::sCategories[cat_id] = option_it->second;
- }
-
}
-
}
diff --git a/indra/newview/lleventinfo.h b/indra/newview/lleventinfo.h
index 880517a9f4..493c659983 100644
--- a/indra/newview/lleventinfo.h
+++ b/indra/newview/lleventinfo.h
@@ -37,7 +37,6 @@
#include "v3dmath.h"
#include "lluuid.h"
-#include "lluserauth.h"
class LLMessageSystem;
@@ -48,7 +47,7 @@ public:
void unpack(LLMessageSystem *msg);
- static void loadCategories(LLUserAuth::options_t event_options);
+ static void loadCategories(const LLSD& options);
public:
std::string mName;
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index 2c52cf9565..80d4d21166 100644
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
@@ -95,18 +95,16 @@ void LLEventNotifier::update()
}
}
-void LLEventNotifier::load(const LLUserAuth::options_t& event_options)
+void LLEventNotifier::load(const LLSD& event_options)
{
- LLUserAuth::options_t::const_iterator resp_it;
- for (resp_it = event_options.begin();
- resp_it != event_options.end();
- ++resp_it)
+ for(LLSD::array_const_iterator resp_it = event_options.beginArray(),
+ end = event_options.endArray(); resp_it != end; ++resp_it)
{
- const LLUserAuth::response_t& response = *resp_it;
+ LLSD response = *resp_it;
LLEventNotification *new_enp = new LLEventNotification();
- if (!new_enp->load(response))
+ if(!new_enp->load(response))
{
delete new_enp;
continue;
@@ -210,49 +208,46 @@ bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& r
return false;
}
-BOOL LLEventNotification::load(const LLUserAuth::response_t &response)
+BOOL LLEventNotification::load(const LLSD& response)
{
-
- LLUserAuth::response_t::const_iterator option_it;
BOOL event_ok = TRUE;
- option_it = response.find("event_id");
- if (option_it != response.end())
+ LLSD option = response.get("event_id");
+ if (option.isDefined())
{
- mEventID = atoi(option_it->second.c_str());
+ mEventID = option.asInteger();
}
else
{
event_ok = FALSE;
}
- option_it = response.find("event_name");
- if (option_it != response.end())
+ option = response.get("event_name");
+ if (option.isDefined())
{
- llinfos << "Event: " << option_it->second << llendl;
- mEventName = option_it->second;
+ llinfos << "Event: " << option.asString() << llendl;
+ mEventName = option.asString();
}
else
{
event_ok = FALSE;
}
-
- option_it = response.find("event_date");
- if (option_it != response.end())
+ option = response.get("event_date");
+ if (option.isDefined())
{
- llinfos << "EventDate: " << option_it->second << llendl;
- mEventDateStr = option_it->second;
+ llinfos << "EventDate: " << option.asString() << llendl;
+ mEventDateStr = option.asString();
}
else
{
event_ok = FALSE;
}
- option_it = response.find("event_date_ut");
- if (option_it != response.end())
+ option = response.get("event_date_ut");
+ if (option.isDefined())
{
- llinfos << "EventDate: " << option_it->second << llendl;
- mEventDate = strtoul(option_it->second.c_str(), NULL, 10);
+ llinfos << "EventDate: " << option.asString() << llendl;
+ mEventDate = strtoul(option.asString().c_str(), NULL, 10);
}
else
{
@@ -264,44 +259,44 @@ BOOL LLEventNotification::load(const LLUserAuth::response_t &response)
S32 x_region = 0;
S32 y_region = 0;
- option_it = response.find("grid_x");
- if (option_it != response.end())
+ option = response.get("grid_x");
+ if (option.isDefined())
{
- llinfos << "GridX: " << option_it->second << llendl;
- grid_x= atoi(option_it->second.c_str());
+ llinfos << "GridX: " << option.asInteger() << llendl;
+ grid_x= option.asInteger();
}
else
{
event_ok = FALSE;
}
- option_it = response.find("grid_y");
- if (option_it != response.end())
+ option = response.get("grid_y");
+ if (option.isDefined())
{
- llinfos << "GridY: " << option_it->second << llendl;
- grid_y = atoi(option_it->second.c_str());
+ llinfos << "GridY: " << option.asInteger() << llendl;
+ grid_y = option.asInteger();
}
else
{
event_ok = FALSE;
}
- option_it = response.find("x_region");
- if (option_it != response.end())
+ option = response.get("x_region");
+ if (option.isDefined())
{
- llinfos << "RegionX: " << option_it->second << llendl;
- x_region = atoi(option_it->second.c_str());
+ llinfos << "RegionX: " << option.asInteger() << llendl;
+ x_region = option.asInteger();
}
else
{
event_ok = FALSE;
}
- option_it = response.find("y_region");
- if (option_it != response.end())
+ option = response.get("y_region");
+ if (option.isDefined())
{
- llinfos << "RegionY: " << option_it->second << llendl;
- y_region = atoi(option_it->second.c_str());
+ llinfos << "RegionY: " << option.asInteger() << llendl;
+ y_region = option.asInteger();
}
else
{
diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h
index feb734948c..6fdde87646 100644
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
@@ -34,7 +34,6 @@
#define LL_LLEVENTNOTIFIER_H
#include "llframetimer.h"
-#include "lluserauth.h"
#include "v3dmath.h"
class LLEventInfo;
@@ -49,7 +48,7 @@ public:
void update(); // Notify the user of the event if it's coming up
- void load(const LLUserAuth::options_t& event_options); // In the format that it comes in from LLUserAuth
+ void load(const LLSD& event_options); // In the format that it comes in from login
void add(LLEventInfo &event_info); // Add a new notification for an event
void remove(U32 event_id);
@@ -69,7 +68,7 @@ public:
LLEventNotification();
virtual ~LLEventNotification();
- BOOL load(const LLUserAuth::response_t &en); // In the format it comes in from LLUserAuth
+ BOOL load(const LLSD& en); // In the format it comes in from login
BOOL load(const LLEventInfo &event_info); // From existing event_info on the viewer.
//void setEventID(const U32 event_id);
//void setEventName(std::string &event_name);
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 8ceb41c27a..b406300a38 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -989,8 +989,12 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)
std::string label = iter->first;
F64 time = iter->second["Time"].asReal();
-
- total_time += time;
+
+ // Skip the total figure
+ if(label.compare("Total") != 0)
+ {
+ total_time += time;
+ }
if (time > 0.0)
{
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 2a8365b3f0..fb724f30e0 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -44,6 +44,7 @@
#include "llgl.h"
#include "llsecondlifeurls.h"
+#include "llappviewer.h"
#include "llviewercontrol.h"
#include "llworld.h"
#include "lldrawpoolterrain.h"
@@ -58,11 +59,6 @@
#include "lldxhardware.h"
#endif
-//
-// externs
-//
-extern LLMemoryInfo gSysMemory;
-extern LLCPUInfo gSysCPU;
#if LL_DARWIN
const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt";
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 56c5eaa70e..30a5f9f36a 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -1,267 +1,266 @@
-/**
- * @file llfloaterabout.cpp
- * @author James Cook
- * @brief The about box from Help->About
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloaterabout.h"
-
-#include "llsys.h"
-#include "llgl.h"
-#include "llui.h" // for tr()
-#include "v3dmath.h"
-
-#include "llcurl.h"
-#include "llimagej2c.h"
-#include "llaudioengine.h"
-
-#include "llviewertexteditor.h"
-#include "llviewercontrol.h"
-#include "llagent.h"
-#include "llviewerstats.h"
-#include "llviewerregion.h"
-#include "llversionviewer.h"
-#include "llviewerbuild.h"
-#include "lluictrlfactory.h"
-#include "lluri.h"
-#include "llweb.h"
-#include "llsecondlifeurls.h"
-#include "lltrans.h"
-#include "llappviewer.h"
-#include "llglheaders.h"
-#include "llwindow.h"
-
-#include "llbutton.h"
-
-#if LL_WINDOWS
-#include "lldxhardware.h"
-#endif
-
-extern LLCPUInfo gSysCPU;
-extern LLMemoryInfo gSysMemory;
-extern U32 gPacketsIn;
-
-static std::string get_viewer_release_notes_url();
-
-
-///----------------------------------------------------------------------------
-/// Class LLFloaterAbout
-///----------------------------------------------------------------------------
-
-// Default constructor
-LLFloaterAbout::LLFloaterAbout(const LLSD& key)
-: LLFloater(key)
-{
- //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml");
-
-}
-
-// Destroys the object
-LLFloaterAbout::~LLFloaterAbout()
-{
-}
-
-BOOL LLFloaterAbout::postBuild()
-{
- center();
- LLViewerTextEditor *support_widget =
- getChild<LLViewerTextEditor>("support_editor", true);
-
- LLViewerTextEditor *credits_widget =
- getChild<LLViewerTextEditor>("credits_editor", true);
-
- // For some reason, adding style doesn't work unless this is true.
- support_widget->setParseHTML(TRUE);
-
- // Text styles for release notes hyperlinks
- LLStyle::Params link_style_params;
- link_style_params.color.control = "HTMLLinkColor";
- link_style_params.link_href = get_viewer_release_notes_url();
-
- // Version string
- std::string version = LLTrans::getString("APP_NAME")
- + llformat(" %d.%d.%d (%d) %s %s (%s)\n",
- LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD,
- __DATE__, __TIME__,
- gSavedSettings.getString("VersionChannelName").c_str());
- support_widget->appendColoredText(version, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
- support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, link_style_params);
-
- std::string support;
- support.append("\n\n");
-
-#if LL_MSVC
- support.append(llformat("Built with MSVC version %d\n\n", _MSC_VER));
-#endif
-
-#if LL_GNUC
- support.append(llformat("Built with GCC version %d\n\n", GCC_VERSION));
-#endif
-
- // Position
- LLViewerRegion* region = gAgent.getRegion();
- if (region)
- {
- LLStyle::Params server_link_style_params;
- server_link_style_params.color.control = "HTMLLinkColor";
- server_link_style_params.link_href = region->getCapability("ServerReleaseNotes");
-
- const LLVector3d &pos = gAgent.getPositionGlobal();
- LLUIString pos_text = getString("you_are_at");
- pos_text.setArg("[POSITION]",
- llformat("%.1f, %.1f, %.1f ", pos.mdV[VX], pos.mdV[VY], pos.mdV[VZ]));
- support.append(pos_text);
-
- LLUIString region_text = getString ("in_region") + " ";
- region_text.setArg("[REGION]", llformat ("%s", gAgent.getRegion()->getName().c_str()));
- support.append(region_text);
-
- std::string buffer;
- buffer = gAgent.getRegion()->getHost().getHostName();
- support.append(buffer);
- support.append(" (");
- buffer = gAgent.getRegion()->getHost().getString();
- support.append(buffer);
- support.append(")\n");
- support.append(gLastVersionChannel);
- support.append("\n");
-
- support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
- support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style_params);
-
- support = "\n\n";
- }
-
- // *NOTE: Do not translate text like GPU, Graphics Card, etc -
- // Most PC users that know what these mean will be used to the english versions,
- // and this info sometimes gets sent to support
-
- // CPU
- support.append(getString("CPU") + " ");
- support.append( gSysCPU.getCPUString() );
- support.append("\n");
-
- U32 memory = gSysMemory.getPhysicalMemoryKB() / 1024;
- // Moved hack adjustment to Windows memory size into llsys.cpp
-
- LLStringUtil::format_map_t args;
- args["[MEM]"] = llformat ("%u", memory);
- support.append(getString("Memory", args) + "\n");
-
- support.append(getString("OSVersion") + " ");
- support.append( LLAppViewer::instance()->getOSInfo().getOSString() );
- support.append("\n");
-
- support.append(getString("GraphicsCardVendor") + " ");
- support.append( (const char*) glGetString(GL_VENDOR) );
- support.append("\n");
-
- support.append(getString("GraphicsCard") + " ");
- support.append( (const char*) glGetString(GL_RENDERER) );
- support.append("\n");
-
-#if LL_WINDOWS
- getWindow()->incBusyCount();
- getWindow()->setCursor(UI_CURSOR_ARROW);
- support.append("Windows Graphics Driver Version: ");
- LLSD driver_info = gDXHardware.getDisplayInfo();
- if (driver_info.has("DriverVersion"))
- {
- support.append(driver_info["DriverVersion"]);
- }
- support.append("\n");
- getWindow()->decBusyCount();
- getWindow()->setCursor(UI_CURSOR_ARROW);
-#endif
-
- support.append(getString("OpenGLVersion") + " ");
- support.append( (const char*) glGetString(GL_VERSION) );
- support.append("\n");
-
- support.append("\n");
-
- support.append(getString("LibCurlVersion") + " ");
- support.append( LLCurl::getVersionString() );
- support.append("\n");
-
- support.append(getString("J2CDecoderVersion") + " ");
- support.append( LLImageJ2C::getEngineInfo() );
- support.append("\n");
-
- support.append(getString("AudioDriverVersion") + " ");
- bool want_fullname = true;
- support.append( gAudiop ? gAudiop->getDriverName(want_fullname) : getString("none") );
- support.append("\n");
-
- // TODO: Implement media plugin version query
-
- support.append(getString("LLQtWebkitVersion") + " ");
- support.append("\n");
-
- if (gPacketsIn > 0)
- {
- args["[LOST]"] = llformat ("%.0f", LLViewerStats::getInstance()->mPacketsLostStat.getCurrent());
- args["[IN]"] = llformat ("%.0f", F32(gPacketsIn));
- args["[PCT]"] = llformat ("%.1f", 100.f*LLViewerStats::getInstance()->mPacketsLostStat.getCurrent() / F32(gPacketsIn) );
- support.append(getString ("PacketsLost", args) + "\n");
- }
-
- support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
-
- // Fix views
- support_widget->setCursorPos(0);
- support_widget->setEnabled(FALSE);
-
- credits_widget->setCursorPos(0);
- credits_widget->setEnabled(FALSE);
-
- return TRUE;
-}
-
-
- static std::string get_viewer_release_notes_url()
- {
- std::ostringstream version;
- version << LL_VERSION_MAJOR << "."
- << LL_VERSION_MINOR << "."
- << LL_VERSION_PATCH << "."
- << LL_VERSION_BUILD;
-
- LLSD query;
- query["channel"] = gSavedSettings.getString("VersionChannelName");
- query["version"] = version.str();
-
- std::ostringstream url;
- url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query);
-
- return url.str();
- }
+/**
+ * @file llfloaterabout.cpp
+ * @author James Cook
+ * @brief The about box from Help->About
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterabout.h"
+
+#include "llsys.h"
+#include "llgl.h"
+#include "llui.h" // for tr()
+#include "v3dmath.h"
+
+#include "llcurl.h"
+#include "llimagej2c.h"
+#include "llaudioengine.h"
+
+#include "llviewertexteditor.h"
+#include "llviewercontrol.h"
+#include "llagent.h"
+#include "llviewerstats.h"
+#include "llviewerregion.h"
+#include "llversionviewer.h"
+#include "llviewerbuild.h"
+#include "lluictrlfactory.h"
+#include "lluri.h"
+#include "llweb.h"
+#include "llsecondlifeurls.h"
+#include "lltrans.h"
+#include "llappviewer.h"
+#include "llglheaders.h"
+#include "llwindow.h"
+
+#include "llbutton.h"
+
+#if LL_WINDOWS
+#include "lldxhardware.h"
+#endif
+
+extern LLMemoryInfo gSysMemory;
+extern U32 gPacketsIn;
+
+static std::string get_viewer_release_notes_url();
+
+
+///----------------------------------------------------------------------------
+/// Class LLFloaterAbout
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLFloaterAbout::LLFloaterAbout(const LLSD& key)
+: LLFloater(key)
+{
+ //LLUICtrlFactory::getInstance()->buildFloater(this, "floater_about.xml");
+
+}
+
+// Destroys the object
+LLFloaterAbout::~LLFloaterAbout()
+{
+}
+
+BOOL LLFloaterAbout::postBuild()
+{
+ center();
+ LLViewerTextEditor *support_widget =
+ getChild<LLViewerTextEditor>("support_editor", true);
+
+ LLViewerTextEditor *credits_widget =
+ getChild<LLViewerTextEditor>("credits_editor", true);
+
+ // For some reason, adding style doesn't work unless this is true.
+ support_widget->setParseHTML(TRUE);
+
+ // Text styles for release notes hyperlinks
+ LLStyle::Params link_style_params;
+ link_style_params.color.control = "HTMLLinkColor";
+ link_style_params.link_href = get_viewer_release_notes_url();
+
+ // Version string
+ std::string version = LLTrans::getString("APP_NAME")
+ + llformat(" %d.%d.%d (%d) %s %s (%s)\n",
+ LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD,
+ __DATE__, __TIME__,
+ gSavedSettings.getString("VersionChannelName").c_str());
+ support_widget->appendColoredText(version, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
+ support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, link_style_params);
+
+ std::string support;
+ support.append("\n\n");
+
+#if LL_MSVC
+ support.append(llformat("Built with MSVC version %d\n\n", _MSC_VER));
+#endif
+
+#if LL_GNUC
+ support.append(llformat("Built with GCC version %d\n\n", GCC_VERSION));
+#endif
+
+ // Position
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ LLStyle::Params server_link_style_params;
+ server_link_style_params.color.control = "HTMLLinkColor";
+ server_link_style_params.link_href = region->getCapability("ServerReleaseNotes");
+
+ const LLVector3d &pos = gAgent.getPositionGlobal();
+ LLUIString pos_text = getString("you_are_at");
+ pos_text.setArg("[POSITION]",
+ llformat("%.1f, %.1f, %.1f ", pos.mdV[VX], pos.mdV[VY], pos.mdV[VZ]));
+ support.append(pos_text);
+
+ LLUIString region_text = getString ("in_region") + " ";
+ region_text.setArg("[REGION]", llformat ("%s", gAgent.getRegion()->getName().c_str()));
+ support.append(region_text);
+
+ std::string buffer;
+ buffer = gAgent.getRegion()->getHost().getHostName();
+ support.append(buffer);
+ support.append(" (");
+ buffer = gAgent.getRegion()->getHost().getString();
+ support.append(buffer);
+ support.append(")\n");
+ support.append(gLastVersionChannel);
+ support.append("\n");
+
+ support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
+ support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style_params);
+
+ support = "\n\n";
+ }
+
+ // *NOTE: Do not translate text like GPU, Graphics Card, etc -
+ // Most PC users that know what these mean will be used to the english versions,
+ // and this info sometimes gets sent to support
+
+ // CPU
+ support.append(getString("CPU") + " ");
+ support.append( gSysCPU.getCPUString() );
+ support.append("\n");
+
+ U32 memory = gSysMemory.getPhysicalMemoryKB() / 1024;
+ // Moved hack adjustment to Windows memory size into llsys.cpp
+
+ LLStringUtil::format_map_t args;
+ args["[MEM]"] = llformat ("%u", memory);
+ support.append(getString("Memory", args) + "\n");
+
+ support.append(getString("OSVersion") + " ");
+ support.append( LLAppViewer::instance()->getOSInfo().getOSString() );
+ support.append("\n");
+
+ support.append(getString("GraphicsCardVendor") + " ");
+ support.append( (const char*) glGetString(GL_VENDOR) );
+ support.append("\n");
+
+ support.append(getString("GraphicsCard") + " ");
+ support.append( (const char*) glGetString(GL_RENDERER) );
+ support.append("\n");
+
+#if LL_WINDOWS
+ getWindow()->incBusyCount();
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+ support.append("Windows Graphics Driver Version: ");
+ LLSD driver_info = gDXHardware.getDisplayInfo();
+ if (driver_info.has("DriverVersion"))
+ {
+ support.append(driver_info["DriverVersion"]);
+ }
+ support.append("\n");
+ getWindow()->decBusyCount();
+ getWindow()->setCursor(UI_CURSOR_ARROW);
+#endif
+
+ support.append(getString("OpenGLVersion") + " ");
+ support.append( (const char*) glGetString(GL_VERSION) );
+ support.append("\n");
+
+ support.append("\n");
+
+ support.append(getString("LibCurlVersion") + " ");
+ support.append( LLCurl::getVersionString() );
+ support.append("\n");
+
+ support.append(getString("J2CDecoderVersion") + " ");
+ support.append( LLImageJ2C::getEngineInfo() );
+ support.append("\n");
+
+ support.append(getString("AudioDriverVersion") + " ");
+ bool want_fullname = true;
+ support.append( gAudiop ? gAudiop->getDriverName(want_fullname) : getString("none") );
+ support.append("\n");
+
+ // TODO: Implement media plugin version query
+
+ support.append(getString("LLQtWebkitVersion") + " ");
+ support.append("\n");
+
+ if (gPacketsIn > 0)
+ {
+ args["[LOST]"] = llformat ("%.0f", LLViewerStats::getInstance()->mPacketsLostStat.getCurrent());
+ args["[IN]"] = llformat ("%.0f", F32(gPacketsIn));
+ args["[PCT]"] = llformat ("%.1f", 100.f*LLViewerStats::getInstance()->mPacketsLostStat.getCurrent() / F32(gPacketsIn) );
+ support.append(getString ("PacketsLost", args) + "\n");
+ }
+
+ support_widget->appendColoredText(support, FALSE, FALSE, LLUIColorTable::instance().getColor("TextFgReadOnlyColor"));
+
+ // Fix views
+ support_widget->setCursorPos(0);
+ support_widget->setEnabled(FALSE);
+
+ credits_widget->setCursorPos(0);
+ credits_widget->setEnabled(FALSE);
+
+ return TRUE;
+}
+
+
+ static std::string get_viewer_release_notes_url()
+ {
+ std::ostringstream version;
+ version << LL_VERSION_MAJOR << "."
+ << LL_VERSION_MINOR << "."
+ << LL_VERSION_PATCH << "."
+ << LL_VERSION_BUILD;
+
+ LLSD query;
+ query["channel"] = gSavedSettings.getString("VersionChannelName");
+ query["version"] = version.str();
+
+ std::ostringstream url;
+ url << LLTrans::getString("RELEASE_NOTES_BASE_URL") << LLURI::mapToQueryString(query);
+
+ return url.str();
+ }
diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h
index 9242f00c91..9c6660c0dc 100644
--- a/indra/newview/llfloaterfriends.h
+++ b/indra/newview/llfloaterfriends.h
@@ -74,6 +74,9 @@ public:
virtual BOOL postBuild();
+ // *HACK Made public to remove friends from LLAvatarIconCtrl context menu
+ static bool handleRemove(const LLSD& notification, const LLSD& response);
+
private:
enum FRIENDS_COLUMN_ORDER
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index 1060a5e031..d9bc43f3b4 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -35,8 +35,6 @@
#include "llfloatertos.h"
// viewer includes
-#include "llappviewer.h"
-#include "llstartup.h"
#include "llviewerstats.h"
#include "llviewerwindow.h"
@@ -52,11 +50,12 @@
#include "message.h"
-LLFloaterTOS::LLFloaterTOS(const LLSD& message)
-: LLModalDialog( message, 100, 100 ),
- mMessage(message.asString()),
+LLFloaterTOS::LLFloaterTOS(const LLSD& data)
+: LLModalDialog( data["message"].asString(), 100, 100 ),
+ mMessage(data["message"].asString()),
mWebBrowserWindowId( 0 ),
- mLoadCompleteCount( 0 )
+ mLoadCompleteCount( 0 ),
+ mReplyPumpName(data["reply_pump"].asString())
{
}
@@ -193,25 +192,12 @@ void LLFloaterTOS::onContinue( void* userdata )
{
LLFloaterTOS* self = (LLFloaterTOS*) userdata;
llinfos << "User agrees with TOS." << llendl;
- if (self->getInstanceName() == "message_tos")
- {
- gAcceptTOS = TRUE;
- }
- else
- {
- gAcceptCriticalMessage = TRUE;
- }
- // Testing TOS dialog
- #if ! LL_RELEASE_FOR_DOWNLOAD
- if ( LLStartUp::getStartupState() == STATE_LOGIN_WAIT )
+ if(self->mReplyPumpName != "")
{
- LLStartUp::setStartupState( STATE_LOGIN_SHOW );
+ LLEventPumps::instance().obtain(self->mReplyPumpName).post(LLSD(true));
}
- else
- #endif
- LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); // Go back and finish authentication
self->closeFloater(); // destroys this object
}
@@ -220,8 +206,12 @@ void LLFloaterTOS::onCancel( void* userdata )
{
LLFloaterTOS* self = (LLFloaterTOS*) userdata;
llinfos << "User disagrees with TOS." << llendl;
- LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done);
- LLStartUp::setStartupState( STATE_LOGIN_SHOW );
+
+ if(self->mReplyPumpName != "")
+ {
+ LLEventPumps::instance().obtain(self->mReplyPumpName).post(LLSD(false));
+ }
+
self->mLoadCompleteCount = 0; // reset counter for next time we come to TOS
self->closeFloater(); // destroys this object
}
@@ -241,3 +231,4 @@ void LLFloaterTOS::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
}
}
}
+
diff --git a/indra/newview/llfloatertos.h b/indra/newview/llfloatertos.h
index 49f982aa80..1d573e8170 100644
--- a/indra/newview/llfloatertos.h
+++ b/indra/newview/llfloatertos.h
@@ -36,6 +36,7 @@
#include "llmodaldialog.h"
#include "llassetstorage.h"
#include "llmediactrl.h"
+#include <boost/function.hpp>
class LLButton;
class LLRadioGroup;
@@ -48,7 +49,7 @@ class LLFloaterTOS :
public LLViewerMediaObserver
{
public:
- LLFloaterTOS(const LLSD& message);
+ LLFloaterTOS(const LLSD& data);
virtual ~LLFloaterTOS();
BOOL postBuild();
@@ -68,6 +69,7 @@ private:
std::string mMessage;
int mWebBrowserWindowId;
int mLoadCompleteCount;
+ std::string mReplyPumpName;
};
#endif // LL_LLFLOATERTOS_H
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 4cbf88f3da..0d773a7c54 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -40,7 +40,7 @@
#include "llerror.h"
#include "llbutton.h"
#include "llhttpclient.h"
-#include "llsdutil.h"
+#include "llsdutil_math.h"
#include "llstring.h"
#include "lluictrlfactory.h"
diff --git a/indra/newview/llinventoryactions.h b/indra/newview/llinventoryactions.h
new file mode 100644
index 0000000000..79247e3abb
--- /dev/null
+++ b/indra/newview/llinventoryactions.h
@@ -0,0 +1,47 @@
+/**
+ * @file llinventoryactions.h
+ * @brief inventory callback functions
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLINVENTORYACTIONS_H
+#define LL_LLINVENTORYACTIONS_H
+
+#include "lluictrl.h"
+
+class LLPanelInventory;
+class LLInventoryView;
+class LLInventoryPanel;
+
+void init_object_inventory_panel_actions(LLPanelInventory *panel, LLUICtrl::CommitCallbackRegistry::Registrar& registrar);
+void init_inventory_actions(LLInventoryView *floater, LLUICtrl::CommitCallbackRegistry::Registrar& registrar);
+void init_inventory_panel_actions(LLInventoryPanel *panel, LLUICtrl::CommitCallbackRegistry::Registrar& registrar);
+
+#endif // LL_LLINVENTORYACTIONS_H
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index aadda3fbfd..ef2ba5c11b 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1982,63 +1982,56 @@ bool LLInventoryModel::isCategoryComplete(const LLUUID& cat_id) const
}
bool LLInventoryModel::loadSkeleton(
- const LLInventoryModel::options_t& options,
+ const LLSD& options,
const LLUUID& owner_id)
{
lldebugs << "importing inventory skeleton for " << owner_id << llendl;
typedef std::set<LLPointer<LLViewerInventoryCategory>, InventoryIDPtrLess> cat_set_t;
cat_set_t temp_cats;
-
- update_map_t child_counts;
-
- LLUUID id;
- LLAssetType::EType preferred_type;
bool rv = true;
- for(options_t::const_iterator it = options.begin(); it < options.end(); ++it)
- {
- LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(owner_id);
- response_t::const_iterator no_response = (*it).end();
- response_t::const_iterator skel;
- skel = (*it).find("name");
- if(skel == no_response) goto clean_cat;
- cat->rename(std::string((*skel).second));
- skel = (*it).find("folder_id");
- if(skel == no_response) goto clean_cat;
- id.set((*skel).second);
- // if an id is null, it locks the viewer.
- if(id.isNull()) goto clean_cat;
- cat->setUUID(id);
- skel = (*it).find("parent_id");
- if(skel == no_response) goto clean_cat;
- id.set((*skel).second);
- cat->setParent(id);
- skel = (*it).find("type_default");
- if(skel == no_response)
- {
- preferred_type = LLAssetType::AT_NONE;
+
+ for(LLSD::array_const_iterator it = options.beginArray(),
+ end = options.endArray(); it != end; ++it)
+ {
+ LLSD name = (*it)["name"];
+ LLSD folder_id = (*it)["folder_id"];
+ LLSD parent_id = (*it)["parent_id"];
+ LLSD version = (*it)["version"];
+ if(name.isDefined()
+ && folder_id.isDefined()
+ && parent_id.isDefined()
+ && version.isDefined()
+ && folder_id.asUUID().notNull() // if an id is null, it locks the viewer.
+ )
+ {
+ LLPointer<LLViewerInventoryCategory> cat = new LLViewerInventoryCategory(owner_id);
+ cat->rename(name.asString());
+ cat->setUUID(folder_id.asUUID());
+ cat->setParent(parent_id.asUUID());
+
+ LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
+ LLSD type_default = (*it)["type_default"];
+ if(type_default.isDefined())
+ {
+ preferred_type = (LLAssetType::EType)type_default.asInteger();
+ }
+ cat->setPreferredType(preferred_type);
+ cat->setVersion(version.asInteger());
+ temp_cats.insert(cat);
}
else
{
- S32 t = atoi((*skel).second.c_str());
- preferred_type = (LLAssetType::EType)t;
+ llwarns << "Unable to import near " << name.asString() << llendl;
+ rv = false;
}
- cat->setPreferredType(preferred_type);
- skel = (*it).find("version");
- if(skel == no_response) goto clean_cat;
- cat->setVersion(atoi((*skel).second.c_str()));
- temp_cats.insert(cat);
- continue;
- clean_cat:
- llwarns << "Unable to import near " << cat->getName() << llendl;
- rv = false;
- //delete cat; // automatic when cat is reasigned or destroyed
}
S32 cached_category_count = 0;
S32 cached_item_count = 0;
if(!temp_cats.empty())
{
+ update_map_t child_counts;
cat_array_t categories;
item_array_t items;
cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.
@@ -2212,85 +2205,84 @@ bool LLInventoryModel::loadSkeleton(
return rv;
}
-bool LLInventoryModel::loadMeat(
- const LLInventoryModel::options_t& options, const LLUUID& owner_id)
+bool LLInventoryModel::loadMeat(const LLSD& options, const LLUUID& owner_id)
{
llinfos << "importing inventory for " << owner_id << llendl;
- LLPermissions default_perm;
- default_perm.init(LLUUID::null, owner_id, LLUUID::null, LLUUID::null);
- LLPointer<LLViewerInventoryItem> item;
- LLUUID id;
- LLAssetType::EType type;
- LLInventoryType::EType inv_type;
bool rv = true;
- for(options_t::const_iterator it = options.begin(); it < options.end(); ++it)
- {
- item = new LLViewerInventoryItem;
- response_t::const_iterator no_response = (*it).end();
- response_t::const_iterator meat;
- meat = (*it).find("name");
- if(meat == no_response) goto clean_item;
- item->rename(std::string((*meat).second));
- meat = (*it).find("item_id");
- if(meat == no_response) goto clean_item;
- id.set((*meat).second);
- item->setUUID(id);
- meat = (*it).find("parent_id");
- if(meat == no_response) goto clean_item;
- id.set((*meat).second);
- item->setParent(id);
- meat = (*it).find("type");
- if(meat == no_response) goto clean_item;
- type = (LLAssetType::EType)atoi((*meat).second.c_str());
- item->setType(type);
- meat = (*it).find("inv_type");
- if(meat != no_response)
- {
- inv_type = (LLInventoryType::EType)atoi((*meat).second.c_str());
- item->setInventoryType(inv_type);
- }
- meat = (*it).find("data_id");
- if(meat == no_response) goto clean_item;
- id.set((*meat).second);
- if(LLAssetType::AT_CALLINGCARD == type)
- {
- LLPermissions perm;
- perm.init(id, owner_id, LLUUID::null, LLUUID::null);
- item->setPermissions(perm);
+ for(LLSD::array_const_iterator it = options.beginArray(),
+ end = options.endArray(); it != end; ++it)
+ {
+ LLSD name = (*it)["name"];
+ LLSD item_id = (*it)["item_id"];
+ LLSD parent_id = (*it)["parent_id"];
+ LLSD asset_type = (*it)["type"];
+ LLSD data_id = (*it)["data_id"];
+ if(name.isDefined()
+ && item_id.isDefined()
+ && parent_id.isDefined()
+ && asset_type.isDefined()
+ && data_id.isDefined())
+ {
+ LLPointer<LLViewerInventoryItem> item = new LLViewerInventoryItem;
+ item->rename(name.asString());
+ item->setUUID(item_id.asUUID());
+ item->setParent(parent_id.asUUID());
+ LLAssetType::EType type = (LLAssetType::EType)asset_type.asInteger();
+ item->setType(type);
+
+ LLSD llsd_inv_type = (*it)["inv_type"];
+ if(llsd_inv_type.isDefined())
+ {
+ LLInventoryType::EType inv_type = (LLInventoryType::EType)llsd_inv_type.asInteger();
+ item->setInventoryType(inv_type);
+ }
+
+ if(LLAssetType::AT_CALLINGCARD == type)
+ {
+ LLPermissions perm;
+ perm.init(data_id.asUUID(), owner_id, LLUUID::null, LLUUID::null);
+ item->setPermissions(perm);
+ }
+ else
+ {
+ LLPermissions default_perm;
+ default_perm.init(LLUUID::null, owner_id, LLUUID::null, LLUUID::null);
+ LLSD llsd_perm_mask = (*it)["perm_mask"];
+ if(llsd_perm_mask.isDefined())
+ {
+ PermissionMask perm_mask = llsd_perm_mask.asInteger();
+ default_perm.initMasks(
+ perm_mask, perm_mask, perm_mask, perm_mask, perm_mask);
+ }
+ else
+ {
+ default_perm.initMasks(
+ PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE);
+ }
+ item->setPermissions(default_perm);
+ item->setAssetUUID(data_id.asUUID());
+ }
+
+ LLSD flags = (*it)["flags"];
+ if(flags.isDefined())
+ {
+ // Not sure how well LLSD.asInteger() maps to
+ // unsigned long - using strtoul()
+ item->setFlags(strtoul(flags.asString().c_str(), NULL, 0));
+ }
+
+ LLSD time = (*it)["time"];
+ if(time.isDefined())
+ {
+ item->setCreationDate(time.asInteger());
+ }
+ addItem(item);
}
else
{
- meat = (*it).find("perm_mask");
- if(meat != no_response)
- {
- PermissionMask perm_mask = atoi((*meat).second.c_str());
- default_perm.initMasks(
- perm_mask, perm_mask, perm_mask, perm_mask, perm_mask);
- }
- else
- {
- default_perm.initMasks(
- PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE, PERM_NONE);
- }
- item->setPermissions(default_perm);
- item->setAssetUUID(id);
- }
- meat = (*it).find("flags");
- if(meat != no_response)
- {
- item->setFlags(strtoul((*meat).second.c_str(), NULL, 0));
- }
- meat = (*it).find("time");
- if(meat != no_response)
- {
- item->setCreationDate(atoi((*meat).second.c_str()));
+ llwarns << "Unable to import near " << name.asString() << llendl;
+ rv = false;
}
- addItem(item);
- continue;
- clean_item:
- llwarns << "Unable to import near " << item->getName() << llendl;
- rv = false;
- //delete item; // automatic when item is reassigned or destroyed
}
return rv;
}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 2ddc35b9ef..649a7e5b16 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -329,10 +329,8 @@ public:
// methods to load up inventory skeleton & meat. These are used
// during authentication. return true if everything parsed.
- typedef std::map<std::string, std::string> response_t;
- typedef std::vector<response_t> options_t;
- bool loadSkeleton(const options_t& options, const LLUUID& owner_id);
- bool loadMeat(const options_t& options, const LLUUID& owner_id);
+ bool loadSkeleton(const LLSD& options, const LLUUID& owner_id);
+ bool loadMeat(const LLSD& options, const LLUUID& owner_id);
// This is a brute force method to rebuild the entire parent-child
// relations.
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
new file mode 100644
index 0000000000..cb7dbc2de0
--- /dev/null
+++ b/indra/newview/lllogininstance.cpp
@@ -0,0 +1,468 @@
+/**
+ * @file lllogininstance.cpp
+ * @brief Viewer's host for a login connection.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lllogininstance.h"
+
+// llcommon
+#include "llevents.h"
+#include "llmd5.h"
+#include "stringize.h"
+
+// llmessage (!)
+#include "llfiltersd2xmlrpc.h" // for xml_escape_string()
+
+// login
+#include "lllogin.h"
+
+// newview
+#include "llviewernetwork.h"
+#include "llviewercontrol.h"
+#include "llurlsimstring.h"
+#include "llfloaterreg.h"
+#include "llfloatertos.h"
+#include "llwindow.h"
+#if LL_LINUX || LL_SOLARIS
+#include "lltrans.h"
+#endif
+
+static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";
+static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";
+
+std::string construct_start_string();
+
+LLLoginInstance::LLLoginInstance() :
+ mLoginModule(new LLLogin()),
+ mNotifications(NULL),
+ mLoginState("offline"),
+ mUserInteraction(true),
+ mSkipOptionalUpdate(false),
+ mAttemptComplete(false),
+ mTransferRate(0.0f)
+{
+ mLoginModule->getEventPump().listen("lllogininstance",
+ boost::bind(&LLLoginInstance::handleLoginEvent, this, _1));
+}
+
+LLLoginInstance::~LLLoginInstance()
+{
+}
+
+void LLLoginInstance::connect(const LLSD& credentials)
+{
+ std::vector<std::string> uris;
+ LLViewerLogin::getInstance()->getLoginURIs(uris);
+ connect(uris.front(), credentials);
+}
+
+void LLLoginInstance::connect(const std::string& uri, const LLSD& credentials)
+{
+ mAttemptComplete = false; // Reset attempt complete at this point!
+ constructAuthParams(credentials);
+ mLoginModule->connect(uri, mRequestData);
+}
+
+void LLLoginInstance::reconnect()
+{
+ // Sort of like connect, only using the pre-existing
+ // request params.
+ std::vector<std::string> uris;
+ LLViewerLogin::getInstance()->getLoginURIs(uris);
+ mLoginModule->connect(uris.front(), mRequestData);
+}
+
+void LLLoginInstance::disconnect()
+{
+ mAttemptComplete = false; // Reset attempt complete at this point!
+ mRequestData.clear();
+ mLoginModule->disconnect();
+}
+
+LLSD LLLoginInstance::getResponse()
+{
+ return mResponseData;
+}
+
+void LLLoginInstance::constructAuthParams(const LLSD& credentials)
+{
+ // Set up auth request options.
+//#define LL_MINIMIAL_REQUESTED_OPTIONS
+ LLSD requested_options;
+ // *Note: this is where gUserAuth used to be created.
+ requested_options.append("inventory-root");
+ requested_options.append("inventory-skeleton");
+ //requested_options.append("inventory-meat");
+ //requested_options.append("inventory-skel-targets");
+#if (!defined LL_MINIMIAL_REQUESTED_OPTIONS)
+ if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary"))
+ {
+ requested_options.append("inventory-lib-root");
+ requested_options.append("inventory-lib-owner");
+ requested_options.append("inventory-skel-lib");
+ // requested_options.append("inventory-meat-lib");
+ }
+
+ requested_options.append("initial-outfit");
+ requested_options.append("gestures");
+ requested_options.append("event_categories");
+ requested_options.append("event_notifications");
+ requested_options.append("classified_categories");
+ //requested_options.append("inventory-targets");
+ requested_options.append("buddy-list");
+ requested_options.append("ui-config");
+#endif
+ requested_options.append("tutorial_setting");
+ requested_options.append("login-flags");
+ requested_options.append("global-textures");
+ if(gSavedSettings.getBOOL("ConnectAsGod"))
+ {
+ gSavedSettings.setBOOL("UseDebugMenus", TRUE);
+ requested_options.append("god-connect");
+ }
+
+ char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
+ LLMD5 hashed_mac;
+ hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES );
+ hashed_mac.finalize();
+ hashed_mac.hex_digest(hashed_mac_string);
+
+ // prepend "$1$" to the password to indicate its the md5'd version.
+ std::string dpasswd("$1$");
+ dpasswd.append(credentials["passwd"].asString());
+
+ // (re)initialize the request params with creds.
+ LLSD request_params(credentials);
+ request_params["passwd"] = dpasswd;
+ request_params["start"] = construct_start_string();
+ request_params["skipoptional"] = mSkipOptionalUpdate;
+ request_params["agree_to_tos"] = false; // Always false here. Set true in
+ request_params["read_critical"] = false; // handleTOSResponse
+ request_params["last_exec_event"] = mLastExecEvent;
+ request_params["mac"] = hashed_mac_string;
+ request_params["version"] = gCurrentVersion; // Includes channel name
+ request_params["channel"] = gSavedSettings.getString("VersionChannelName");
+ request_params["id0"] = mSerialNumber;
+
+ mRequestData.clear();
+ mRequestData["method"] = "login_to_simulator";
+ mRequestData["params"] = request_params;
+ mRequestData["options"] = requested_options;
+}
+
+bool LLLoginInstance::handleLoginEvent(const LLSD& event)
+{
+ std::cout << "LoginListener called!: \n";
+ std::cout << event << "\n";
+
+ if(!(event.has("state") && event.has("progress")))
+ {
+ llerrs << "Unknown message from LLLogin!" << llendl;
+ }
+
+ mLoginState = event["state"].asString();
+ mResponseData = event["data"];
+
+ if(event.has("transfer_rate"))
+ {
+ mTransferRate = event["transfer_rate"].asReal();
+ }
+
+ if(mLoginState == "offline")
+ {
+ handleLoginFailure(event);
+ }
+ else if(mLoginState == "online")
+ {
+ handleLoginSuccess(event);
+ }
+
+ return false;
+}
+
+bool LLLoginInstance::handleLoginFailure(const LLSD& event)
+{
+ // Login has failed.
+ // Figure out why and respond...
+ LLSD response = event["data"];
+ std::string reason_response = response["reason"].asString();
+ std::string message_response = response["message"].asString();
+ if(mUserInteraction)
+ {
+ // For the cases of critical message or TOS agreement,
+ // start the TOS dialog. The dialog response will be handled
+ // by the LLLoginInstance::handleTOSResponse() callback.
+ // The callback intiates the login attempt next step, either
+ // to reconnect or to end the attempt in failure.
+ if(reason_response == "tos")
+ {
+ LLSD data(LLSD::emptyMap());
+ data["message"] = message_response;
+ data["reply_pump"] = TOS_REPLY_PUMP;
+ LLFloaterReg::showInstance("message_tos", data);
+ LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
+ .listen(TOS_LISTENER_NAME,
+ boost::bind(&LLLoginInstance::handleTOSResponse,
+ this, _1, "agree_to_tos"));
+ }
+ else if(reason_response == "critical")
+ {
+ LLSD data(LLSD::emptyMap());
+ data["message"] = message_response;
+ data["reply_pump"] = TOS_REPLY_PUMP;
+ LLFloaterReg::showInstance("message_critical", data);
+ LLEventPumps::instance().obtain(TOS_REPLY_PUMP)
+ .listen(TOS_LISTENER_NAME,
+ boost::bind(&LLLoginInstance::handleTOSResponse,
+ this, _1, "read_critical"));
+ }
+ else if(reason_response == "update" || gSavedSettings.getBOOL("ForceMandatoryUpdate"))
+ {
+ gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
+ updateApp(true, message_response);
+ }
+ else if(reason_response == "optional")
+ {
+ updateApp(false, message_response);
+ }
+ else
+ {
+ attemptComplete();
+ }
+ }
+ else // no user interaction
+ {
+ attemptComplete();
+ }
+
+ return false;
+}
+
+bool LLLoginInstance::handleLoginSuccess(const LLSD& event)
+{
+ if(gSavedSettings.getBOOL("ForceMandatoryUpdate"))
+ {
+ LLSD response = event["data"];
+ std::string message_response = response["message"].asString();
+
+ // Testing update...
+ gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
+
+ // Don't confuse startup by leaving login "online".
+ mLoginModule->disconnect();
+ updateApp(true, message_response);
+ }
+ else
+ {
+ attemptComplete();
+ }
+ return false;
+}
+
+bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
+{
+ if(accepted)
+ {
+ // Set the request data to true and retry login.
+ mRequestData["params"][key] = true;
+ reconnect();
+ }
+ else
+ {
+ attemptComplete();
+ }
+
+ LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME);
+ return true;
+}
+
+
+void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)
+{
+ // store off config state, as we might quit soon
+ gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+ LLUIColorTable::instance().saveUserSettings();
+
+ std::ostringstream message;
+ std::string msg;
+ if (!auth_msg.empty())
+ {
+ msg = "(" + auth_msg + ") \n";
+ }
+
+ LLSD args;
+ args["MESSAGE"] = msg;
+
+ LLSD payload;
+ payload["mandatory"] = mandatory;
+
+/*
+ We're constructing one of the following 6 strings here:
+ "DownloadWindowsMandatory"
+ "DownloadWindowsReleaseForDownload"
+ "DownloadWindows"
+ "DownloadMacMandatory"
+ "DownloadMacReleaseForDownload"
+ "DownloadMac"
+
+ I've called them out explicitly in this comment so that they can be grepped for.
+
+ Also, we assume that if we're not Windows we're Mac. If we ever intend to support
+ Linux with autoupdate, this should be an explicit #elif LL_DARWIN, but
+ we'd rather deliver the wrong message than no message, so until Linux is supported
+ we'll leave it alone.
+ */
+ std::string notification_name = "Download";
+
+#if LL_WINDOWS
+ notification_name += "Windows";
+#else
+ notification_name += "Mac";
+#endif
+
+ if (mandatory)
+ {
+ notification_name += "Mandatory";
+ }
+ else
+ {
+#if LL_RELEASE_FOR_DOWNLOAD
+ notification_name += "ReleaseForDownload";
+#endif
+ }
+
+ if(mNotifications)
+ {
+ mNotifications->add(notification_name, args, payload,
+ boost::bind(&LLLoginInstance::updateDialogCallback, this, _1, _2));
+ }
+
+ /* *NOTE:Mani Experiment with Event API interface.
+ if(!mUpdateAppResponse)
+ {
+ bool make_unique = true;
+ mUpdateAppResponse.reset(new LLEventStream("logininstance_updateapp", make_unique));
+ mUpdateAppResponse->listen("diaupdateDialogCallback",
+ boost::bind(&LLLoginInstance::updateDialogCallback,
+ this, _1
+ )
+ );
+ }
+
+ LLSD event;
+ event["op"] = "requestAdd";
+ event["name"] = notification_name;
+ event["substitutions"] = args;
+ event["payload"] = payload;
+ event["reply"] = mUpdateAppResponse->getName();
+
+ LLEventPumps::getInstance()->obtain("LLNotifications").post(event);
+ */
+}
+
+bool LLLoginInstance::updateDialogCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotification::getSelectedOption(notification, response);
+ std::string update_exe_path;
+ bool mandatory = notification["payload"]["mandatory"].asBoolean();
+
+#if !LL_RELEASE_FOR_DOWNLOAD
+ if (option == 2)
+ {
+ // This condition attempts to skip the
+ // update if using a dev build.
+ // The relog probably won't work if the
+ // update is mandatory. :)
+
+ // *REMOVE:Mani - Saving for reference...
+ //LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
+ mSkipOptionalUpdate = true;
+ reconnect();
+ return false;
+ }
+#endif
+
+ if (option == 1)
+ {
+ // ...user doesn't want to do it
+ if (mandatory)
+ {
+ // Mandatory update, user chose to not to update...
+ // The login attemp is complete, startup should
+ // quit when detecting this.
+ attemptComplete();
+
+ // *REMOVE:Mani - Saving for reference...
+ //LLAppViewer::instance()->forceQuit();
+ // // Bump them back to the login screen.
+ // //reset_login();
+ }
+ else
+ {
+ // Optional update, user chose to skip
+ mSkipOptionalUpdate = true;
+ reconnect();
+ }
+ return false;
+ }
+
+ if(mUpdaterLauncher)
+ {
+ mUpdaterLauncher();
+ }
+
+ attemptComplete();
+
+ return false;
+}
+
+std::string construct_start_string()
+{
+ std::string start;
+ if (LLURLSimString::parse())
+ {
+ // a startup URL was specified
+ std::string unescaped_start =
+ STRINGIZE( "uri:"
+ << LLURLSimString::sInstance.mSimName << "&"
+ << LLURLSimString::sInstance.mX << "&"
+ << LLURLSimString::sInstance.mY << "&"
+ << LLURLSimString::sInstance.mZ);
+ start = xml_escape_string(unescaped_start);
+ }
+ else
+ {
+ start = gSavedSettings.getString("LoginLocation");
+ }
+ return start;
+}
+
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
new file mode 100644
index 0000000000..6a2ccf919e
--- /dev/null
+++ b/indra/newview/lllogininstance.h
@@ -0,0 +1,111 @@
+/**
+ * @file lllogininstance.h
+ * @brief A host for the viewer's login connection.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ *
+ * Copyright (c) 2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLLOGININSTANCE_H
+#define LL_LLLOGININSTANCE_H
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/function.hpp>
+class LLLogin;
+class LLEventStream;
+class LLNotificationsInterface;
+
+// This class hosts the login module and is used to
+// negotiate user authentication attempts.
+class LLLoginInstance : public LLSingleton<LLLoginInstance>
+{
+public:
+ LLLoginInstance();
+ ~LLLoginInstance();
+
+ void connect(const LLSD& credential); // Connect to the current grid choice.
+ void connect(const std::string& uri, const LLSD& credential); // Connect to the given uri.
+ void reconnect(); // reconnect using the current credentials.
+ void disconnect();
+
+ bool authFailure() { return mAttemptComplete && mLoginState == "offline"; }
+ bool authSuccess() { return mAttemptComplete && mLoginState == "online"; }
+
+ const std::string& getLoginState() { return mLoginState; }
+ LLSD getResponse(const std::string& key) { return getResponse()[key]; }
+ LLSD getResponse();
+
+ // Only valid when authSuccess == true.
+ const F64 getLastTransferRateBPS() { return mTransferRate; }
+
+ // Set whether this class will drive user interaction.
+ // If not, login failures like 'need tos agreement' will
+ // end the login attempt.
+ void setUserInteraction(bool state) { mUserInteraction = state; }
+ bool getUserInteraction() { return mUserInteraction; }
+
+ // Whether to tell login to skip optional update request.
+ // False by default.
+ void setSkipOptionalUpdate(bool state) { mSkipOptionalUpdate = state; }
+ void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
+ void setLastExecEvent(int lee) { mLastExecEvent = lee; }
+
+ void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
+
+ typedef boost::function<void()> UpdaterLauncherCallback;
+ void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; }
+
+private:
+ void constructAuthParams(const LLSD& credentials);
+ void updateApp(bool mandatory, const std::string& message);
+ bool updateDialogCallback(const LLSD& notification, const LLSD& response);
+
+ bool handleLoginEvent(const LLSD& event);
+ bool handleLoginFailure(const LLSD& event);
+ bool handleLoginSuccess(const LLSD& event);
+
+ bool handleTOSResponse(bool v, const std::string& key);
+
+ void attemptComplete() { mAttemptComplete = true; } // In the future an event?
+
+ boost::scoped_ptr<LLLogin> mLoginModule;
+ LLNotificationsInterface* mNotifications;
+
+ std::string mLoginState;
+ LLSD mRequestData;
+ LLSD mResponseData;
+ bool mUserInteraction;
+ bool mSkipOptionalUpdate;
+ bool mAttemptComplete;
+ F64 mTransferRate;
+ std::string mSerialNumber;
+ int mLastExecEvent;
+ UpdaterLauncherCallback mUpdaterLauncher;
+ boost::scoped_ptr<LLEventStream> mUpdateAppResponse;
+};
+
+#endif
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index efa15e05da..2433b6fac6 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -68,7 +68,6 @@
#include "llworldmap.h"
#include "llfocusmgr.h"
#include "llnearbychatbar.h"
-
void handle_pay_by_id(const LLUUID& agent_id)
{
const BOOL is_group = FALSE;
diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp
index c6840721a3..61e18195b8 100644
--- a/indra/newview/llpanelplace.cpp
+++ b/indra/newview/llpanelplace.cpp
@@ -58,6 +58,7 @@
//#include "llviewermenu.h" // create_landmark()
#include "llweb.h"
#include "llsdutil.h"
+#include "llsdutil_math.h"
LLPanelPlace::LLPanelPlace()
: LLPanel(),
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index a01977c9b5..3926ee0f07 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -59,6 +59,7 @@
#include "llviewerregion.h"
#include "llviewertexteditor.h"
#include "llworldmap.h"
+#include "llsdutil_math.h"
static LLRegisterPanelClassWrapper<LLPanelPlaceInfo> t_place_info("panel_place_info");
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 920ec0c65d..8859f1ffb5 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -56,7 +56,6 @@
#include "llcachename.h"
#include "lldir.h"
#include "llerrorcontrol.h"
-#include "llfiltersd2xmlrpc.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llhttpsender.h"
@@ -66,10 +65,11 @@
#include "llmemorystream.h"
#include "llmessageconfig.h"
#include "llmoveview.h"
+#include "llteleporthistory.h"
#include "llregionhandle.h"
#include "llsd.h"
#include "llsdserialize.h"
-#include "llsdutil.h"
+#include "llsdutil_math.h"
#include "llsecondlifeurls.h"
#include "llstring.h"
#include "lluserrelations.h"
@@ -101,7 +101,6 @@
#include "llfloaterland.h"
#include "llfloaterpreference.h"
#include "llfloatertopobjects.h"
-#include "llfloatertos.h"
#include "llfloaterworldmap.h"
#include "llgesturemgr.h"
#include "llgroupmgr.h"
@@ -114,6 +113,7 @@
#include "llfloaterinventory.h"
#include "llkeyboard.h"
#include "llloginhandler.h" // gLoginHandler, SLURL support
+#include "lllogininstance.h" // Host the login module.
#include "llpanellogin.h"
#include "llmutelist.h"
#include "llnotify.h"
@@ -133,7 +133,6 @@
#include "llsecondlifeurls.h"
#include "llselectmgr.h"
#include "llsky.h"
-#include "llsrv.h"
#include "llstatview.h"
#include "lltrans.h"
#include "llstatusbar.h" // sendMoneyBalanceRequest(), owns L$ balance
@@ -146,7 +145,6 @@
#include "llurlsimstring.h"
#include "llurlhistory.h"
#include "llurlwhitelist.h"
-#include "lluserauth.h"
#include "llvieweraudio.h"
#include "llviewerassetstorage.h"
#include "llviewercamera.h"
@@ -188,6 +186,9 @@
#include "llwearable.h"
#include "llinventorybridge.h"
+#include "lllogin.h"
+#include "llevents.h"
+
#if LL_WINDOWS
#include "llwindebug.h"
#include "lldxhardware.h"
@@ -197,12 +198,12 @@
// exported globals
//
bool gAgentMovementCompleted = false;
-std::string gInitialOutfit;
-std::string gInitialOutfitGender;
std::string SCREEN_HOME_FILENAME = "screen_home.bmp";
std::string SCREEN_LAST_FILENAME = "screen_last.bmp";
+LLPointer<LLViewerTexture> gStartTexture;
+
//
// Imported globals
//
@@ -212,12 +213,6 @@ extern S32 gStartImageHeight;
//
// local globals
//
-
-LLPointer<LLViewerTexture> gStartTexture;
-
-static LLHost gAgentSimHost;
-static BOOL gSkipOptionalUpdate = FALSE;
-
static bool gGotUseCircuitCodeAck = false;
static std::string sInitialOutfit;
static std::string sInitialOutfitGender; // "male" or "female"
@@ -226,6 +221,18 @@ static bool gUseCircuitCallbackCalled = false;
EStartupState LLStartUp::gStartupState = STATE_FIRST;
+// *NOTE:Mani - to reconcile with giab changes...
+static std::string gFirstname;
+static std::string gLastname;
+static std::string gPassword;
+
+static U64 gFirstSimHandle = 0;
+static LLHost gFirstSim;
+static std::string gFirstSimSeedCap;
+static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);
+static std::string gAgentStartLocation = "safe";
+
+static LLEventStream sStartupStateWatcher("StartupState");
//
// local function declaration
@@ -238,8 +245,6 @@ void show_first_run_dialog();
bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
bool login_alert_status(const LLSD& notification, const LLSD& response);
-void update_app(BOOL mandatory, const std::string& message);
-bool update_dialog_callback(const LLSD& notification, const LLSD& response);
void login_packet_failed(void**, S32 result);
void use_circuit_callback(void**, S32 result);
void register_viewer_callbacks(LLMessageSystem* msg);
@@ -249,6 +254,7 @@ void init_start_screen(S32 location_id);
void release_start_screen();
void reset_login();
void apply_udp_blacklist(const std::string& csv);
+bool process_login_success_response();
void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group)
{
@@ -308,9 +314,6 @@ void update_texture_fetch()
gTextureList.updateImages(0.10f);
}
-static std::vector<std::string> sAuthUris;
-static S32 sAuthUriNum = -1;
-
//Copies landmarks from the "Library" to "My Favorites"
void populate_favorites_bar()
{
@@ -382,23 +385,11 @@ bool idle_startup()
// auth/transform loop will do.
static F32 progress = 0.10f;
- static std::string auth_method;
static std::string auth_desc;
static std::string auth_message;
- static std::string firstname;
- static std::string lastname;
- static LLUUID web_login_key;
- static std::string password;
- static std::vector<const char*> requested_options;
-
- static U64 first_sim_handle = 0;
- static LLHost first_sim;
- static std::string first_sim_seed_cap;
static LLVector3 initial_sun_direction(1.f, 0.f, 0.f);
static LLVector3 agent_start_position_region(10.f, 10.f, 10.f); // default for when no space server
- static LLVector3 agent_start_look_at(1.0f, 0.f, 0.f);
- static std::string agent_start_location = "safe";
// last location by default
static S32 agent_location_id = START_LOCATION_ID_LAST;
@@ -406,7 +397,7 @@ bool idle_startup()
static bool show_connect_box = true;
- static bool stipend_since_login = false;
+ //static bool stipend_since_login = false;
// HACK: These are things from the main loop that usually aren't done
// until initialization is complete, but need to be done here for things
@@ -427,12 +418,7 @@ bool idle_startup()
LLStringUtil::setLocale (LLTrans::getString(system));
- if (gNoRender)
- {
- // HACK, skip optional updates if you're running drones
- gSkipOptionalUpdate = TRUE;
- }
- else
+ if (!gNoRender)
{
// Update images?
gTextureList.updateImages(0.01f);
@@ -748,24 +734,23 @@ bool idle_startup()
|| !gLoginHandler.getWebLoginKey().isNull() )
{
// We have at least some login information on a SLURL
- firstname = gLoginHandler.getFirstName();
- lastname = gLoginHandler.getLastName();
- web_login_key = gLoginHandler.getWebLoginKey();
+ gFirstname = gLoginHandler.getFirstName();
+ gLastname = gLoginHandler.getLastName();
// Show the login screen if we don't have everything
show_connect_box =
- firstname.empty() || lastname.empty() || web_login_key.isNull();
+ gFirstname.empty() || gLastname.empty();
}
else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
{
LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
- firstname = cmd_line_login[0].asString();
- lastname = cmd_line_login[1].asString();
+ gFirstname = cmd_line_login[0].asString();
+ gLastname = cmd_line_login[1].asString();
LLMD5 pass((unsigned char*)cmd_line_login[2].asString().c_str());
char md5pass[33]; /* Flawfinder: ignore */
pass.hex_digest(md5pass);
- password = md5pass;
+ gPassword = md5pass;
#ifdef USE_VIEWER_AUTH
show_connect_box = true;
@@ -776,9 +761,9 @@ bool idle_startup()
}
else if (gSavedSettings.getBOOL("AutoLogin"))
{
- firstname = gSavedSettings.getString("FirstName");
- lastname = gSavedSettings.getString("LastName");
- password = LLStartUp::loadPasswordFromDisk();
+ gFirstname = gSavedSettings.getString("FirstName");
+ gLastname = gSavedSettings.getString("LastName");
+ gPassword = LLStartUp::loadPasswordFromDisk();
gSavedSettings.setBOOL("RememberPassword", TRUE);
#ifdef USE_VIEWER_AUTH
@@ -791,9 +776,9 @@ bool idle_startup()
{
// if not automatically logging in, display login dialog
// a valid grid is selected
- firstname = gSavedSettings.getString("FirstName");
- lastname = gSavedSettings.getString("LastName");
- password = LLStartUp::loadPasswordFromDisk();
+ gFirstname = gSavedSettings.getString("FirstName");
+ gLastname = gSavedSettings.getString("LastName");
+ gPassword = LLStartUp::loadPasswordFromDisk();
show_connect_box = true;
}
@@ -829,7 +814,7 @@ bool idle_startup()
// Load all the name information out of the login view
// NOTE: Hits "Attempted getFields with no login view shown" warning, since we don't
// show the login view until login_show() is called below.
- // LLPanelLogin::getFields(firstname, lastname, password);
+ // LLPanelLogin::getFields(gFirstname, gLastname, gPassword);
if (gNoRender)
{
@@ -841,7 +826,7 @@ bool idle_startup()
// Show the login dialog
login_show();
// connect dialog is already shown, so fill in the names
- LLPanelLogin::setFields( firstname, lastname, password);
+ LLPanelLogin::setFields( gFirstname, gLastname, gPassword);
LLPanelLogin::giveFocus();
@@ -898,37 +883,29 @@ bool idle_startup()
if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
{
- //reset the values that could have come in from a slurl
- if (!gLoginHandler.getWebLoginKey().isNull())
- {
- firstname = gLoginHandler.getFirstName();
- lastname = gLoginHandler.getLastName();
- web_login_key = gLoginHandler.getWebLoginKey();
- }
-
if (show_connect_box)
{
// TODO if not use viewer auth
// Load all the name information out of the login view
- LLPanelLogin::getFields(&firstname, &lastname, &password);
+ LLPanelLogin::getFields(&gFirstname, &gLastname, &gPassword);
// end TODO
// HACK: Try to make not jump on login
gKeyboard->resetKeys();
}
- if (!firstname.empty() && !lastname.empty())
+ if (!gFirstname.empty() && !gLastname.empty())
{
- gSavedSettings.setString("FirstName", firstname);
- gSavedSettings.setString("LastName", lastname);
+ gSavedSettings.setString("FirstName", gFirstname);
+ gSavedSettings.setString("LastName", gLastname);
- LL_INFOS("AppInit") << "Attempting login as: " << firstname << " " << lastname << LL_ENDL;
- gDebugInfo["LoginName"] = firstname + " " + lastname;
+ LL_INFOS("AppInit") << "Attempting login as: " << gFirstname << " " << gLastname << LL_ENDL;
+ gDebugInfo["LoginName"] = gFirstname + " " + gLastname;
}
// create necessary directories
// *FIX: these mkdir's should error check
- gDirUtilp->setLindenUserDir(firstname, lastname);
+ gDirUtilp->setLindenUserDir(gFirstname, gLastname);
LLFile::mkdir(gDirUtilp->getLindenUserDir());
// Set PerAccountSettingsFile to the default value.
@@ -962,7 +939,7 @@ bool idle_startup()
gDirUtilp->setChatLogsDir(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
}
- gDirUtilp->setPerAccountChatLogsDir(firstname, lastname);
+ gDirUtilp->setPerAccountChatLogsDir(gFirstname, gLastname);
LLFile::mkdir(gDirUtilp->getChatLogsDir());
LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir());
@@ -983,13 +960,6 @@ bool idle_startup()
if (show_connect_box)
{
- if ( LLPanelLogin::isGridComboDirty() )
- {
- // User picked a grid from the popup, so clear the
- // stored uris and they will be reacquired from the grid choice.
- sAuthUris.clear();
- }
-
std::string location;
LLPanelLogin::getLocation( location );
LLURLSimString::setString( location );
@@ -1018,7 +988,7 @@ bool idle_startup()
agent_location_id = START_LOCATION_ID_URL;
// doesn't really matter what location_which is, since
- // agent_start_look_at will be overwritten when the
+ // gAgentStartLookAt will be overwritten when the
// UserLoginLocationReply arrives
location_which = START_LOCATION_ID_LAST;
}
@@ -1051,590 +1021,124 @@ bool idle_startup()
gVFS->pokeFiles();
- // skipping over STATE_UPDATE_CHECK because that just waits for input
LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
return FALSE;
}
- if (STATE_UPDATE_CHECK == LLStartUp::getStartupState())
- {
- // wait for user to give input via dialog box
- return FALSE;
- }
-
if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
{
-//#define LL_MINIMIAL_REQUESTED_OPTIONS
gDebugInfo["GridName"] = LLViewerLogin::getInstance()->getGridLabel();
- // *Note: this is where gUserAuth used to be created.
- requested_options.clear();
- requested_options.push_back("inventory-root");
- requested_options.push_back("inventory-skeleton");
- //requested_options.push_back("inventory-meat");
- //requested_options.push_back("inventory-skel-targets");
-#if (!defined LL_MINIMIAL_REQUESTED_OPTIONS)
- if(FALSE == gSavedSettings.getBOOL("NoInventoryLibrary"))
- {
- requested_options.push_back("inventory-lib-root");
- requested_options.push_back("inventory-lib-owner");
- requested_options.push_back("inventory-skel-lib");
- // requested_options.push_back("inventory-meat-lib");
- }
-
- requested_options.push_back("initial-outfit");
- requested_options.push_back("gestures");
- requested_options.push_back("event_categories");
- requested_options.push_back("event_notifications");
- requested_options.push_back("classified_categories");
+ // Update progress status and the display loop.
requested_options.push_back("adult_compliant");
- //requested_options.push_back("inventory-targets");
- requested_options.push_back("buddy-list");
- requested_options.push_back("ui-config");
-#endif
- requested_options.push_back("tutorial_setting");
- requested_options.push_back("login-flags");
- requested_options.push_back("global-textures");
- if(gSavedSettings.getBOOL("ConnectAsGod"))
- {
- gSavedSettings.setBOOL("UseDebugMenus", TRUE);
- requested_options.push_back("god-connect");
- }
- std::vector<std::string> uris;
- LLViewerLogin::getInstance()->getLoginURIs(uris);
- std::vector<std::string>::const_iterator iter, end;
- for (iter = uris.begin(), end = uris.end(); iter != end; ++iter)
- {
- std::vector<std::string> rewritten;
- rewritten = LLSRV::rewriteURI(*iter);
- sAuthUris.insert(sAuthUris.end(),
- rewritten.begin(), rewritten.end());
- }
- sAuthUriNum = 0;
- auth_method = "login_to_simulator";
-
auth_desc = LLTrans::getString("LoginInProgress");
- LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
- }
-
- if (STATE_LOGIN_AUTHENTICATE == LLStartUp::getStartupState())
- {
- LL_DEBUGS("AppInit") << "STATE_LOGIN_AUTHENTICATE" << LL_ENDL;
set_startup_status(progress, auth_desc, auth_message);
progress += 0.02f;
display_startup();
-
- std::stringstream start;
- if (LLURLSimString::parse())
- {
- // a startup URL was specified
- std::stringstream unescaped_start;
- unescaped_start << "uri:"
- << LLURLSimString::sInstance.mSimName << "&"
- << LLURLSimString::sInstance.mX << "&"
- << LLURLSimString::sInstance.mY << "&"
- << LLURLSimString::sInstance.mZ;
- start << xml_escape_string(unescaped_start.str());
-
- }
- else
- {
- start << gSavedSettings.getString("LoginLocation");
- }
-
- char hashed_mac_string[MD5HEX_STR_SIZE]; /* Flawfinder: ignore */
- LLMD5 hashed_mac;
- hashed_mac.update( gMACAddress, MAC_ADDRESS_BYTES );
- hashed_mac.finalize();
- hashed_mac.hex_digest(hashed_mac_string);
-
- // TODO if statement here to use web_login_key
- sAuthUriNum = llclamp(sAuthUriNum, 0, (S32)sAuthUris.size()-1);
- LLUserAuth::getInstance()->authenticate(
- sAuthUris[sAuthUriNum],
- auth_method,
- firstname,
- lastname,
- password, // web_login_key,
- start.str(),
- gSkipOptionalUpdate,
- gAcceptTOS,
- gAcceptCriticalMessage,
- gLastExecEvent,
- requested_options,
- hashed_mac_string,
- LLAppViewer::instance()->getSerialNumber());
-
- // reset globals
- gAcceptTOS = FALSE;
- gAcceptCriticalMessage = FALSE;
- LLStartUp::setStartupState( STATE_LOGIN_NO_DATA_YET );
- return FALSE;
- }
- if(STATE_LOGIN_NO_DATA_YET == LLStartUp::getStartupState())
- {
- LL_DEBUGS("AppInit") << "STATE_LOGIN_NO_DATA_YET" << LL_ENDL;
- // If we get here we have gotten past the potential stall
- // in curl, so take "may appear frozen" out of progress bar. JC
- auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
- set_startup_status(progress, auth_desc, auth_message);
- // Process messages to keep from dropping circuit.
- LLMessageSystem* msg = gMessageSystem;
- while (msg->checkAllMessages(gFrameCount, gServicePump))
- {
- }
- msg->processAcks();
- LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
- if(LLUserAuth::E_NO_RESPONSE_YET == error)
+ // Setting initial values...
+ LLLoginInstance* login = LLLoginInstance::getInstance();
+ login->setNotificationsInterface(LLNotifications::getInstance());
+ if(gNoRender)
{
- LL_DEBUGS("AppInit") << "waiting..." << LL_ENDL;
- return FALSE;
+ // HACK, skip optional updates if you're running drones
+ login->setSkipOptionalUpdate(true);
}
- LLStartUp::setStartupState( STATE_LOGIN_DOWNLOADING );
- progress += 0.01f;
- set_startup_status(progress, auth_desc, auth_message);
- return FALSE;
- }
- if(STATE_LOGIN_DOWNLOADING == LLStartUp::getStartupState())
- {
- LL_DEBUGS("AppInit") << "STATE_LOGIN_DOWNLOADING" << LL_ENDL;
- // Process messages to keep from dropping circuit.
- LLMessageSystem* msg = gMessageSystem;
- while (msg->checkAllMessages(gFrameCount, gServicePump))
- {
- }
- msg->processAcks();
- LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
- if(LLUserAuth::E_DOWNLOADING == error)
- {
- LL_DEBUGS("AppInit") << "downloading..." << LL_ENDL;
- return FALSE;
- }
+ login->setUserInteraction(show_connect_box);
+ login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
+ login->setLastExecEvent(gLastExecEvent);
+ login->setUpdaterLauncher(boost::bind(&LLAppViewer::launchUpdater, LLAppViewer::instance()));
+
+ // This call to LLLoginInstance::connect() starts the
+ // authentication process.
+ LLSD credentials;
+ credentials["first"] = gFirstname;
+ credentials["last"] = gLastname;
+ credentials["passwd"] = gPassword;
+ login->connect(credentials);
+
LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );
- progress += 0.01f;
- set_startup_status(progress, LLTrans::getString("LoginProcessingResponse"), auth_message);
return FALSE;
}
- if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())
+ if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())
{
- LL_DEBUGS("AppInit") << "STATE_LOGIN_PROCESS_RESPONSE" << LL_ENDL;
+ bool transitionBackToLoginPanel = false;
std::ostringstream emsg;
- bool quit = false;
- bool update = false;
- std::string login_response;
- std::string reason_response;
- std::string message_response;
- bool successful_login = false;
- LLUserAuth::UserAuthcode error = LLUserAuth::getInstance()->authResponse();
- // reset globals
- gAcceptTOS = FALSE;
- gAcceptCriticalMessage = FALSE;
- switch(error)
- {
- case LLUserAuth::E_OK:
- login_response = LLUserAuth::getInstance()->getResponse("login");
- if(login_response == "true")
- {
- // Yay, login!
- successful_login = true;
- }
- else if(login_response == "indeterminate")
+ if(LLLoginInstance::getInstance()->authFailure())
+ {
+ // Still have error conditions that may need some
+ // sort of handling.
+ emsg << "Login failed.\n";
+ std::string reason_response = LLLoginInstance::getInstance()->getResponse("reason");
+ std::string message_response = LLLoginInstance::getInstance()->getResponse("message");
+
+ if(!message_response.empty())
{
- LL_INFOS("AppInit") << "Indeterminate login..." << LL_ENDL;
- sAuthUris = LLSRV::rewriteURI(LLUserAuth::getInstance()->getResponse("next_url"));
- sAuthUriNum = 0;
- auth_method = LLUserAuth::getInstance()->getResponse("next_method");
- auth_message = LLUserAuth::getInstance()->getResponse("message");
- if(auth_method.substr(0, 5) == "login")
+ // XUI: fix translation for strings returned during login
+ // We need a generic table for translations
+ std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ];
+ if ( big_reason.size() == 0 )
{
- auth_desc.assign(LLTrans::getString("LoginAuthenticating"));
+ emsg << message_response;
}
else
{
- auth_desc.assign(LLTrans::getString("LoginMaintenance"));
- }
- // ignoring the duration & options array for now.
- // Go back to authenticate.
- LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
- return FALSE;
- }
- else
- {
- emsg << "Login failed.\n";
- reason_response = LLUserAuth::getInstance()->getResponse("reason");
- message_response = LLUserAuth::getInstance()->getResponse("message");
-
- if (!message_response.empty())
- {
- // XUI: fix translation for strings returned during login
- // We need a generic table for translations
- std::string big_reason = LLAgent::sTeleportErrorMessages[ message_response ];
- if ( big_reason.size() == 0 )
- {
- emsg << message_response;
- }
- else
- {
- emsg << big_reason;
- }
- }
-
- if(reason_response == "tos")
- {
- if (show_connect_box)
- {
- LL_DEBUGS("AppInit") << "Need tos agreement" << LL_ENDL;
- LLStartUp::setStartupState( STATE_UPDATE_CHECK );
- LLFloaterReg::showInstance("message_tos", LLSD(message_response));
- // LLFloaterTOS deletes itself.
- return false;
- }
- else
- {
- quit = true;
- }
- }
- if(reason_response == "critical")
- {
- if (show_connect_box)
- {
- LL_DEBUGS("AppInit") << "Need critical message" << LL_ENDL;
- LLStartUp::setStartupState( STATE_UPDATE_CHECK );
- LLFloaterReg::showInstance("message_critical", LLSD(message_response));
- // LLFloaterTOS deletes itself.
- return false;
- }
- else
- {
- quit = true;
- }
- }
- if(reason_response == "key")
- {
- // Couldn't login because user/password is wrong
- // Clear the password
- password = "";
- }
- if(reason_response == "update")
- {
- auth_message = LLUserAuth::getInstance()->getResponse("message");
- update = true;
- }
- if(reason_response == "optional")
- {
- LL_DEBUGS("AppInit") << "Login got optional update" << LL_ENDL;
- auth_message = LLUserAuth::getInstance()->getResponse("message");
- if (show_connect_box)
- {
- update_app(FALSE, auth_message);
- LLStartUp::setStartupState( STATE_UPDATE_CHECK );
- gSkipOptionalUpdate = TRUE;
- return false;
- }
+ emsg << big_reason;
}
}
- break;
- case LLUserAuth::E_COULDNT_RESOLVE_HOST:
- case LLUserAuth::E_SSL_PEER_CERTIFICATE:
- case LLUserAuth::E_UNHANDLED_ERROR:
- case LLUserAuth::E_SSL_CACERT:
- case LLUserAuth::E_SSL_CONNECT_ERROR:
- default:
- if (sAuthUriNum >= (int) sAuthUris.size() - 1)
- {
- emsg << "Unable to connect to " << LLAppViewer::instance()->getSecondLifeTitle() << ".\n";
- emsg << LLUserAuth::getInstance()->errorMessage();
- } else {
- sAuthUriNum++;
- std::ostringstream s;
- LLStringUtil::format_map_t args;
- args["[NUMBER]"] = llformat("%d", sAuthUriNum + 1);
- auth_desc = LLTrans::getString("LoginAttempt", args);
- LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
- return FALSE;
- }
- break;
- }
-
- if (update || gSavedSettings.getBOOL("ForceMandatoryUpdate"))
- {
- gSavedSettings.setBOOL("ForceMandatoryUpdate", FALSE);
- update_app(TRUE, auth_message);
- LLStartUp::setStartupState( STATE_UPDATE_CHECK );
- return false;
- }
- // Version update and we're not showing the dialog
- if(quit)
- {
- LLUserAuth::getInstance()->reset();
- LLAppViewer::instance()->forceQuit();
- return false;
- }
-
- if(successful_login)
- {
- std::string text;
- text = LLUserAuth::getInstance()->getResponse("udp_blacklist");
- if(!text.empty())
+ if(reason_response == "key")
{
- apply_udp_blacklist(text);
+ // Couldn't login because user/password is wrong
+ // Clear the password
+ gPassword = "";
}
- // unpack login data needed by the application
- text = LLUserAuth::getInstance()->getResponse("agent_id");
- if(!text.empty()) gAgentID.set(text);
- gDebugInfo["AgentID"] = text;
-
- text = LLUserAuth::getInstance()->getResponse("session_id");
- if(!text.empty()) gAgentSessionID.set(text);
- gDebugInfo["SessionID"] = text;
-
- text = LLUserAuth::getInstance()->getResponse("secure_session_id");
- if(!text.empty()) gAgent.mSecureSessionID.set(text);
-
- text = LLUserAuth::getInstance()->getResponse("first_name");
- if(!text.empty())
+ if(reason_response == "update"
+ || reason_response == "optional")
{
- // Remove quotes from string. Login.cgi sends these to force
- // names that look like numbers into strings.
- firstname.assign(text);
- LLStringUtil::replaceChar(firstname, '"', ' ');
- LLStringUtil::trim(firstname);
- }
- text = LLUserAuth::getInstance()->getResponse("last_name");
- if(!text.empty()) lastname.assign(text);
- gSavedSettings.setString("FirstName", firstname);
- gSavedSettings.setString("LastName", lastname);
-
- if (gSavedSettings.getBOOL("RememberPassword"))
- {
- // Successful login means the password is valid, so save it.
- LLStartUp::savePasswordToDisk(password);
+ // In the case of a needed update, quit.
+ // Its either downloading or declined.
+ // If optional was skipped this case shouldn't
+ // be reached.
+ LLLoginInstance::getInstance()->disconnect();
+ LLAppViewer::instance()->forceQuit();
}
else
{
- // Don't leave password from previous session sitting around
- // during this login session.
- LLStartUp::deletePasswordFromDisk();
- }
-
- // this is their actual ability to access content
- text = LLUserAuth::getInstance()->getResponse("agent_access_max");
- if (!text.empty())
- {
- // agent_access can be 'A', 'M', and 'PG'.
- gAgent.setMaturity(text[0]);
- }
-
- // this is the value of their preference setting for that content
- // which will always be <= agent_access_max
- text = LLUserAuth::getInstance()->getResponse("agent_region_access");
- if (!text.empty())
- {
- int preferredMaturity = LLAgent::convertTextToMaturity(text[0]);
- gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
- }
- // During the AO transition, this flag will be true. Then the flag will
- // go away. After the AO transition, this code and all the code that
- // uses it can be deleted.
- text = LLUserAuth::getInstance()->getResponse("ao_transition");
- if (!text.empty())
- {
- if (text == "1")
- {
- gAgent.setAOTransition();
- }
- }
-
- text = LLUserAuth::getInstance()->getResponse("start_location");
- if(!text.empty()) agent_start_location.assign(text);
- text = LLUserAuth::getInstance()->getResponse("circuit_code");
- if(!text.empty())
- {
- gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10);
- }
- std::string sim_ip_str = LLUserAuth::getInstance()->getResponse("sim_ip");
- std::string sim_port_str = LLUserAuth::getInstance()->getResponse("sim_port");
- if(!sim_ip_str.empty() && !sim_port_str.empty())
- {
- U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10);
- first_sim.set(sim_ip_str, sim_port);
- if (first_sim.isOk())
- {
- gMessageSystem->enableCircuit(first_sim, TRUE);
- }
- }
- std::string region_x_str = LLUserAuth::getInstance()->getResponse("region_x");
- std::string region_y_str = LLUserAuth::getInstance()->getResponse("region_y");
- if(!region_x_str.empty() && !region_y_str.empty())
- {
- U32 region_x = strtoul(region_x_str.c_str(), NULL, 10);
- U32 region_y = strtoul(region_y_str.c_str(), NULL, 10);
- first_sim_handle = to_region_handle(region_x, region_y);
- }
-
- const std::string look_at_str = LLUserAuth::getInstance()->getResponse("look_at");
- if (!look_at_str.empty())
- {
- size_t len = look_at_str.size();
- LLMemoryStream mstr((U8*)look_at_str.c_str(), len);
- LLSD sd = LLSDSerialize::fromNotation(mstr, len);
- agent_start_look_at = ll_vector3_from_sd(sd);
- }
-
- text = LLUserAuth::getInstance()->getResponse("seed_capability");
- if (!text.empty()) first_sim_seed_cap = text;
-
- text = LLUserAuth::getInstance()->getResponse("seconds_since_epoch");
- if(!text.empty())
- {
- U32 server_utc_time = strtoul(text.c_str(), NULL, 10);
- if(server_utc_time)
- {
- time_t now = time(NULL);
- gUTCOffset = (server_utc_time - now);
- }
- }
-
- std::string home_location = LLUserAuth::getInstance()->getResponse("home");
- if(!home_location.empty())
- {
- size_t len = home_location.size();
- LLMemoryStream mstr((U8*)home_location.c_str(), len);
- LLSD sd = LLSDSerialize::fromNotation(mstr, len);
- S32 region_x = sd["region_handle"][0].asInteger();
- S32 region_y = sd["region_handle"][1].asInteger();
- U64 region_handle = to_region_handle(region_x, region_y);
- LLVector3 position = ll_vector3_from_sd(sd["position"]);
- gAgent.setHomePosRegion(region_handle, position);
- }
-
- gAgent.mMOTD.assign(LLUserAuth::getInstance()->getResponse("message"));
- LLUserAuth::options_t options;
- if(LLUserAuth::getInstance()->getOptions("inventory-root", options))
- {
- LLUserAuth::response_t::iterator it;
- it = options[0].find("folder_id");
- if(it != options[0].end())
- {
- gInventory.setRootFolderID( LLUUID( (*it).second ) );
- }
- }
-
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("login-flags", options))
- {
- LLUserAuth::response_t::iterator it;
- LLUserAuth::response_t::iterator no_flag = options[0].end();
- it = options[0].find("ever_logged_in");
- if(it != no_flag)
- {
- if((*it).second == "N") gAgent.setFirstLogin(TRUE);
- else gAgent.setFirstLogin(FALSE);
- }
- it = options[0].find("stipend_since_login");
- if(it != no_flag)
- {
- if((*it).second == "Y") stipend_since_login = true;
- }
- it = options[0].find("gendered");
- if(it != no_flag)
- {
- if((*it).second == "Y") gAgent.setGenderChosen(TRUE);
- }
- it = options[0].find("daylight_savings");
- if(it != no_flag)
- {
- if((*it).second == "Y") gPacificDaylightTime = TRUE;
- else gPacificDaylightTime = FALSE;
- }
+ transitionBackToLoginPanel = true;
//setup map of datetime strings to codes and slt & local time offset from utc
LLStringOps::setupDatetimeInfo (gPacificDaylightTime);
}
- options.clear();
- if (LLUserAuth::getInstance()->getOptions("initial-outfit", options)
- && !options.empty())
- {
- LLUserAuth::response_t::iterator it;
- LLUserAuth::response_t::iterator it_end = options[0].end();
- it = options[0].find("folder_name");
- if(it != it_end)
- {
- // Initial outfit is a folder in your inventory,
- // must be an exact folder-name match.
- sInitialOutfit = (*it).second;
- }
- it = options[0].find("gender");
- if (it != it_end)
- {
- sInitialOutfitGender = (*it).second;
- }
- }
-
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("global-textures", options))
- {
- // Extract sun and moon texture IDs. These are used
- // in the LLVOSky constructor, but I can't figure out
- // how to pass them in. JC
- LLUserAuth::response_t::iterator it;
- LLUserAuth::response_t::iterator no_texture = options[0].end();
- it = options[0].find("sun_texture_id");
- if(it != no_texture)
- {
- gSunTextureID.set((*it).second);
- }
- it = options[0].find("moon_texture_id");
- if(it != no_texture)
- {
- gMoonTextureID.set((*it).second);
- }
- it = options[0].find("cloud_texture_id");
- if(it != no_texture)
- {
- gCloudTextureID.set((*it).second);
- }
- }
-
-
- // JC: gesture loading done below, when we have an asset system
- // in place. Don't delete/clear user_credentials until then.
-
- if(gAgentID.notNull()
- && gAgentSessionID.notNull()
- && gMessageSystem->mOurCircuitCode
- && first_sim.isOk()
- && gInventory.getRootFolderID().notNull())
+ }
+ else if(LLLoginInstance::getInstance()->authSuccess())
+ {
+ if(process_login_success_response())
{
- LLStartUp::setStartupState( STATE_WORLD_INIT );
+ // Pass the user information to the voice chat server interface.
+ gVoiceClient->userAuthorized(gFirstname, gLastname, gAgentID);
+ LLStartUp::setStartupState( STATE_WORLD_INIT);
}
else
{
- if (gNoRender)
- {
- LL_WARNS("AppInit") << "Bad login - missing return values" << LL_ENDL;
- LL_WARNS("AppInit") << emsg << LL_ENDL;
- exit(0);
- }
- // Bounce back to the login screen.
- LLSD args;
- args["ERROR_MESSAGE"] = emsg.str();
- LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done);
- reset_login();
- gSavedSettings.setBOOL("AutoLogin", FALSE);
- show_connect_box = true;
+ transitionBackToLoginPanel = false;
}
-
- // Pass the user information to the voice chat server interface.
- gVoiceClient->userAuthorized(firstname, lastname, gAgentID);
}
- else // if(successful_login)
+ else
+ {
+ // Still waiting for response.
+ // *TODO:Mani - Actually check for login progress.
+ // If we get here we have gotten past the potential stall
+ // in curl, so take "may appear frozen" out of progress bar. JC
+ auth_desc = LLTrans::getString("LoginInProgressNoFrozen");
+ set_startup_status(progress, auth_desc, auth_message);
+ }
+
+ if(transitionBackToLoginPanel)
{
if (gNoRender)
{
@@ -1642,11 +1146,12 @@ bool idle_startup()
LL_WARNS("AppInit") << emsg << LL_ENDL;
exit(0);
}
+
// Bounce back to the login screen.
LLSD args;
args["ERROR_MESSAGE"] = emsg.str();
LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done);
- reset_login();
+ reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
gSavedSettings.setBOOL("AutoLogin", FALSE);
show_connect_box = true;
}
@@ -1709,14 +1214,14 @@ bool idle_startup()
// This is necessary because creating objects before this is set will result in a
// bad mPositionAgent cache.
- gAgent.initOriginGlobal(from_region_handle(first_sim_handle));
+ gAgent.initOriginGlobal(from_region_handle(gFirstSimHandle));
- LLWorld::getInstance()->addRegion(first_sim_handle, first_sim);
+ LLWorld::getInstance()->addRegion(gFirstSimHandle, gFirstSim);
- LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle);
+ LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(gFirstSimHandle);
LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
- regionp->setSeedCapability(first_sim_seed_cap);
+ regionp->setSeedCapability(gFirstSimSeedCap);
LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;
// Set agent's initial region to be the one we just created.
@@ -1855,7 +1360,7 @@ bool idle_startup()
// the coordinates handed to us to fit in the local region.
gAgent.setPositionAgent(agent_start_position_region);
- gAgent.resetAxes(agent_start_look_at);
+ gAgent.resetAxes(gAgentStartLookAt);
gAgent.stopCameraAnimation();
gAgent.resetCamera();
@@ -1894,18 +1399,18 @@ bool idle_startup()
LL_WARNS("AppInit") << "Attempting to connect to simulator with a zero circuit code!" << LL_ENDL;
}
- gUseCircuitCallbackCalled = FALSE;
+ gUseCircuitCallbackCalled = false;
- msg->enableCircuit(first_sim, TRUE);
+ msg->enableCircuit(gFirstSim, TRUE);
// now, use the circuit info to tell simulator about us!
- LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << first_sim << " with code " << msg->mOurCircuitCode << LL_ENDL;
+ LL_INFOS("AppInit") << "viewer: UserLoginLocationReply() Enabling " << gFirstSim << " with code " << msg->mOurCircuitCode << LL_ENDL;
msg->newMessageFast(_PREHASH_UseCircuitCode);
msg->nextBlockFast(_PREHASH_CircuitCode);
msg->addU32Fast(_PREHASH_Code, msg->mOurCircuitCode);
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
msg->sendReliable(
- first_sim,
+ gFirstSim,
MAX_TIMEOUT_COUNT,
FALSE,
TIMEOUT_SECONDS,
@@ -2016,105 +1521,99 @@ bool idle_startup()
LLAgentLanguage::update();
// unpack thin inventory
- LLUserAuth::options_t options;
- options.clear();
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
//bool dump_buffer = false;
-
- if(LLUserAuth::getInstance()->getOptions("inventory-lib-root", options)
- && !options.empty())
+
+ LLSD inv_lib_root = response["inventory-lib-root"];
+ if(inv_lib_root.isDefined())
{
// should only be one
- LLUserAuth::response_t::iterator it;
- it = options[0].find("folder_id");
- if(it != options[0].end())
+ LLSD id = inv_lib_root[0]["folder_id"];
+ if(id.isDefined())
{
- gInventory.setLibraryRootFolderID( LLUUID( (*it).second ) );
+ gInventory.setLibraryRootFolderID(id.asUUID());
}
}
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("inventory-lib-owner", options)
- && !options.empty())
+
+ LLSD inv_lib_owner = response["inventory-lib-owner"];
+ if(inv_lib_owner.isDefined())
{
// should only be one
- LLUserAuth::response_t::iterator it;
- it = options[0].find("agent_id");
- if(it != options[0].end())
+ LLSD id = inv_lib_owner[0]["agent_id"];
+ if(id.isDefined())
{
- gInventory.setLibraryOwnerID( LLUUID( (*it).second ) );
+ gInventory.setLibraryOwnerID( LLUUID(id.asUUID()));
}
}
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("inventory-skel-lib", options)
- && gInventory.getLibraryOwnerID().notNull())
+
+ LLSD inv_skel_lib = response["inventory-skel-lib"];
+ if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
{
- if(!gInventory.loadSkeleton(options, gInventory.getLibraryOwnerID()))
+ if(!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
}
}
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("inventory-skeleton", options))
+
+ LLSD inv_skeleton = response["inventory-skeleton"];
+ if(inv_skeleton.isDefined())
{
- if(!gInventory.loadSkeleton(options, gAgent.getID()))
+ if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
{
LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
}
}
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("buddy-list", options))
+ LLSD buddy_list = response["buddy-list"];
+ if(buddy_list.isDefined())
{
- LLUserAuth::options_t::iterator it = options.begin();
- LLUserAuth::options_t::iterator end = options.end();
LLAvatarTracker::buddy_map_t list;
LLUUID agent_id;
S32 has_rights = 0, given_rights = 0;
- for (; it != end; ++it)
+ for(LLSD::array_const_iterator it = buddy_list.beginArray(),
+ end = buddy_list.endArray(); it != end; ++it)
{
- LLUserAuth::response_t::const_iterator option_it;
- option_it = (*it).find("buddy_id");
- if(option_it != (*it).end())
+ LLSD buddy_id = (*it)["buddy_id"];
+ if(buddy_id.isDefined())
{
- agent_id.set((*option_it).second);
+ agent_id = buddy_id.asUUID();
}
- option_it = (*it).find("buddy_rights_has");
- if(option_it != (*it).end())
+
+ LLSD buddy_rights_has = (*it)["buddy_rights_has"];
+ if(buddy_rights_has.isDefined())
{
- has_rights = atoi((*option_it).second.c_str());
+ has_rights = buddy_rights_has.asInteger();
}
- option_it = (*it).find("buddy_rights_given");
- if(option_it != (*it).end())
+
+ LLSD buddy_rights_given = (*it)["buddy_rights_given"];
+ if(buddy_rights_given.isDefined())
{
- given_rights = atoi((*option_it).second.c_str());
+ given_rights = buddy_rights_given.asInteger();
}
+
list[agent_id] = new LLRelationship(given_rights, has_rights, false);
}
LLAvatarTracker::instance().addBuddyList(list);
}
- options.clear();
-
bool show_hud = false;
- if(LLUserAuth::getInstance()->getOptions("tutorial_setting", options))
+ LLSD tutorial_setting = response["tutorial_setting"];
+ if(tutorial_setting.isDefined())
{
- LLUserAuth::options_t::iterator it = options.begin();
- LLUserAuth::options_t::iterator end = options.end();
- for (; it != end; ++it)
+ for(LLSD::array_const_iterator it = tutorial_setting.beginArray(),
+ end = tutorial_setting.endArray(); it != end; ++it)
{
- LLUserAuth::response_t::const_iterator option_it;
- option_it = (*it).find("tutorial_url");
- if(option_it != (*it).end())
+ LLSD tutorial_url = (*it)["tutorial_url"];
+ if(tutorial_url.isDefined())
{
// Tutorial floater will append language code
- gSavedSettings.setString("TutorialURL", option_it->second);
+ gSavedSettings.setString("TutorialURL", tutorial_url.asString());
}
- option_it = (*it).find("use_tutorial");
- if(option_it != (*it).end())
+
+ LLSD use_tutorial = (*it)["use_tutorial"];
+ if(use_tutorial.asString() == "true")
{
- if (option_it->second == "true")
- {
- show_hud = true;
- }
+ show_hud = true;
}
}
}
@@ -2126,19 +1625,22 @@ bool idle_startup()
LLFloaterReg::showInstance("hud", LLSD(), FALSE);
}
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("event_categories", options))
+ LLSD event_categories = response["event_categories"];
+ if(event_categories.isDefined())
{
- LLEventInfo::loadCategories(options);
+ LLEventInfo::loadCategories(event_categories);
}
- if(LLUserAuth::getInstance()->getOptions("event_notifications", options))
+
+ LLSD event_notifications = response["event_notifications"];
+ if(event_notifications.isDefined())
{
- gEventNotifier.load(options);
+ gEventNotifier.load(event_notifications);
}
- options.clear();
- if(LLUserAuth::getInstance()->getOptions("classified_categories", options))
+
+ LLSD classified_categories = response["classified_categories"];
+ if(classified_categories.isDefined())
{
- LLClassifiedInfo::loadCategories(options);
+ LLClassifiedInfo::loadCategories(classified_categories);
}
@@ -2201,7 +1703,7 @@ bool idle_startup()
// This is actually a pessimistic computation, because TCP may not have enough
// time to ramp up on the (small) default inventory file to truly measure max
// bandwidth. JC
- F64 rate_bps = LLUserAuth::getInstance()->getLastTransferRateBPS();
+ F64 rate_bps = LLLoginInstance::getInstance()->getLastTransferRateBPS();
const F32 FAST_RATE_BPS = 600.f * 1024.f;
const F32 FASTER_RATE_BPS = 750.f * 1024.f;
F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
@@ -2249,34 +1751,20 @@ bool idle_startup()
// JC: Initialize "active" gestures. This may also trigger
// many gesture downloads, if this is the user's first
// time on this machine or -purge has been run.
- LLUserAuth::options_t gesture_options;
- if (LLUserAuth::getInstance()->getOptions("gestures", gesture_options))
+ LLSD gesture_options
+ = LLLoginInstance::getInstance()->getResponse("gestures");
+ if (gesture_options.isDefined())
{
LL_DEBUGS("AppInit") << "Gesture Manager loading " << gesture_options.size()
<< LL_ENDL;
std::vector<LLUUID> item_ids;
- LLUserAuth::options_t::iterator resp_it;
- for (resp_it = gesture_options.begin();
- resp_it != gesture_options.end();
- ++resp_it)
+ for(LLSD::array_const_iterator resp_it = gesture_options.beginArray(),
+ end = gesture_options.endArray(); resp_it != end; ++resp_it)
{
- const LLUserAuth::response_t& response = *resp_it;
- LLUUID item_id;
- LLUUID asset_id;
- LLUserAuth::response_t::const_iterator option_it;
-
- option_it = response.find("item_id");
- if (option_it != response.end())
- {
- const std::string& uuid_string = (*option_it).second;
- item_id.set(uuid_string);
- }
- option_it = response.find("asset_id");
- if (option_it != response.end())
- {
- const std::string& uuid_string = (*option_it).second;
- asset_id.set(uuid_string);
- }
+ // If the id is not specifed in the LLSD,
+ // the LLSD operator[]() will return a null LLUUID.
+ LLUUID item_id = (*resp_it)["item_id"];
+ LLUUID asset_id = (*resp_it)["asset_id"];
if (item_id.notNull() && asset_id.notNull())
{
@@ -2332,8 +1820,8 @@ bool idle_startup()
if (!gAgent.isFirstLogin())
{
bool url_ok = LLURLSimString::sInstance.parse();
- if ((url_ok && agent_start_location == "url") ||
- (!url_ok && ((agent_start_location == gSavedSettings.getString("LoginLocation")))))
+ if ((url_ok && gAgentStartLocation == "url") ||
+ (!url_ok && ((gAgentStartLocation == gSavedSettings.getString("LoginLocation")))))
{
// Start location is OK
// Disabled code to restore camera location and focus if logging in to default location
@@ -2546,8 +2034,10 @@ bool idle_startup()
// then the data is cached for the viewer's lifetime)
LLProductInfoRequestManager::instance();
+ // *FIX:Mani - What do I do here?
+ // Need we really clear the Auth response data?
// Clean up the userauth stuff.
- LLUserAuth::getInstance()->reset();
+ // LLUserAuth::getInstance()->reset();
LLStartUp::setStartupState( STATE_STARTED );
@@ -2837,230 +2327,6 @@ bool login_alert_status(const LLSD& notification, const LLSD& response)
return false;
}
-void update_app(BOOL mandatory, const std::string& auth_msg)
-{
- // store off config state, as we might quit soon
- gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
- LLUIColorTable::instance().saveUserSettings();
- std::ostringstream message;
-
- std::string msg;
- if (!auth_msg.empty())
- {
- msg = "("+ auth_msg + ") \n";
- }
-
- LLSD args;
- args["MESSAGE"] = msg;
-
- LLSD payload;
- payload["mandatory"] = mandatory;
-
-/*
- We're constructing one of the following 6 strings here:
- "DownloadWindowsMandatory"
- "DownloadWindowsReleaseForDownload"
- "DownloadWindows"
- "DownloadMacMandatory"
- "DownloadMacReleaseForDownload"
- "DownloadMac"
-
- I've called them out explicitly in this comment so that they can be grepped for.
-
- Also, we assume that if we're not Windows we're Mac. If we ever intend to support
- Linux with autoupdate, this should be an explicit #elif LL_DARWIN, but
- we'd rather deliver the wrong message than no message, so until Linux is supported
- we'll leave it alone.
- */
- std::string notification_name = "Download";
-
-#if LL_WINDOWS
- notification_name += "Windows";
-#elif LL_DARWIN
- notification_name += "Mac";
-#else
- notification_name += "Linux";
-#endif
-
- if (mandatory)
- {
- notification_name += "Mandatory";
- }
- else
- {
-#if LL_RELEASE_FOR_DOWNLOAD
- notification_name += "ReleaseForDownload";
-#endif
- }
-
- LLNotifications::instance().add(notification_name, args, payload, update_dialog_callback);
-}
-
-bool update_dialog_callback(const LLSD& notification, const LLSD& response)
-{
- S32 option = LLNotification::getSelectedOption(notification, response);
- std::string update_exe_path;
- bool mandatory = notification["payload"]["mandatory"].asBoolean();
-
-#if !LL_RELEASE_FOR_DOWNLOAD
- if (option == 2)
- {
- LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
- return false;
- }
-#endif
-
- if (option == 1)
- {
- // ...user doesn't want to do it
- if (mandatory)
- {
- LLAppViewer::instance()->forceQuit();
- // Bump them back to the login screen.
- //reset_login();
- }
- else
- {
- LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
- }
- return false;
- }
-
- // if a sim name was passed in via command line parameter (typically through a SLURL)
- if ( LLURLSimString::sInstance.mSimString.length() )
- {
- // record the location to start at next time
- gSavedSettings.setString("NextLoginLocation", LLURLSimString::sInstance.mSimString);
- }
-
- LLSD query_map = LLSD::emptyMap();
- // *TODO place os string in a global constant
-#if LL_WINDOWS
- query_map["os"] = "win";
-#elif LL_DARWIN
- query_map["os"] = "mac";
-#elif LL_LINUX
- query_map["os"] = "lnx";
-#elif LL_SOLARIS
- query_map["os"] = "sol";
-#endif
- // *TODO change userserver to be grid on both viewer and sim, since
- // userserver no longer exists.
- query_map["userserver"] = LLViewerLogin::getInstance()->getGridLabel();
- query_map["channel"] = gSavedSettings.getString("VersionChannelName");
- // *TODO constantize this guy
- // *NOTE: This URL is also used in win_setup/lldownloader.cpp
- LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
-
- if(LLAppViewer::sUpdaterInfo)
- {
- delete LLAppViewer::sUpdaterInfo ;
- }
- LLAppViewer::sUpdaterInfo = new LLAppViewer::LLUpdaterInfo() ;
-
-#if LL_WINDOWS
- LLAppViewer::sUpdaterInfo->mUpdateExePath = gDirUtilp->getTempFilename();
- if (LLAppViewer::sUpdaterInfo->mUpdateExePath.empty())
- {
- delete LLAppViewer::sUpdaterInfo ;
- LLAppViewer::sUpdaterInfo = NULL ;
-
- // We're hosed, bail
- LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL;
- LLAppViewer::instance()->forceQuit();
- return false;
- }
-
- LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe";
-
- std::string updater_source = gDirUtilp->getAppRODataDir();
- updater_source += gDirUtilp->getDirDelimiter();
- updater_source += "updater.exe";
-
- LL_DEBUGS("AppInit") << "Calling CopyFile source: " << updater_source
- << " dest: " << LLAppViewer::sUpdaterInfo->mUpdateExePath
- << LL_ENDL;
-
-
- if (!CopyFileA(updater_source.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), FALSE))
- {
- delete LLAppViewer::sUpdaterInfo ;
- LLAppViewer::sUpdaterInfo = NULL ;
-
- LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
- LLAppViewer::instance()->forceQuit();
- return false;
- }
-
- LLAppViewer::sUpdaterInfo->mParams << "-url \"" << update_url.asString() << "\"";
-
- LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << " " << LLAppViewer::sUpdaterInfo->mParams.str() << LL_ENDL;
-
- //Explicitly remove the marker file, otherwise we pass the lock onto the child process and things get weird.
- LLAppViewer::instance()->removeMarkerFile(); // In case updater fails
-
-#elif LL_DARWIN
- LLAppViewer::sUpdaterInfo->mUpdateExePath = "'";
- LLAppViewer::sUpdaterInfo->mUpdateExePath += gDirUtilp->getAppRODataDir();
- LLAppViewer::sUpdaterInfo->mUpdateExePath += "/mac-updater.app/Contents/MacOS/mac-updater' -url \"";
- LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString();
- LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \"";
- LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle();
- LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &";
-
- LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL;
-
- // Run the auto-updater.
- system(LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str()); /* Flawfinder: ignore */
-
-#elif (LL_LINUX || LL_SOLARIS) && LL_GTK
- // we tell the updater where to find the xml containing string
- // translations which it can use for its own UI
- std::string xml_strings_file = "strings.xml";
- std::vector<std::string> xui_path_vec = LLUI::getXUIPaths();
- std::string xml_search_paths;
- std::vector<std::string>::const_iterator iter;
- // build comma-delimited list of xml paths to pass to updater
- for (iter = xui_path_vec.begin(); iter != xui_path_vec.end(); )
- {
- std::string this_skin_dir = gDirUtilp->getDefaultSkinDir()
- + gDirUtilp->getDirDelimiter()
- + (*iter);
- llinfos << "Got a XUI path: " << this_skin_dir << llendl;
- xml_search_paths.append(this_skin_dir);
- ++iter;
- if (iter != xui_path_vec.end())
- xml_search_paths.append(","); // comma-delimit
- }
- // build the overall command-line to run the updater correctly
- update_exe_path =
- gDirUtilp->getExecutableDir() + "/" + "linux-updater.bin" +
- " --url \"" + update_url.asString() + "\"" +
- " --name \"" + LLAppViewer::instance()->getSecondLifeTitle() + "\"" +
- " --dest \"" + gDirUtilp->getAppRODataDir() + "\"" +
- " --stringsdir \"" + xml_search_paths + "\"" +
- " --stringsfile \"" + xml_strings_file + "\"";
-
- LL_INFOS("AppInit") << "Calling updater: "
- << update_exe_path << LL_ENDL;
-
- // *TODO: we could use the gdk equivilant to ensure the updater
- // gets started on the same screen.
- GError *error = NULL;
- if (!g_spawn_command_line_async(update_exe_path.c_str(), &error))
- {
- llerrs << "Failed to launch updater: "
- << error->message
- << llendl;
- }
- if (error)
- g_error_free(error);
-#else
- OSMessageBox(LLTrans::getString("MBNoAutoUpdate"), LLStringUtil::null, OSMB_OK);
-#endif
- LLAppViewer::instance()->forceQuit();
- return false;
-}
void use_circuit_callback(void**, S32 result)
{
@@ -3416,11 +2682,7 @@ std::string LLStartUp::startupStateToString(EStartupState state)
RTNENUM( STATE_LOGIN_SHOW );
RTNENUM( STATE_LOGIN_WAIT );
RTNENUM( STATE_LOGIN_CLEANUP );
- RTNENUM( STATE_UPDATE_CHECK );
RTNENUM( STATE_LOGIN_AUTH_INIT );
- RTNENUM( STATE_LOGIN_AUTHENTICATE );
- RTNENUM( STATE_LOGIN_NO_DATA_YET );
- RTNENUM( STATE_LOGIN_DOWNLOADING );
RTNENUM( STATE_LOGIN_PROCESS_RESPONSE );
RTNENUM( STATE_WORLD_INIT );
RTNENUM( STATE_SEED_GRANTED_WAIT );
@@ -3440,14 +2702,17 @@ std::string LLStartUp::startupStateToString(EStartupState state)
#undef RTNENUM
}
-
// static
void LLStartUp::setStartupState( EStartupState state )
{
LL_INFOS("AppInit") << "Startup state changing from " <<
- startupStateToString(gStartupState) << " to " <<
+ getStartupStateString() << " to " <<
startupStateToString(state) << LL_ENDL;
gStartupState = state;
+ LLSD stateInfo;
+ stateInfo["str"] = getStartupStateString();
+ stateInfo["enum"] = state;
+ sStartupStateWatcher.post(stateInfo);
}
@@ -3561,3 +2826,252 @@ void apply_udp_blacklist(const std::string& csv)
}
+bool process_login_success_response()
+{
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
+
+ std::string text(response["udp_blacklist"]);
+ if(!text.empty())
+ {
+ apply_udp_blacklist(text);
+ }
+
+ // unpack login data needed by the application
+ text = response["agent_id"].asString();
+ if(!text.empty()) gAgentID.set(text);
+ gDebugInfo["AgentID"] = text;
+
+ text = response["session_id"].asString();
+ if(!text.empty()) gAgentSessionID.set(text);
+ gDebugInfo["SessionID"] = text;
+
+ text = response["secure_session_id"].asString();
+ if(!text.empty()) gAgent.mSecureSessionID.set(text);
+
+ text = response["first_name"].asString();
+ if(!text.empty())
+ {
+ // Remove quotes from string. Login.cgi sends these to force
+ // names that look like numbers into strings.
+ gFirstname.assign(text);
+ LLStringUtil::replaceChar(gFirstname, '"', ' ');
+ LLStringUtil::trim(gFirstname);
+ }
+ text = response["last_name"].asString();
+ if(!text.empty())
+ {
+ gLastname.assign(text);
+ }
+ gSavedSettings.setString("FirstName", gFirstname);
+ gSavedSettings.setString("LastName", gLastname);
+
+ if (gSavedSettings.getBOOL("RememberPassword"))
+ {
+ // Successful login means the password is valid, so save it.
+ LLStartUp::savePasswordToDisk(gPassword);
+ }
+ else
+ {
+ // Don't leave password from previous session sitting around
+ // during this login session.
+ LLStartUp::deletePasswordFromDisk();
+ }
+
+ // this is their actual ability to access content
+ text = response["agent_access_max"].asString();
+ if (!text.empty())
+ {
+ // agent_access can be 'A', 'M', and 'PG'.
+ gAgent.setMaturity(text[0]);
+ }
+
+ // this is the value of their preference setting for that content
+ // which will always be <= agent_access_max
+ text = response["agent_region_access"].asString();
+ if (!text.empty())
+ {
+ int preferredMaturity = LLAgent::convertTextToMaturity(text[0]);
+ gSavedSettings.setU32("PreferredMaturity", preferredMaturity);
+ }
+ // During the AO transition, this flag will be true. Then the flag will
+ // go away. After the AO transition, this code and all the code that
+ // uses it can be deleted.
+ text = response["ao_transition"].asString();
+ if (!text.empty())
+ {
+ if (text == "1")
+ {
+ gAgent.setAOTransition();
+ }
+ }
+
+ text = response["start_location"].asString();
+ if(!text.empty())
+ {
+ gAgentStartLocation.assign(text);
+ }
+
+ text = response["circuit_code"].asString();
+ if(!text.empty())
+ {
+ gMessageSystem->mOurCircuitCode = strtoul(text.c_str(), NULL, 10);
+ }
+ std::string sim_ip_str = response["sim_ip"];
+ std::string sim_port_str = response["sim_port"];
+ if(!sim_ip_str.empty() && !sim_port_str.empty())
+ {
+ U32 sim_port = strtoul(sim_port_str.c_str(), NULL, 10);
+ gFirstSim.set(sim_ip_str, sim_port);
+ if (gFirstSim.isOk())
+ {
+ gMessageSystem->enableCircuit(gFirstSim, TRUE);
+ }
+ }
+ std::string region_x_str = response["region_x"];
+ std::string region_y_str = response["region_y"];
+ if(!region_x_str.empty() && !region_y_str.empty())
+ {
+ U32 region_x = strtoul(region_x_str.c_str(), NULL, 10);
+ U32 region_y = strtoul(region_y_str.c_str(), NULL, 10);
+ gFirstSimHandle = to_region_handle(region_x, region_y);
+ }
+
+ const std::string look_at_str = response["look_at"];
+ if (!look_at_str.empty())
+ {
+ size_t len = look_at_str.size();
+ LLMemoryStream mstr((U8*)look_at_str.c_str(), len);
+ LLSD sd = LLSDSerialize::fromNotation(mstr, len);
+ gAgentStartLookAt = ll_vector3_from_sd(sd);
+ }
+
+ text = response["seed_capability"].asString();
+ if (!text.empty()) gFirstSimSeedCap = text;
+
+ text = response["seconds_since_epoch"].asString();
+ if(!text.empty())
+ {
+ U32 server_utc_time = strtoul(text.c_str(), NULL, 10);
+ if(server_utc_time)
+ {
+ time_t now = time(NULL);
+ gUTCOffset = (server_utc_time - now);
+ }
+ }
+
+ std::string home_location = response["home"];
+ if(!home_location.empty())
+ {
+ size_t len = home_location.size();
+ LLMemoryStream mstr((U8*)home_location.c_str(), len);
+ LLSD sd = LLSDSerialize::fromNotation(mstr, len);
+ S32 region_x = sd["region_handle"][0].asInteger();
+ S32 region_y = sd["region_handle"][1].asInteger();
+ U64 region_handle = to_region_handle(region_x, region_y);
+ LLVector3 position = ll_vector3_from_sd(sd["position"]);
+ gAgent.setHomePosRegion(region_handle, position);
+ }
+
+ gAgent.mMOTD.assign(response["message"]);
+
+ // Options...
+ // Each 'option' is an array of submaps.
+ // It appears that we only ever use the first element of the array.
+ LLUUID inv_root_folder_id = response["inventory-root"][0]["folder_id"];
+ if(inv_root_folder_id.notNull())
+ {
+ gInventory.setRootFolderID(inv_root_folder_id);
+ //gInventory.mock(gAgent.getInventoryRootID());
+ }
+
+ LLSD login_flags = response["login-flags"][0];
+ if(login_flags.size())
+ {
+ std::string flag = login_flags["ever_logged_in"];
+ if(!flag.empty())
+ {
+ gAgent.setFirstLogin((flag == "N") ? TRUE : FALSE);
+ }
+
+ /* Flag is currently ignored by the viewer.
+ flag = login_flags["stipend_since_login"];
+ if(flag == "Y")
+ {
+ stipend_since_login = true;
+ }
+ */
+
+ flag = login_flags["gendered"].asString();
+ if(flag == "Y")
+ {
+ gAgent.setGenderChosen(TRUE);
+ }
+
+ flag = login_flags["daylight_savings"].asString();
+ if(flag == "Y")
+ {
+ gPacificDaylightTime = (flag == "Y") ? TRUE : FALSE;
+ }
+
+ //setup map of datetime strings to codes and slt & local time offset from utc
+ LLStringOps::setupDatetimeInfo (gPacificDaylightTime);
+ }
+
+ LLSD initial_outfit = response["initial-outfit"][0];
+ if(initial_outfit.size())
+ {
+ std::string flag = initial_outfit["folder_name"];
+ if(!flag.empty())
+ {
+ // Initial outfit is a folder in your inventory,
+ // must be an exact folder-name match.
+ sInitialOutfit = flag;
+ }
+
+ flag = initial_outfit["gender"].asString();
+ if(!flag.empty())
+ {
+ sInitialOutfitGender = flag;
+ }
+ }
+
+ LLSD global_textures = response["global-textures"][0];
+ if(global_textures.size())
+ {
+ // Extract sun and moon texture IDs. These are used
+ // in the LLVOSky constructor, but I can't figure out
+ // how to pass them in. JC
+ LLUUID id = global_textures["sun_texture_id"];
+ if(id.notNull())
+ {
+ gSunTextureID = id;
+ }
+
+ id = global_textures["moon_texture_id"];
+ if(id.notNull())
+ {
+ gMoonTextureID = id;
+ }
+
+ id = global_textures["cloud_texture_id"];
+ if(id.notNull())
+ {
+ gCloudTextureID = id;
+ }
+ }
+
+
+ bool success = false;
+ // JC: gesture loading done below, when we have an asset system
+ // in place. Don't delete/clear user_credentials until then.
+ if(gAgentID.notNull()
+ && gAgentSessionID.notNull()
+ && gMessageSystem->mOurCircuitCode
+ && gFirstSim.isOk()
+ && gInventory.getRootFolderID().notNull())
+ {
+ success = true;
+ }
+
+ return success;
+}
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 4532c5e586..7f869d014f 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -50,11 +50,7 @@ typedef enum {
STATE_LOGIN_SHOW, // Show login screen
STATE_LOGIN_WAIT, // Wait for user input at login screen
STATE_LOGIN_CLEANUP, // Get rid of login screen and start login
- STATE_UPDATE_CHECK, // Wait for user at a dialog box (updates, term-of-service, etc)
STATE_LOGIN_AUTH_INIT, // Start login to SL servers
- STATE_LOGIN_AUTHENTICATE, // Do authentication voodoo
- STATE_LOGIN_NO_DATA_YET, // Waiting for authentication replies to start
- STATE_LOGIN_DOWNLOADING, // Waiting for authentication replies to download
STATE_LOGIN_PROCESS_RESPONSE, // Check authentication reply
STATE_WORLD_INIT, // Start building the world
STATE_MULTIMEDIA_INIT, // Init the rest of multimedia library
@@ -75,8 +71,6 @@ typedef enum {
// exported symbols
extern bool gAgentMovementCompleted;
extern LLPointer<LLViewerTexture> gStartTexture;
-extern std::string gInitialOutfit;
-extern std::string gInitialOutfitGender; // "male" or "female"
class LLStartUp
{
diff --git a/indra/newview/lluilistener.cpp b/indra/newview/lluilistener.cpp
new file mode 100644
index 0000000000..9c643e78de
--- /dev/null
+++ b/indra/newview/lluilistener.cpp
@@ -0,0 +1,50 @@
+/**
+ * @file lluilistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-08-18
+ * @brief Implementation for lluilistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "lluilistener.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "lluictrl.h"
+#include "llerror.h"
+
+LLUIListener::LLUIListener(const std::string& name):
+ LLDispatchListener(name, "op")
+{
+ add("call", &LLUIListener::call, LLSD().insert("function", LLSD()));
+}
+
+void LLUIListener::call(const LLSD& event) const
+{
+ LLUICtrl::commit_callback_t* func =
+ LLUICtrl::CommitCallbackRegistry::getValue(event["function"]);
+ if (! func)
+ {
+ // This API is intended for use by a script. It's a fire-and-forget
+ // API: we provide no reply. Therefore, a typo in the script will
+ // provide no feedback whatsoever to that script. To rub the coder's
+ // nose in such an error, crump rather than quietly ignoring it.
+ LL_ERRS("LLUIListener") << "function '" << event["function"] << "' not found" << LL_ENDL;
+ }
+ else
+ {
+ // Interestingly, view_listener_t::addMenu() (addCommit(),
+ // addEnable()) constructs a commit_callback_t callable that accepts
+ // two parameters but discards the first. Only the second is passed to
+ // handleEvent(). Therefore we feel completely safe passing NULL for
+ // the first parameter.
+ (*func)(NULL, event["parameter"]);
+ }
+}
diff --git a/indra/newview/lluilistener.h b/indra/newview/lluilistener.h
new file mode 100644
index 0000000000..ea904a99ff
--- /dev/null
+++ b/indra/newview/lluilistener.h
@@ -0,0 +1,29 @@
+/**
+ * @file lluilistener.h
+ * @author Nat Goodspeed
+ * @date 2009-08-18
+ * @brief Engage named functions as specified by XUI
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLUILISTENER_H)
+#define LL_LLUILISTENER_H
+
+#include "lleventdispatcher.h"
+#include <string>
+
+class LLSD;
+
+class LLUIListener: public LLDispatchListener
+{
+public:
+ LLUIListener(const std::string& name);
+
+private:
+ void call(const LLSD& event) const;
+};
+
+#endif /* ! defined(LL_LLUILISTENER_H) */
diff --git a/indra/newview/llviewercontrollistener.cpp b/indra/newview/llviewercontrollistener.cpp
new file mode 100644
index 0000000000..ecba1b8eb0
--- /dev/null
+++ b/indra/newview/llviewercontrollistener.cpp
@@ -0,0 +1,102 @@
+/**
+ * @file llviewercontrollistener.cpp
+ * @author Brad Kittenbrink
+ * @date 2009-07-09
+ * @brief Implementation for llviewercontrollistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewercontrollistener.h"
+
+#include "llviewercontrol.h"
+
+LLViewerControlListener gSavedSettingsListener;
+
+LLViewerControlListener::LLViewerControlListener()
+ : LLDispatchListener("LLViewerControl", "group")
+{
+ add("Global", boost::bind(&LLViewerControlListener::set, &gSavedSettings, _1));
+ add("PerAccount", boost::bind(&LLViewerControlListener::set, &gSavedPerAccountSettings, _1));
+ add("Warning", boost::bind(&LLViewerControlListener::set, &gWarningSettings, _1));
+ add("Crash", boost::bind(&LLViewerControlListener::set, &gCrashSettings, _1));
+
+#if 0
+ add(/*"toggleControl",*/ "Global", boost::bind(&LLViewerControlListener::toggleControl, &gSavedSettings, _1));
+ add(/*"toggleControl",*/ "PerAccount", boost::bind(&LLViewerControlListener::toggleControl, &gSavedPerAccountSettings, _1));
+ add(/*"toggleControl",*/ "Warning", boost::bind(&LLViewerControlListener::toggleControl, &gWarningSettings, _1));
+ add(/*"toggleControl",*/ "Crash", boost::bind(&LLViewerControlListener::toggleControl, &gCrashSettings, _1));
+
+ add(/*"setDefault",*/ "Global", boost::bind(&LLViewerControlListener::setDefault, &gSavedSettings, _1));
+ add(/*"setDefault",*/ "PerAccount", boost::bind(&LLViewerControlListener::setDefault, &gSavedPerAccountSettings, _1));
+ add(/*"setDefault",*/ "Warning", boost::bind(&LLViewerControlListener::setDefault, &gWarningSettings, _1));
+ add(/*"setDefault",*/ "Crash", boost::bind(&LLViewerControlListener::setDefault, &gCrashSettings, _1));
+#endif // 0
+}
+
+//static
+void LLViewerControlListener::set(LLControlGroup * controls, LLSD const & event_data)
+{
+ if(event_data.has("key"))
+ {
+ std::string key(event_data["key"]);
+
+ if(controls->controlExists(key))
+ {
+ controls->setUntypedValue(key, event_data["value"]);
+ }
+ else
+ {
+ llwarns << "requested unknown control: \"" << key << '\"' << llendl;
+ }
+ }
+}
+
+//static
+void LLViewerControlListener::toggleControl(LLControlGroup * controls, LLSD const & event_data)
+{
+ if(event_data.has("key"))
+ {
+ std::string key(event_data["key"]);
+
+ if(controls->controlExists(key))
+ {
+ LLControlVariable * control = controls->getControl(key);
+ if(control->isType(TYPE_BOOLEAN))
+ {
+ control->set(!control->get().asBoolean());
+ }
+ else
+ {
+ llwarns << "requested toggle of non-boolean control: \"" << key << "\", type is " << control->type() << llendl;
+ }
+ }
+ else
+ {
+ llwarns << "requested unknown control: \"" << key << '\"' << llendl;
+ }
+ }
+}
+
+//static
+void LLViewerControlListener::setDefault(LLControlGroup * controls, LLSD const & event_data)
+{
+ if(event_data.has("key"))
+ {
+ std::string key(event_data["key"]);
+
+ if(controls->controlExists(key))
+ {
+ LLControlVariable * control = controls->getControl(key);
+ control->resetToDefault();
+ }
+ else
+ {
+ llwarns << "requested unknown control: \"" << key << '\"' << llendl;
+ }
+ }
+}
diff --git a/indra/newview/llviewercontrollistener.h b/indra/newview/llviewercontrollistener.h
new file mode 100644
index 0000000000..cacf97e908
--- /dev/null
+++ b/indra/newview/llviewercontrollistener.h
@@ -0,0 +1,33 @@
+/**
+ * @file llviewercontrollistener.h
+ * @author Brad Kittenbrink
+ * @date 2009-07-09
+ * @brief Event API for subset of LLViewerControl methods
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERCONTROLLISTENER_H
+#define LL_LLVIEWERCONTROLLISTENER_H
+
+#include "lleventdispatcher.h"
+
+class LLControlGroup;
+class LLSD;
+
+class LLViewerControlListener : public LLDispatchListener
+{
+public:
+ LLViewerControlListener();
+
+private:
+ static void set(LLControlGroup *controls, LLSD const & event_data);
+ static void toggleControl(LLControlGroup *controls, LLSD const & event_data);
+ static void setDefault(LLControlGroup *controls, LLSD const & event_data);
+};
+
+extern LLViewerControlListener gSavedSettingsListener;
+
+#endif // LL_LLVIEWERCONTROLLISTENER_H
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index a06d913fd6..c3e6bd28da 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -763,6 +763,11 @@ void LLViewerMediaImpl::navigateStop()
bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
{
bool result = false;
+ // *NOTE:Mani - if this doesn't exist llmozlib goes crashy in the debug build.
+ // LLMozlib::init wants to write some files to <exe_dir>/components
+ std::string debug_init_component_dir( gDirUtilp->getExecutableDir() );
+ debug_init_component_dir += "/components";
+ LLAPRFile::makeDir(debug_init_component_dir.c_str());
if (mMediaSource)
{
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8220fff6b5..43e9a27484 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -210,6 +210,7 @@
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llfloaternotificationsconsole.h"
+#include "lluilistener.h"
#include "lltexlayer.h"
@@ -420,6 +421,8 @@ public:
static LLMenuParcelObserver* gMenuParcelObserver = NULL;
+static LLUIListener sUIListener("UI");
+
LLMenuParcelObserver::LLMenuParcelObserver()
{
LLViewerParcelMgr::getInstance()->addObserver(this);
@@ -6967,7 +6970,7 @@ void force_error_bad_memory_access(void *)
void force_error_infinite_loop(void *)
{
- LLAppViewer::instance()->forceErrorInifiniteLoop();
+ LLAppViewer::instance()->forceErrorInfiniteLoop();
}
void force_error_software_exception(void *)
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 918b15ef09..801c46035a 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -35,6 +35,8 @@
#include "llviewernetwork.h"
#include "llviewercontrol.h"
+#include "llevents.h"
+#include "lllogin.h"
struct LLGridData
{
@@ -155,6 +157,10 @@ LLViewerLogin::LLViewerLogin() :
{
}
+ LLViewerLogin::~LLViewerLogin()
+ {
+ }
+
void LLViewerLogin::setGridChoice(EGridInfo grid)
{
if(grid < 0 || grid >= GRID_INFO_COUNT)
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 4001ed05c1..edae6dc47b 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -34,7 +34,10 @@
#ifndef LL_LLVIEWERNETWORK_H
#define LL_LLVIEWERNETWORK_H
+#include <boost/scoped_ptr.hpp>
+
class LLHost;
+class LLLogin;
enum EGridInfo
{
@@ -74,6 +77,7 @@ class LLViewerLogin : public LLSingleton<LLViewerLogin>
{
public:
LLViewerLogin();
+ ~LLViewerLogin();
void setGridChoice(EGridInfo grid);
void setGridChoice(const std::string& grid_name);
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index ca3061e083..d900ea9b33 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -57,6 +57,7 @@
#include "llparcelselection.h"
#include "llresmgr.h"
#include "llsdutil.h"
+#include "llsdutil_math.h"
#include "llstatusbar.h"
#include "llui.h"
#include "llviewertexture.h"
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 36499fd191..8b7bb83d0d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -32,6 +32,10 @@
#include "llviewerprecompiledheaders.h"
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
// system library includes
#include <stdio.h>
#include <iostream>
@@ -195,6 +199,7 @@
#include "llfloaternotificationsconsole.h"
#include "llnearbychat.h"
+#include "llviewerwindowlistener.h"
#if LL_WINDOWS
#include <tchar.h> // For Unicode conversion methods
@@ -1259,7 +1264,8 @@ LLViewerWindow::LLViewerWindow(
mResDirty(false),
mStatesDirty(false),
mIsFullscreenChecked(false),
- mCurrResolutionIndex(0)
+ mCurrResolutionIndex(0),
+ mViewerWindowListener(new LLViewerWindowListener("LLViewerWindow", this))
{
LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 7afb77bed8..8502f7a719 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -52,6 +52,8 @@
#include "llcursortypes.h"
#include "llhandle.h"
+#include <boost/scoped_ptr.hpp>
+
class LLView;
class LLViewerObject;
class LLUUID;
@@ -63,6 +65,7 @@ class LLImageRaw;
class LLHUDIcon;
class LLWindow;
class LLRootView;
+class LLViewerWindowListener;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -458,6 +461,8 @@ protected:
bool mIsFullscreenChecked; // Did the user check the fullscreen checkbox in the display settings
U32 mCurrResolutionIndex;
+ boost::scoped_ptr<LLViewerWindowListener> mViewerWindowListener;
+
protected:
static std::string sSnapshotBaseName;
static std::string sSnapshotDir;
diff --git a/indra/newview/llviewerwindowlistener.cpp b/indra/newview/llviewerwindowlistener.cpp
new file mode 100644
index 0000000000..317e361c80
--- /dev/null
+++ b/indra/newview/llviewerwindowlistener.cpp
@@ -0,0 +1,87 @@
+/**
+ * @file llviewerwindowlistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-06-30
+ * @brief Implementation for llviewerwindowlistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llviewerwindowlistener.h"
+// STL headers
+#include <map>
+// std headers
+// external library headers
+// other Linden headers
+#include "llviewerwindow.h"
+
+LLViewerWindowListener::LLViewerWindowListener(const std::string& pumpname, LLViewerWindow* llviewerwindow):
+ LLDispatchListener(pumpname, "op"),
+ mViewerWindow(llviewerwindow)
+{
+ // add() every method we want to be able to invoke via this event API.
+ LLSD saveSnapshotArgs;
+ saveSnapshotArgs["filename"] = LLSD::String();
+ saveSnapshotArgs["reply"] = LLSD::String();
+ // The following are optional, so don't build them into required prototype.
+// saveSnapshotArgs["width"] = LLSD::Integer();
+// saveSnapshotArgs["height"] = LLSD::Integer();
+// saveSnapshotArgs["showui"] = LLSD::Boolean();
+// saveSnapshotArgs["rebuild"] = LLSD::Boolean();
+// saveSnapshotArgs["type"] = LLSD::String();
+ add("saveSnapshot", &LLViewerWindowListener::saveSnapshot, saveSnapshotArgs);
+ add("requestReshape", &LLViewerWindowListener::requestReshape);
+}
+
+void LLViewerWindowListener::saveSnapshot(const LLSD& event) const
+{
+ LLReqID reqid(event);
+ typedef std::map<LLSD::String, LLViewerWindow::ESnapshotType> TypeMap;
+ TypeMap types;
+#define tp(name) types[#name] = LLViewerWindow::SNAPSHOT_TYPE_##name
+ tp(COLOR);
+ tp(DEPTH);
+ tp(OBJECT_ID);
+#undef tp
+ // Our add() call should ensure that the incoming LLSD does in fact
+ // contain our required arguments. Deal with the optional ones.
+ S32 width (mViewerWindow->getWindowDisplayWidth());
+ S32 height(mViewerWindow->getWindowDisplayHeight());
+ if (event.has("width"))
+ width = event["width"].asInteger();
+ if (event.has("height"))
+ height = event["height"].asInteger();
+ // showui defaults to true, requiring special treatment
+ bool showui = true;
+ if (event.has("showui"))
+ showui = event["showui"].asBoolean();
+ bool rebuild(event["rebuild"]); // defaults to false
+ LLViewerWindow::ESnapshotType type(LLViewerWindow::SNAPSHOT_TYPE_COLOR);
+ if (event.has("type"))
+ {
+ TypeMap::const_iterator found = types.find(event["type"]);
+ if (found == types.end())
+ {
+ LL_ERRS("LLViewerWindowListener") << "LLViewerWindowListener::saveSnapshot(): "
+ << "unrecognized type " << event["type"] << LL_ENDL;
+ }
+ type = found->second;
+ }
+ bool ok = mViewerWindow->saveSnapshot(event["filename"], width, height, showui, rebuild, type);
+ LLSD response(reqid.makeResponse());
+ response["ok"] = ok;
+ LLEventPumps::instance().obtain(event["reply"]).post(response);
+}
+
+void LLViewerWindowListener::requestReshape(LLSD const & event_data) const
+{
+ if(event_data.has("w") && event_data.has("h"))
+ {
+ mViewerWindow->reshape(event_data["w"].asInteger(), event_data["h"].asInteger());
+ }
+}
diff --git a/indra/newview/llviewerwindowlistener.h b/indra/newview/llviewerwindowlistener.h
new file mode 100644
index 0000000000..59c636ecec
--- /dev/null
+++ b/indra/newview/llviewerwindowlistener.h
@@ -0,0 +1,35 @@
+/**
+ * @file llviewerwindowlistener.h
+ * @author Nat Goodspeed
+ * @date 2009-06-30
+ * @brief Event API for subset of LLViewerWindow methods
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLVIEWERWINDOWLISTENER_H)
+#define LL_LLVIEWERWINDOWLISTENER_H
+
+#include "lleventdispatcher.h"
+
+class LLViewerWindow;
+class LLSD;
+
+/// Listen on an LLEventPump with specified name for LLViewerWindow request events.
+class LLViewerWindowListener: public LLDispatchListener
+{
+public:
+ /// Specify the pump name on which to listen, and bind the LLViewerWindow
+ /// instance to use (e.g. gViewerWindow).
+ LLViewerWindowListener(const std::string& pumpname, LLViewerWindow* llviewerwindow);
+
+private:
+ void saveSnapshot(const LLSD& event) const;
+ void requestReshape(LLSD const & event_data) const;
+
+ LLViewerWindow* mViewerWindow;
+};
+
+#endif /* ! defined(LL_LLVIEWERWINDOWLISTENER_H) */
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
new file mode 100644
index 0000000000..71e2427c99
--- /dev/null
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -0,0 +1,496 @@
+/**
+ * @file llxmlrpclistener.cpp
+ * @author Nat Goodspeed
+ * @date 2009-03-18
+ * @brief Implementation for llxmlrpclistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+// associated header
+#include "llxmlrpclistener.h"
+// STL headers
+#include <map>
+#include <set>
+// std headers
+// external library headers
+#include <boost/scoped_ptr.hpp>
+#include <boost/range.hpp> // boost::begin(), boost::end()
+// other Linden headers
+#include "llerror.h"
+#include "stringize.h"
+#include "llxmlrpctransaction.h"
+
+#include <xmlrpc-epi/xmlrpc.h>
+
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
+template <typename STATUS>
+class StatusMapperBase
+{
+ typedef std::map<STATUS, std::string> MapType;
+
+public:
+ StatusMapperBase(const std::string& desc):
+ mDesc(desc)
+ {}
+
+ std::string lookup(STATUS status) const
+ {
+ typename MapType::const_iterator found = mMap.find(status);
+ if (found != mMap.end())
+ {
+ return found->second;
+ }
+ return STRINGIZE("<unknown " << mDesc << " " << status << ">");
+ }
+
+protected:
+ std::string mDesc;
+ MapType mMap;
+};
+
+class StatusMapper: public StatusMapperBase<LLXMLRPCTransaction::Status>
+{
+public:
+ StatusMapper(): StatusMapperBase<LLXMLRPCTransaction::Status>("Status")
+ {
+ mMap[LLXMLRPCTransaction::StatusNotStarted] = "NotStarted";
+ mMap[LLXMLRPCTransaction::StatusStarted] = "Started";
+ mMap[LLXMLRPCTransaction::StatusDownloading] = "Downloading";
+ mMap[LLXMLRPCTransaction::StatusComplete] = "Complete";
+ mMap[LLXMLRPCTransaction::StatusCURLError] = "CURLError";
+ mMap[LLXMLRPCTransaction::StatusXMLRPCError] = "XMLRPCError";
+ mMap[LLXMLRPCTransaction::StatusOtherError] = "OtherError";
+ }
+};
+
+static const StatusMapper sStatusMapper;
+
+class CURLcodeMapper: public StatusMapperBase<CURLcode>
+{
+public:
+ CURLcodeMapper(): StatusMapperBase<CURLcode>("CURLcode")
+ {
+ // from curl.h
+// skip the "CURLE_" prefix for each of these strings
+#define def(sym) (mMap[sym] = #sym + 6)
+ def(CURLE_OK);
+ def(CURLE_UNSUPPORTED_PROTOCOL); /* 1 */
+ def(CURLE_FAILED_INIT); /* 2 */
+ def(CURLE_URL_MALFORMAT); /* 3 */
+ def(CURLE_URL_MALFORMAT_USER); /* 4 - NOT USED */
+ def(CURLE_COULDNT_RESOLVE_PROXY); /* 5 */
+ def(CURLE_COULDNT_RESOLVE_HOST); /* 6 */
+ def(CURLE_COULDNT_CONNECT); /* 7 */
+ def(CURLE_FTP_WEIRD_SERVER_REPLY); /* 8 */
+ def(CURLE_FTP_ACCESS_DENIED); /* 9 a service was denied by the FTP server
+ due to lack of access - when login fails
+ this is not returned. */
+ def(CURLE_FTP_USER_PASSWORD_INCORRECT); /* 10 - NOT USED */
+ def(CURLE_FTP_WEIRD_PASS_REPLY); /* 11 */
+ def(CURLE_FTP_WEIRD_USER_REPLY); /* 12 */
+ def(CURLE_FTP_WEIRD_PASV_REPLY); /* 13 */
+ def(CURLE_FTP_WEIRD_227_FORMAT); /* 14 */
+ def(CURLE_FTP_CANT_GET_HOST); /* 15 */
+ def(CURLE_FTP_CANT_RECONNECT); /* 16 */
+ def(CURLE_FTP_COULDNT_SET_BINARY); /* 17 */
+ def(CURLE_PARTIAL_FILE); /* 18 */
+ def(CURLE_FTP_COULDNT_RETR_FILE); /* 19 */
+ def(CURLE_FTP_WRITE_ERROR); /* 20 */
+ def(CURLE_FTP_QUOTE_ERROR); /* 21 */
+ def(CURLE_HTTP_RETURNED_ERROR); /* 22 */
+ def(CURLE_WRITE_ERROR); /* 23 */
+ def(CURLE_MALFORMAT_USER); /* 24 - NOT USED */
+ def(CURLE_UPLOAD_FAILED); /* 25 - failed upload "command" */
+ def(CURLE_READ_ERROR); /* 26 - could open/read from file */
+ def(CURLE_OUT_OF_MEMORY); /* 27 */
+ /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
+ instead of a memory allocation error if CURL_DOES_CONVERSIONS
+ is defined
+ */
+ def(CURLE_OPERATION_TIMEOUTED); /* 28 - the timeout time was reached */
+ def(CURLE_FTP_COULDNT_SET_ASCII); /* 29 - TYPE A failed */
+ def(CURLE_FTP_PORT_FAILED); /* 30 - FTP PORT operation failed */
+ def(CURLE_FTP_COULDNT_USE_REST); /* 31 - the REST command failed */
+ def(CURLE_FTP_COULDNT_GET_SIZE); /* 32 - the SIZE command failed */
+ def(CURLE_HTTP_RANGE_ERROR); /* 33 - RANGE "command" didn't work */
+ def(CURLE_HTTP_POST_ERROR); /* 34 */
+ def(CURLE_SSL_CONNECT_ERROR); /* 35 - wrong when connecting with SSL */
+ def(CURLE_BAD_DOWNLOAD_RESUME); /* 36 - couldn't resume download */
+ def(CURLE_FILE_COULDNT_READ_FILE); /* 37 */
+ def(CURLE_LDAP_CANNOT_BIND); /* 38 */
+ def(CURLE_LDAP_SEARCH_FAILED); /* 39 */
+ def(CURLE_LIBRARY_NOT_FOUND); /* 40 */
+ def(CURLE_FUNCTION_NOT_FOUND); /* 41 */
+ def(CURLE_ABORTED_BY_CALLBACK); /* 42 */
+ def(CURLE_BAD_FUNCTION_ARGUMENT); /* 43 */
+ def(CURLE_BAD_CALLING_ORDER); /* 44 - NOT USED */
+ def(CURLE_INTERFACE_FAILED); /* 45 - CURLOPT_INTERFACE failed */
+ def(CURLE_BAD_PASSWORD_ENTERED); /* 46 - NOT USED */
+ def(CURLE_TOO_MANY_REDIRECTS ); /* 47 - catch endless re-direct loops */
+ def(CURLE_UNKNOWN_TELNET_OPTION); /* 48 - User specified an unknown option */
+ def(CURLE_TELNET_OPTION_SYNTAX ); /* 49 - Malformed telnet option */
+ def(CURLE_OBSOLETE); /* 50 - NOT USED */
+ def(CURLE_SSL_PEER_CERTIFICATE); /* 51 - peer's certificate wasn't ok */
+ def(CURLE_GOT_NOTHING); /* 52 - when this is a specific error */
+ def(CURLE_SSL_ENGINE_NOTFOUND); /* 53 - SSL crypto engine not found */
+ def(CURLE_SSL_ENGINE_SETFAILED); /* 54 - can not set SSL crypto engine as
+ default */
+ def(CURLE_SEND_ERROR); /* 55 - failed sending network data */
+ def(CURLE_RECV_ERROR); /* 56 - failure in receiving network data */
+ def(CURLE_SHARE_IN_USE); /* 57 - share is in use */
+ def(CURLE_SSL_CERTPROBLEM); /* 58 - problem with the local certificate */
+ def(CURLE_SSL_CIPHER); /* 59 - couldn't use specified cipher */
+ def(CURLE_SSL_CACERT); /* 60 - problem with the CA cert (path?) */
+ def(CURLE_BAD_CONTENT_ENCODING); /* 61 - Unrecognized transfer encoding */
+ def(CURLE_LDAP_INVALID_URL); /* 62 - Invalid LDAP URL */
+ def(CURLE_FILESIZE_EXCEEDED); /* 63 - Maximum file size exceeded */
+ def(CURLE_FTP_SSL_FAILED); /* 64 - Requested FTP SSL level failed */
+ def(CURLE_SEND_FAIL_REWIND); /* 65 - Sending the data requires a rewind
+ that failed */
+ def(CURLE_SSL_ENGINE_INITFAILED); /* 66 - failed to initialise ENGINE */
+ def(CURLE_LOGIN_DENIED); /* 67 - user); password or similar was not
+ accepted and we failed to login */
+ def(CURLE_TFTP_NOTFOUND); /* 68 - file not found on server */
+ def(CURLE_TFTP_PERM); /* 69 - permission problem on server */
+ def(CURLE_TFTP_DISKFULL); /* 70 - out of disk space on server */
+ def(CURLE_TFTP_ILLEGAL); /* 71 - Illegal TFTP operation */
+ def(CURLE_TFTP_UNKNOWNID); /* 72 - Unknown transfer ID */
+ def(CURLE_TFTP_EXISTS); /* 73 - File already exists */
+ def(CURLE_TFTP_NOSUCHUSER); /* 74 - No such user */
+ def(CURLE_CONV_FAILED); /* 75 - conversion failed */
+ def(CURLE_CONV_REQD); /* 76 - caller must register conversion
+ callbacks using curl_easy_setopt options
+ CURLOPT_CONV_FROM_NETWORK_FUNCTION);
+ CURLOPT_CONV_TO_NETWORK_FUNCTION); and
+ CURLOPT_CONV_FROM_UTF8_FUNCTION */
+ def(CURLE_SSL_CACERT_BADFILE); /* 77 - could not load CACERT file); missing
+ or wrong format */
+ def(CURLE_REMOTE_FILE_NOT_FOUND); /* 78 - remote file not found */
+ def(CURLE_SSH); /* 79 - error from the SSH layer); somewhat
+ generic so the error message will be of
+ interest when this has happened */
+
+ def(CURLE_SSL_SHUTDOWN_FAILED); /* 80 - Failed to shut down the SSL
+ connection */
+#undef def
+ }
+};
+
+static const CURLcodeMapper sCURLcodeMapper;
+
+LLXMLRPCListener::LLXMLRPCListener(const std::string& pumpname):
+ mBoundListener(LLEventPumps::instance().
+ obtain(pumpname).
+ listen("LLXMLRPCListener", boost::bind(&LLXMLRPCListener::process, this, _1)))
+{
+}
+
+/**
+ * Capture an outstanding LLXMLRPCTransaction and poll it periodically until
+ * done.
+ *
+ * The sequence is:
+ * # Instantiate Poller, which instantiates, populates and initiates an
+ * LLXMLRPCTransaction. Poller self-registers on the LLEventPump named
+ * "mainloop".
+ * # "mainloop" is conventionally pumped once per frame. On each such call,
+ * Poller checks its LLXMLRPCTransaction for completion.
+ * # When the LLXMLRPCTransaction completes, Poller collects results (if any)
+ * and sends notification.
+ * # The tricky part: Poller frees itself (and thus its LLXMLRPCTransaction)
+ * when done. The only external reference to it is the connection to the
+ * "mainloop" LLEventPump.
+ */
+class Poller
+{
+public:
+ /// Validate the passed request for required fields, then use it to
+ /// populate an XMLRPC_REQUEST and an associated LLXMLRPCTransaction. Send
+ /// the request.
+ Poller(const LLSD& command):
+ mReqID(command),
+ mUri(command["uri"]),
+ mMethod(command["method"]),
+ mReplyPump(command["reply"])
+ {
+ // LL_ERRS if any of these are missing
+ const char* required[] = { "uri", "method", "reply" };
+ // optional: "options" (array of string)
+ // Validate the request
+ std::set<std::string> missing;
+ for (const char** ri = boost::begin(required); ri != boost::end(required); ++ri)
+ {
+ // If the command does not contain this required entry, add it to 'missing'.
+ if (! command.has(*ri))
+ {
+ missing.insert(*ri);
+ }
+ }
+ if (! missing.empty())
+ {
+ LL_ERRS("LLXMLRPCListener") << mMethod << " request missing params: ";
+ const char* separator = "";
+ for (std::set<std::string>::const_iterator mi(missing.begin()), mend(missing.end());
+ mi != mend; ++mi)
+ {
+ LL_CONT << separator << *mi;
+ separator = ", ";
+ }
+ LL_CONT << LL_ENDL;
+ }
+
+ // Build the XMLRPC request.
+ XMLRPC_REQUEST request = XMLRPC_RequestNew();
+ XMLRPC_RequestSetMethodName(request, mMethod.c_str());
+ XMLRPC_RequestSetRequestType(request, xmlrpc_request_call);
+ XMLRPC_VALUE xparams = XMLRPC_CreateVector(NULL, xmlrpc_vector_struct);
+ LLSD params(command["params"]);
+ if (params.isMap())
+ {
+ for (LLSD::map_const_iterator pi(params.beginMap()), pend(params.endMap());
+ pi != pend; ++pi)
+ {
+ std::string name(pi->first);
+ LLSD param(pi->second);
+ if (param.isString())
+ {
+ XMLRPC_VectorAppendString(xparams, name.c_str(), param.asString().c_str(), 0);
+ }
+ else if (param.isInteger() || param.isBoolean())
+ {
+ XMLRPC_VectorAppendInt(xparams, name.c_str(), param.asInteger());
+ }
+ else if (param.isReal())
+ {
+ XMLRPC_VectorAppendDouble(xparams, name.c_str(), param.asReal());
+ }
+ else
+ {
+ LL_ERRS("LLXMLRPCListener") << mMethod << " request param "
+ << name << " has unknown type: " << param << LL_ENDL;
+ }
+ }
+ }
+ LLSD options(command["options"]);
+ if (options.isArray())
+ {
+ XMLRPC_VALUE xoptions = XMLRPC_CreateVector("options", xmlrpc_vector_array);
+ for (LLSD::array_const_iterator oi(options.beginArray()), oend(options.endArray());
+ oi != oend; ++oi)
+ {
+ XMLRPC_VectorAppendString(xoptions, NULL, oi->asString().c_str(), 0);
+ }
+ XMLRPC_AddValueToVector(xparams, xoptions);
+ }
+ XMLRPC_RequestSetData(request, xparams);
+
+ mTransaction.reset(new LLXMLRPCTransaction(mUri, request));
+ mPreviousStatus = mTransaction->status(NULL);
+
+ // Free the XMLRPC_REQUEST object and the attached data values.
+ XMLRPC_RequestFree(request, 1);
+
+ // Now ensure that we get regular callbacks to poll for completion.
+ mBoundListener =
+ LLEventPumps::instance().
+ obtain("mainloop").
+ listen(LLEventPump::inventName(), boost::bind(&Poller::poll, this, _1));
+
+ LL_INFOS("LLXMLRPCListener") << mMethod << " request sent to " << mUri << LL_ENDL;
+ }
+
+ /// called by "mainloop" LLEventPump
+ bool poll(const LLSD&)
+ {
+ bool done = mTransaction->process();
+
+ CURLcode curlcode;
+ LLXMLRPCTransaction::Status status;
+ {
+ // LLXMLRPCTransaction::status() is defined to accept int* rather
+ // than CURLcode*. I don't feel the urge to fix the signature, but
+ // we want a CURLcode rather than an int. So fetch it as a local
+ // int, but then assign to a CURLcode for the remainder of this
+ // method.
+ int curlint;
+ status = mTransaction->status(&curlint);
+ curlcode = CURLcode(curlint);
+ }
+
+ LLSD data(mReqID.makeResponse());
+ data["status"] = sStatusMapper.lookup(status);
+ data["errorcode"] = sCURLcodeMapper.lookup(curlcode);
+ data["error"] = "";
+ data["transfer_rate"] = 0.0;
+ LLEventPump& replyPump(LLEventPumps::instance().obtain(mReplyPump));
+ if (! done)
+ {
+ // Not done yet, carry on.
+ if (status == LLXMLRPCTransaction::StatusDownloading
+ && status != mPreviousStatus)
+ {
+ // If a response has been received, send the
+ // 'downloading' status if it hasn't been sent.
+ replyPump.post(data);
+ }
+
+ mPreviousStatus = status;
+ return false;
+ }
+
+ // Here the transaction is complete. Check status.
+ data["error"] = mTransaction->statusMessage();
+ data["transfer_rate"] = mTransaction->transferRate();
+ LL_INFOS("LLXMLRPCListener") << mMethod << " result from " << mUri << ": status "
+ << data["status"].asString() << ", errorcode "
+ << data["errorcode"].asString()
+ << " (" << data["error"].asString() << ")"
+ << LL_ENDL;
+ // In addition to CURLE_OK, LLUserAuth distinguishes different error
+ // values of 'curlcode':
+ // CURLE_COULDNT_RESOLVE_HOST,
+ // CURLE_SSL_PEER_CERTIFICATE,
+ // CURLE_SSL_CACERT,
+ // CURLE_SSL_CONNECT_ERROR.
+ // Given 'message', need we care?
+ if (status == LLXMLRPCTransaction::StatusComplete)
+ {
+ // Success! Parse data.
+ std::string status_string(data["status"]);
+ data["responses"] = parseResponse(status_string);
+ data["status"] = status_string;
+ }
+
+ // whether successful or not, send reply on requested LLEventPump
+ replyPump.post(data);
+
+ // Because mTransaction is a boost::scoped_ptr, deleting this object
+ // frees our LLXMLRPCTransaction object.
+ // Because mBoundListener is an LLTempBoundListener, deleting this
+ // object disconnects it from "mainloop".
+ // *** MUST BE LAST ***
+ delete this;
+ return false;
+ }
+
+private:
+ /// Derived from LLUserAuth::parseResponse() and parseOptionInto()
+ LLSD parseResponse(std::string& status_string)
+ {
+ // Extract every member into data["responses"] (a map of string
+ // values).
+ XMLRPC_REQUEST response = mTransaction->response();
+ if (! response)
+ {
+ LL_DEBUGS("LLXMLRPCListener") << "No response" << LL_ENDL;
+ return LLSD();
+ }
+
+ XMLRPC_VALUE param = XMLRPC_RequestGetData(response);
+ if (! param)
+ {
+ LL_DEBUGS("LLXMLRPCListener") << "Response contains no data" << LL_ENDL;
+ return LLSD();
+ }
+
+ // Now, parse everything
+ return parseValues(status_string, "", param);
+ }
+
+ /**
+ * Parse key/value pairs from a given XMLRPC_VALUE into an LLSD map.
+ * @param key_pfx Used to describe a given key in log messages. At top
+ * level, pass "". When parsing an options array, pass the top-level key
+ * name of the array plus the index of the array entry; to this we'll
+ * append the subkey of interest.
+ * @param param XMLRPC_VALUE iterator. At top level, pass
+ * XMLRPC_RequestGetData(XMLRPC_REQUEST).
+ */
+ LLSD parseValues(std::string& status_string, const std::string& key_pfx, XMLRPC_VALUE param)
+ {
+ LLSD responses;
+ for (XMLRPC_VALUE current = XMLRPC_VectorRewind(param); current;
+ current = XMLRPC_VectorNext(param))
+ {
+ std::string key(XMLRPC_GetValueID(current));
+ LL_DEBUGS("LLXMLRPCListener") << "key: " << key_pfx << key << LL_ENDL;
+ XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(current);
+ if (xmlrpc_type_string == type)
+ {
+ LLSD::String val(XMLRPC_GetValueString(current));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
+ responses.insert(key, val);
+ }
+ else if (xmlrpc_type_int == type)
+ {
+ LLSD::Integer val(XMLRPC_GetValueInt(current));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
+ responses.insert(key, val);
+ }
+ else if (xmlrpc_type_double == type)
+ {
+ LLSD::Real val(XMLRPC_GetValueDouble(current));
+ LL_DEBUGS("LLXMLRPCListener") << "val: " << val << LL_ENDL;
+ responses.insert(key, val);
+ }
+ else if (xmlrpc_type_array == type)
+ {
+ // We expect this to be an array of submaps. Walk the array,
+ // recursively parsing each submap and collecting them.
+ LLSD array;
+ int i = 0; // for descriptive purposes
+ for (XMLRPC_VALUE row = XMLRPC_VectorRewind(current); row;
+ row = XMLRPC_VectorNext(current), ++i)
+ {
+ // Recursive call. For the lower-level key_pfx, if 'key'
+ // is "foo", pass "foo[0]:", then "foo[1]:", etc. In the
+ // nested call, a subkey "bar" will then be logged as
+ // "foo[0]:bar", and so forth.
+ // Parse the scalar subkey/value pairs from this array
+ // entry into a temp submap. Collect such submaps in 'array'.
+ array.append(parseValues(status_string,
+ STRINGIZE(key_pfx << key << '[' << i << "]:"),
+ row));
+ }
+ // Having collected an 'array' of 'submap's, insert that whole
+ // 'array' as the value of this 'key'.
+ responses.insert(key, array);
+ }
+ else
+ {
+ // whoops - unrecognized type
+ LL_WARNS("LLXMLRPCListener") << "Unhandled xmlrpc type " << type << " for key "
+ << key_pfx << key << LL_ENDL;
+ responses.insert(key, STRINGIZE("<bad XMLRPC type " << type << '>'));
+ status_string = "BadType";
+ }
+ }
+ return responses;
+ }
+
+ const LLReqID mReqID;
+ const std::string mUri;
+ const std::string mMethod;
+ const std::string mReplyPump;
+ LLTempBoundListener mBoundListener;
+ boost::scoped_ptr<LLXMLRPCTransaction> mTransaction;
+ LLXMLRPCTransaction::Status mPreviousStatus; // To detect state changes.
+};
+
+bool LLXMLRPCListener::process(const LLSD& command)
+{
+ // Allocate a new heap Poller, but do not save a pointer to it. Poller
+ // will check its own status and free itself on completion of the request.
+ (new Poller(command));
+ // conventional event listener return
+ return false;
+}
diff --git a/indra/newview/llxmlrpclistener.h b/indra/newview/llxmlrpclistener.h
new file mode 100644
index 0000000000..120c2b329b
--- /dev/null
+++ b/indra/newview/llxmlrpclistener.h
@@ -0,0 +1,35 @@
+/**
+ * @file llxmlrpclistener.h
+ * @author Nat Goodspeed
+ * @date 2009-03-18
+ * @brief LLEventPump API for LLXMLRPCTransaction. This header doesn't
+ * actually define the API; the API is defined by the pump name on
+ * which this class listens, and by the expected content of LLSD it
+ * receives.
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLXMLRPCLISTENER_H)
+#define LL_LLXMLRPCLISTENER_H
+
+#include "llevents.h"
+
+/// Listen on an LLEventPump with specified name for LLXMLRPCTransaction
+/// request events.
+class LLXMLRPCListener
+{
+public:
+ /// Specify the pump name on which to listen
+ LLXMLRPCListener(const std::string& pumpname);
+
+ /// Handle request events on the event pump specified at construction time
+ bool process(const LLSD& command);
+
+private:
+ LLTempBoundListener mBoundListener;
+};
+
+#endif /* ! defined(LL_LLXMLRPCLISTENER_H) */
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index a2fd0f0d9c..0e1beb377f 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
#include "llxmlrpctransaction.h"
+#include "llxmlrpclistener.h"
#include "llcurl.h"
#include "llviewercontrol.h"
@@ -42,6 +43,13 @@
#include "llappviewer.h"
+// Static instance of LLXMLRPCListener declared here so that every time we
+// bring in this code, we instantiate a listener. If we put the static
+// instance of LLXMLRPCListener into llxmlrpclistener.cpp, the linker would
+// simply omit llxmlrpclistener.o, and shouting on the LLEventPump would do
+// nothing.
+static LLXMLRPCListener listener("LLXMLRPCTransaction");
+
LLXMLRPCValue LLXMLRPCValue::operator[](const char* id) const
{
return LLXMLRPCValue(XMLRPC_VectorGetValueWithID(mV, id));
@@ -213,6 +221,11 @@ LLXMLRPCTransaction::Impl::Impl(const std::string& uri,
XMLRPC_RequestSetData(request, params.getValue());
init(request, useGzip);
+ // DEV-28398: without this XMLRPC_RequestFree() call, it looks as though
+ // the 'request' object is simply leaked. It's less clear to me whether we
+ // should also ask to free request value data (second param 1), since the
+ // data come from 'params'.
+ XMLRPC_RequestFree(request, 1);
}
diff --git a/indra/newview/nl.lproj/language.txt b/indra/newview/nl.lproj/language.txt
new file mode 100644
index 0000000000..d5f5c2a19c
--- /dev/null
+++ b/indra/newview/nl.lproj/language.txt
@@ -0,0 +1 @@
+nl \ No newline at end of file
diff --git a/indra/newview/pl.lproj/language.txt b/indra/newview/pl.lproj/language.txt
new file mode 100644
index 0000000000..55239f3c18
--- /dev/null
+++ b/indra/newview/pl.lproj/language.txt
@@ -0,0 +1 @@
+pl \ No newline at end of file
diff --git a/indra/newview/pt.lproj/language.txt b/indra/newview/pt.lproj/language.txt
new file mode 100644
index 0000000000..9e3340eca2
--- /dev/null
+++ b/indra/newview/pt.lproj/language.txt
@@ -0,0 +1 @@
+pt \ No newline at end of file
diff --git a/indra/newview/ru.lproj/language.txt b/indra/newview/ru.lproj/language.txt
new file mode 100644
index 0000000000..adc719b423
--- /dev/null
+++ b/indra/newview/ru.lproj/language.txt
@@ -0,0 +1 @@
+ru \ No newline at end of file
diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml
index 401aa74084..e94e22d9b8 100644
--- a/indra/newview/skins/default/xui/de/floater_snapshot.xml
+++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml
@@ -21,12 +21,12 @@
<button label="Senden" name="send_btn"/>
<button label="Speichern ([AMOUNT] L$)" name="upload_btn"/>
<flyout_button label="Speichern" name="save_btn" tool_tip="Bild als Datei speichern">
- <flyout_button_item name="save_item">
- Speichern
- </flyout_button_item>
- <flyout_button_item name="saveas_item">
- Speichern unter...
- </flyout_button_item>
+ <flyout_button.item name="save_item">
+ Speichern
+ </flyout_button.item>
+ <flyout_button.item name="saveas_item">
+ Speichern unter...
+ </flyout_button.item>
</flyout_button>
<button label="Abbrechen" name="discard_btn"/>
<button label="Mehr &gt;&gt;" name="more_btn" tool_tip="Erweiterte Optionen"/>
@@ -38,75 +38,33 @@
Format
</text>
<combo_box label="Auflösung" name="postcard_size_combo">
- <combo_item name="CurrentWindow">
- Aktuelles Fenster
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="Custom">
- Benutzerdefiniert
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Aktuelles Fenster" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="Custom" label="Benutzerdefiniert" />
</combo_box>
<combo_box label="Auflösung" name="texture_size_combo">
- <combo_item name="CurrentWindow">
- Aktuelles Fenster
- </combo_item>
- <combo_item name="Small(128x128)">
- Klein (128x128)
- </combo_item>
- <combo_item name="Medium(256x256)">
- Mittel (256x256)
- </combo_item>
- <combo_item name="Large(512x512)">
- Groß (512x512)
- </combo_item>
- <combo_item name="Custom">
- Benutzerdefiniert
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Aktuelles Fenster" />
+ <combo_box.item name="Small(128x128)" label="Klein (128x128)" />
+ <combo_box.item name="Medium(256x256)" label="Mittel (256x256)" />
+ <combo_box.item name="Large(512x512)" label="Groß (512x512)" />
+ <combo_box.item name="Custom" label="Benutzerdefiniert" />
</combo_box>
<combo_box label="Auflösung" name="local_size_combo">
- <combo_item name="CurrentWindow">
- Aktuelles Fenster
- </combo_item>
- <combo_item name="320x240">
- 320x240
- </combo_item>
- <combo_item name="640x480">
- 640x480
- </combo_item>
- <combo_item name="800x600">
- 800x600
- </combo_item>
- <combo_item name="1024x768">
- 1024x768
- </combo_item>
- <combo_item name="1280x1024">
- 1280x1024
- </combo_item>
- <combo_item name="1600x1200">
- 1600x1200
- </combo_item>
- <combo_item name="Custom">
- Benutzerdefiniert
- </combo_item>
+ <combo_box.item name="CurrentWindow" label="Aktuelles Fenster" />
+ <combo_box.item name="320x240" label="320x240" />
+ <combo_box.item name="640x480" label="640x480" />
+ <combo_box.item name="800x600" label="800x600" />
+ <combo_box.item name="1024x768" label="1024x768" />
+ <combo_box.item name="1280x1024" label="1280x1024" />
+ <combo_box.item name="1600x1200" label="1600x1200" />
+ <combo_box.item name="Custom" label="Benutzerdefiniert" />
</combo_box>
<combo_box label="Format" name="local_format_combo">
- <combo_item name="PNG">
- PNG
- </combo_item>
- <combo_item name="JPEG">
- JPEG
- </combo_item>
- <combo_item name="BMP">
- BMP
- </combo_item>
+ <combo_box.item name="PNG" label="PNG" />
+ <combo_box.item name="JPEG" label="JPEG" />
+ <combo_box.item name="BMP" label="BMP" />
</combo_box>
<spinner label="Breite" name="snapshot_width"/>
<spinner label="Höhe" name="snapshot_height"/>
@@ -116,15 +74,9 @@
Aufnehmen:
</text>
<combo_box label="Bildlayer" name="layer_types" width="132" left="73">
- <combo_item name="Colors">
- Farben
- </combo_item>
- <combo_item name="Depth">
- Tiefe
- </combo_item>
- <combo_item name="ObjectMattes">
- Objektmasken
- </combo_item>
+ <combo_box.item name="Colors" label="Farben" />
+ <combo_box.item name="Depth" label="Tiefe" />
+ <combo_box.item name="ObjectMattes" label="Objektmasken" />
</combo_box>
<check_box label="Interface auf Foto anzeigen" name="ui_check"/>
<check_box label="HUD-Objekte auf Foto anzeigen" name="hud_check"/>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
index 40b4909e84..92b45bf5a5 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
@@ -10,15 +10,9 @@
</radio_group>
<check_box label="Startposition auf Anmeldebildschirm anzeigen" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox">
- <combo_item name="Never">
- Nie
- </combo_item>
- <combo_item name="Show Temporarily">
- Temporär anzeigen
- </combo_item>
- <combo_item name="Always">
- Immer
- </combo_item>
+ <combo_box.item name="Never" label="Nie" />
+ <combo_box.item name="Show Temporarily" label="Temporär anzeigen" />
+ <combo_box.item name="Always" label="Immer" />
</combo_box>
<check_box label="Kleine Avatarnamen" name="small_avatar_names_checkbox"/>
<check_box label="Meinen Namen auf meinem Bildschirm ausblenden" name="show_my_name_checkbox"/>
@@ -80,49 +74,29 @@ Alterseinstufung zugreifen:
&lt;Region eingeben&gt;
</string>
<combo_box name="crash_behavior_combobox" width="166">
- <combo_item name="Askbeforesending">
- Vor dem Senden fragen
- </combo_item>
- <combo_item name="Alwayssend">
- Immer senden
- </combo_item>
- <combo_item name="Neversend">
- Nie senden
- </combo_item>
+ <combo_box.item name="Askbeforesending" label="Vor dem Senden fragen" />
+ <combo_box.item name="Alwayssend" label="Immer senden" />
+ <combo_box.item name="Neversend" label="Nie senden" />
</combo_box>
<combo_box name="language_combobox" width="166">
- <combo_item name="System Default Language">
- Betriebssystem-Einstellung
- </combo_item>
- <combo_item name="English">
- English (Englisch)
- </combo_item>
- <combo_item name="Danish">
- Danks (Dänisch) - Beta
- </combo_item>
- <combo_item name="Deutsch(German)">
- Deutsch - Beta
- </combo_item>
- <combo_item name="Spanish">
- Español (Spanisch) - Beta
- </combo_item>
- <combo_item name="French">
- Français (Französisch) - Beta
- </combo_item>
+ <combo_box.item name="System Default Language" label="Betriebssystem-Einstellung" />
+ <combo_box.item name="English" label="English (Englisch)" />
+ <combo_box.item name="Danish" label="Danks (Dänisch) - Beta" />
+ <combo_box.item name="Deutsch(German)" label="Deutsch - Beta" />
+ <combo_box.item name="Spanish" label="Español (Spanisch) - Beta" />
+ <combo_box.item name="French" label="Français (Französisch) - Beta" />
+ <combo_box.item name="Hungarian" label="Magyar (Ungarisch) - Beta" />
+ <combo_box.item name="Polish" label="Polski (Polnisch) - Beta" />
+ <combo_box.item name="Portugese" label="Português (Portugiesisch) - Beta" />
+ <combo_box.item name="Chinese" label="中文 (简体) (Chinesisch) - Beta" />
+ <combo_box.item name="(Japanese)" label="日本語 (Japanisch) - Beta" />
+ <combo_box.item name="(Korean)" label="한국어 (Koreanisch) - Beta" />
<combo_item name="Italian">
Italiano (Italienisch) - Beta
</combo_item>
- <combo_item name="Hungarian">
- Magyar (Ungarisch) - Beta
- </combo_item>
<combo_item name="Dutch">
Nederlands (Niederländisch) - Beta
</combo_item>
- <combo_item name="Polish">
- Polski (Polnisch) - Beta
- </combo_item>
- <combo_item name="Portugese">
- Português (Portugiesisch) - Beta
</combo_item>
<combo_item name="Russian">
Русский (Russian) - Beta
@@ -132,16 +106,6 @@ Alterseinstufung zugreifen:
</combo_item>
<combo_item name="Ukrainian">
Українська (Ukrainisch) - Beta
- </combo_item>
- <combo_item name="Chinese">
- 中文 (简体) (Chinesisch) - Beta
- </combo_item>
- <combo_item name="(Japanese)">
- 日本語 (Japanisch) - Beta
- </combo_item>
- <combo_item name="(Korean)">
- 한국어 (Koreanisch) - Beta
- </combo_item>
</combo_box>
<check_box label="Objekten Sprache mitteilen" name="language_is_public" tool_tip="In-Welt-Objekten wird Ihre bevorzugte Spracheinstellung mitgeteilt."/>
</panel>
diff --git a/indra/newview/skins/default/xui/es/floater_about_land.xml b/indra/newview/skins/default/xui/es/floater_about_land.xml
index 767b384a2d..3e3b8df646 100644
--- a/indra/newview/skins/default/xui/es/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/es/floater_about_land.xml
@@ -341,42 +341,18 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
</combo_item>
</combo_box>
<combo_box name="land category">
- <combo_item name="AnyCategory">
- Cualquier categoría
- </combo_item>
- <combo_item name="LindenLocation">
- Localización Linden
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- Arte y Cultura
- </combo_item>
- <combo_item name="Business">
- Negocios
- </combo_item>
- <combo_item name="Educational">
- Educativo
- </combo_item>
- <combo_item name="Gaming">
- Juegos de azar
- </combo_item>
- <combo_item name="Hangout">
- Entretenimiento
- </combo_item>
- <combo_item name="NewcomerFriendly">
- Para recién llegados
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- Parques y Naturaleza
- </combo_item>
- <combo_item name="Residential">
- Residencial
- </combo_item>
- <combo_item name="Shopping">
- Compras
- </combo_item>
- <combo_item name="Other">
- Otra
- </combo_item>
+ <combo_box.item name="AnyCategory" label="Cualquier categoría"/>
+ <combo_box.item name="LindenLocation" label="Localización Linden"/>
+ <combo_box.item name="Arts&amp;Culture" label="Arte y Cultura"/>
+ <combo_box.item name="Business" label="Negocios"/>
+ <combo_box.item name="Educational" label="Educativo"/>
+ <combo_box.item name="Gaming" label="Juegos de azar"/>
+ <combo_box.item name="Hangout" label="Entretenimiento"/>
+ <combo_box.item name="NewcomerFriendly" label="Para recién llegados"/>
+ <combo_box.item name="Parks&amp;Nature" label="Parques y Naturaleza"/>
+ <combo_box.item name="Residential" label="Residencial"/>
+ <combo_box.item name="Shopping" label="Compras"/>
+ <combo_box.item name="Other" label="Otra"/>
</combo_box>
<button label="?" label_selected="?" name="?"/>
<check_box label="Contenido &apos;Mature&apos;" name="MatureCheck" tool_tip=""/>
@@ -408,15 +384,9 @@ Sólo las parcelas más grandes pueden listarse en la búsqueda.
Punto de teleporte:
</text>
<combo_box name="landing type" tool_tip="Punto de teleporte: defina cómo manejar en su terreno los teleportes.">
- <combo_item length="1" name="Blocked" type="string">
- Bloqueado
- </combo_item>
- <combo_item length="1" name="LandingPoint" type="string">
- Punto de llegada
- </combo_item>
- <combo_item length="1" name="Anywhere" type="string">
- Cualquiera
- </combo_item>
+ <combo_box.item length="1" name="Blocked" type="string" label="Bloqueado"/>
+ <combo_box.item length="1" name="LandingPoint" type="string" label="Punto de llegada"/>
+ <combo_box.item length="1" name="Anywhere" type="string" label="Cualquiera"/>
</combo_box>
<string name="push_restrict_text">
Sin &apos;empujones&apos;
@@ -497,12 +467,8 @@ música:
<check_box label="Acceso permitido al grupo: [GROUP]" name="GroupCheck" tool_tip="Elija el grupo en la pestaña General."/>
<check_box label="Vender pases a:" name="PassCheck" tool_tip="Permitir acceso temporal a esta parcela"/>
<combo_box name="pass_combo">
- <combo_item name="Anyone">
- Cualquiera
- </combo_item>
- <combo_item name="Group">
- Grupo
- </combo_item>
+ <combo_box.item name="Anyone" label="Cualquiera"/>
+ <combo_box.item name="Group" label="Grupo"/>
</combo_box>
<spinner label="Precio en L$:" name="PriceSpin"/>
<spinner label="Horas de acceso:" name="HoursSpin"/>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
index 9e5cd88603..b711821e5f 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
@@ -10,15 +10,9 @@
</radio_group>
<check_box label="Ver mi posición inicial en la pantalla de inicio de sesión" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox" width="166">
- <combo_item name="Never">
- Nunca
- </combo_item>
- <combo_item name="Show Temporarily">
- Mostrarlos temporalmente
- </combo_item>
- <combo_item name="Always">
- Siempre
- </combo_item>
+ <combo_box.item name="Never" label="Nunca"/>
+ <combo_box.item name="Show Temporarily" label="Mostrarlos temporalmente"/>
+ <combo_box.item name="Always" label="Siempre"/>
</combo_box>
<check_box label="Nombres de avatar en pequeño" name="small_avatar_names_checkbox"/>
<check_box label="No ver mi nombre en mi pantalla" name="show_my_name_checkbox"/>
@@ -80,49 +74,29 @@ contenido calificado:
&lt;escriba el nombre de la región&gt;
</string>
<combo_box name="crash_behavior_combobox" width="166">
- <combo_item length="1" name="Askbeforesending" type="string">
- Preguntar antes de enviar
- </combo_item>
- <combo_item length="1" name="Alwayssend" type="string">
- Enviar siempre
- </combo_item>
- <combo_item length="1" name="Neversend" type="string">
- No enviar nunca
- </combo_item>
+ <combo_box.item length="1" name="Askbeforesending" type="string" label="Preguntar antes de enviar"/>
+ <combo_box.item length="1" name="Alwayssend" type="string" label="Enviar siempre"/>
+ <combo_box.item length="1" name="Neversend" type="string" label="No enviar nunca"/>
</combo_box>
<combo_box name="language_combobox" width="166">
- <combo_item name="System Default Language">
- Predeterminado del sistema
- </combo_item>
- <combo_item length="1" name="English" type="string">
- English (Inglés)
- </combo_item>
- <combo_item name="Danish">
- Dansk (Danés) - Beta
- </combo_item>
- <combo_item length="1" name="Deutsch(German)" type="string">
- Deutsch (Alemán) - Beta
- </combo_item>
- <combo_item name="Spanish" type="string">
- Español - Beta
- </combo_item>
- <combo_item length="1" name="French" type="string">
- Français (Francés) - Beta
- </combo_item>
+ <combo_box.item name="System Default Language" label="Predeterminado del sistema"/>
+ <combo_box.item length="1" name="English" type="string" label="English (Inglés)"/>
+ <combo_box.item name="Danish" label="Dansk (Danés) - Beta"/>
+ <combo_box.item length="1" name="Deutsch(German)" type="string" label="Deutsch (Alemán) - Beta"/>
+ <combo_box.item name="Spanish" type="string" label="Español - Beta"/>
+ <combo_box.item length="1" name="French" type="string" label="Français (Francés) - Beta"/>
+ <combo_box.item name="Hungarian" label="Magyar (Húngaro) - Beta"/>
+ <combo_box.item name="Polish" label="Polski (Polaco) - Beta"/>
+ <combo_box.item name="Portugese" label="Portugués (Portugués) - Beta"/>
+ <combo_box.item length="1" name="Chinese" type="string" label="中文 (简体) (Chino) - Beta"/>
+ <combo_box.item length="1" name="(Japanese)" type="string" label="日本語 (Japonés) - Beta"/>
+ <combo_box.item length="1" name="(Korean)" type="string" label="한국어 (Coreano) - Beta"/>
<combo_item name="Italian">
Italiano - Beta
</combo_item>
- <combo_item name="Hungarian">
- Magyar (Húngaro) - Beta
- </combo_item>
<combo_item name="Dutch">
Nederlands (Neerlandés) - Beta
</combo_item>
- <combo_item name="Polish">
- Polski (Polaco) - Beta
- </combo_item>
- <combo_item name="Portugese">
- Portugués (Portugués) - Beta
</combo_item>
<combo_item name="Russian">
Русский (Ruso) - Beta
@@ -132,16 +106,6 @@ contenido calificado:
</combo_item>
<combo_item name="Ukrainian">
Українська (Ucraniano) - Beta
- </combo_item>
- <combo_item length="1" name="Chinese" type="string">
- 中文 (简体) (Chino) - Beta
- </combo_item>
- <combo_item length="1" name="(Japanese)" type="string">
- 日本語 (Japonés) - Beta
- </combo_item>
- <combo_item length="1" name="(Korean)" type="string">
- 한국어 (Coreano) - Beta
- </combo_item>
</combo_box>
<check_box label="Compartir el idioma con los objetos" name="language_is_public" tool_tip="Hace que los objetos con script del mundo sepan su idioma preferido."/>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 23e1e74035..7c366e8bdc 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -10,15 +10,9 @@
</radio_group>
<check_box label="Afficher le lieu de départ sur l&apos;écran de connexion" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox" width="166">
- <combo_item name="Never">
- Jamais
- </combo_item>
- <combo_item name="Show Temporarily">
- Afficher temporairement
- </combo_item>
- <combo_item name="Always">
- Toujours
- </combo_item>
+ <combo_box.item name="Never" label="Jamais"/>
+ <combo_box.item name="Show Temporarily" label="Afficher temporairement"/>
+ <combo_box.item name="Always" label="Toujours"/>
</combo_box>
<check_box label="Nom des avatars en petit" name="small_avatar_names_checkbox"/>
<check_box label="Masquer mon nom sur mon écran" name="show_my_name_checkbox"/>
@@ -81,68 +75,34 @@ de sélection :
&lt;Saisissez le nom de la région&gt;
</string>
<combo_box name="crash_behavior_combobox" width="166">
- <combo_item length="1" name="Askbeforesending" type="string">
- Demander avant d&apos;envoyer
- </combo_item>
- <combo_item length="1" name="Alwayssend" type="string">
- Toujours envoyer
- </combo_item>
- <combo_item length="1" name="Neversend" type="string">
- Ne jamais envoyer
- </combo_item>
+ <combo_box.item length="1" name="Askbeforesending" type="string" label="Demander avant d&apos;envoyer"/>
+ <combo_box.item length="1" name="Alwayssend" type="string" label="Toujours envoyer"/>
+ <combo_box.item length="1" name="Neversend" type="string" label="Ne jamais envoyer"/>
</combo_box>
<combo_box name="language_combobox" width="166">
- <combo_item name="System Default Language">
- Choix par défaut
- </combo_item>
- <combo_item length="1" name="English" type="string">
- English (Anglais)
- </combo_item>
- <combo_item length="1" name="Danish" type="string">
- Dansk (Danois) - Bêta
- </combo_item>
- <combo_item length="1" name="Deutsch(German)" type="string">
- Deutsch (Allemand) - Bêta
- </combo_item>
- <combo_item name="Spanish">
- Español (Espagnol) - Bêta
- </combo_item>
- <combo_item name="French">
- Français - Bêta
- </combo_item>
+ <combo_box.item name="System Default Language" label="Choix par défaut"/>
+ <combo_box.item length="1" name="English" type="string" label="English (Anglais)"/>
+ <combo_box.item length="1" name="Danish" type="string" label="Dansk (Danois) - Bêta"/>
+ <combo_box.item length="1" name="Deutsch(German)" type="string" label="Deutsch (Allemand) - Bêta"/>
+ <combo_box.item name="Spanish" label="Español (Espagnol) - Bêta"/>
+ <combo_box.item name="French" label="Français - Bêta"/>
+ <combo_box.item name="Hungarian" label="Magyar (Hongrois) - Bêta"/>
+ <combo_box.item name="Polish" label="Polski (Polonais) - Bêta"/>
+ <combo_box.item name="Portugese" label="Portugués (Portugais) - Bêta"/>
+ <combo_box.item name="Russian" label="Русский (Russe) - Bêta"/>
+ <combo_box.item name="Ukrainian" label="Українська (Ukrainien) - Bêta"/>
+ <combo_box.item length="1" name="Chinese" type="string" label="中文 (简体) (Chinois) - Bêta"/>
+ <combo_box.item length="1" name="(Japanese)" type="string" label="日本語 (Japonais) - Bêta"/>
+ <combo_box.item length="1" name="(Korean)" type="string" label="한국어 (Coréen) - Bêta"/>
<combo_item name="Italian">
Italiano (Italien) - Bêta
</combo_item>
- <combo_item name="Hungarian">
- Magyar (Hongrois) - Bêta
- </combo_item>
<combo_item name="Dutch">
Nederlands (Néerlandais) - Bêta
</combo_item>
- <combo_item name="Polish">
- Polski (Polonais) - Bêta
- </combo_item>
- <combo_item name="Portugese">
- Portugués (Portugais) - Bêta
- </combo_item>
- <combo_item name="Russian">
- Русский (Russe) - Bêta
</combo_item>
<combo_item name="Turkish">
Türkçe (Turc) - Bêta
- </combo_item>
- <combo_item name="Ukrainian">
- Українська (Ukrainien) - Bêta
- </combo_item>
- <combo_item length="1" name="Chinese" type="string">
- 中文 (简体) (Chinois) - Bêta
- </combo_item>
- <combo_item length="1" name="(Japanese)" type="string">
- 日本語 (Japonais) - Bêta
- </combo_item>
- <combo_item length="1" name="(Korean)" type="string">
- 한국어 (Coréen) - Bêta
- </combo_item>
</combo_box>
<check_box label="Partager la langue avec les objets" name="language_is_public" tool_tip="Cette option permet de faire connaître aux objets du Monde votre langue favorite."/>
</panel>
diff --git a/indra/newview/skins/default/xui/it/floater_about_land.xml b/indra/newview/skins/default/xui/it/floater_about_land.xml
index e4ad34bf50..4f57067cd2 100644
--- a/indra/newview/skins/default/xui/it/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/it/floater_about_land.xml
@@ -345,42 +345,18 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
</combo_item>
</combo_box>
<combo_box name="land category">
- <combo_item name="AnyCategory">
- Tutte le categorie
- </combo_item>
- <combo_item name="LindenLocation">
- Luogo dei Linden
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- Arte &amp; Cultura
- </combo_item>
- <combo_item name="Business">
- Affari
- </combo_item>
- <combo_item name="Educational">
- Educazione
- </combo_item>
- <combo_item name="Gaming">
- Gioco
- </combo_item>
- <combo_item name="Hangout">
- Divertimento
- </combo_item>
- <combo_item name="NewcomerFriendly">
- Accoglienza nuovi residenti
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- Parchi &amp; Natura
- </combo_item>
- <combo_item name="Residential">
- Residenziale
- </combo_item>
- <combo_item name="Shopping">
- Shopping
- </combo_item>
- <combo_item name="Other">
- Altro
- </combo_item>
+ <combo_box.item name="AnyCategory" label="Tutte le categorie"/>
+ <combo_box.item name="LindenLocation" label="Luogo dei Linden"/>
+ <combo_box.item name="Arts&amp;Culture" label="Arte &amp; Cultura"/>
+ <combo_box.item name="Business" label="Affari"/>
+ <combo_box.item name="Educational" label="Educazione"/>
+ <combo_box.item name="Gaming" label="Gioco"/>
+ <combo_box.item name="Hangout" label="Divertimento"/>
+ <combo_box.item name="NewcomerFriendly" label="Accoglienza nuovi residenti"/>
+ <combo_box.item name="Parks&amp;Nature" label="Parchi &amp; Natura"/>
+ <combo_box.item name="Residential" label="Residenziale"/>
+ <combo_box.item name="Shopping" label="Shopping"/>
+ <combo_box.item name="Other" label="Altro"/>
</combo_box>
<button label="?" label_selected="?" name="?"/>
<check_box label="Contenuto Mature" name="MatureCheck" tool_tip=" "/>
@@ -412,15 +388,9 @@ Solamente terreni più grandi possono essere abilitati nella ricerca.
Rotte dei teleport:
</text>
<combo_box width="140" name="landing type" tool_tip="Rotte dei teleport -- seleziona come vuoi organizzare i teleport nella tua terra.">
- <combo_item name="Blocked">
- Bloccati
- </combo_item>
- <combo_item name="LandingPoint">
- Punto di atterraggio
- </combo_item>
- <combo_item name="Anywhere">
- Ovunque
- </combo_item>
+ <combo_box.item name="Blocked" label="Bloccati"/>
+ <combo_box.item name="LandingPoint" label="Punto di atterraggio"/>
+ <combo_box.item name="Anywhere" label="Ovunque"/>
</combo_box>
<string name="push_restrict_text">
Nessuna spinta
@@ -501,12 +471,8 @@ Media:
<check_box label="Permetti accesso al gruppo: [GROUP]" name="GroupCheck" tool_tip="Imposta il gruppo nel pannello generale."/>
<check_box label="Vendi pass a:" name="PassCheck" tool_tip="Permetti in questo terreno l&apos;accesso temporaneo"/>
<combo_box name="pass_combo">
- <combo_item name="Anyone">
- Chiunque
- </combo_item>
- <combo_item name="Group">
- Gruppo
- </combo_item>
+ <combo_box.item name="Anyone" label="Chiunque"/>
+ <combo_box.item name="Group" label="Gruppo"/>
</combo_box>
<spinner label="Prezzo in L$:" name="PriceSpin"/>
<spinner label="Ore di accesso:" name="HoursSpin"/>
diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
index aadd86d055..620cd33c0a 100644
--- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml
@@ -10,15 +10,9 @@
</radio_group>
<check_box label="Mostra il punto di partenza nella schermata d&apos;inizio" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox" width="166">
- <combo_item name="Never">
- Mai
- </combo_item>
- <combo_item name="Show Temporarily">
- Mostra temporanemente
- </combo_item>
- <combo_item name="Always">
- Sempre
- </combo_item>
+ <combo_box.item name="Never" label="Mai"/>
+ <combo_box.item name="Show Temporarily" label="Mostra temporanemente"/>
+ <combo_box.item name="Always" label="Sempre"/>
</combo_box>
<check_box label="Nomi avatar in piccolo" name="small_avatar_names_checkbox"/>
<check_box label="Nascondi il mio nome sul mio schermo" name="show_my_name_checkbox"/>
@@ -80,50 +74,29 @@ contenuto di tipo:
&lt;Scrivi il nome della regione&gt;
</string>
<combo_box name="crash_behavior_combobox" width="166">
- <combo_item name="Askbeforesending">
- Chiedi prima di inviare
- </combo_item>
- <combo_item name="Alwayssend">
- Invia sempre
- </combo_item>
- <combo_item name="Neversend">
- Non inviare mai
- </combo_item>
+ <combo_box.item name="Askbeforesending" label="Chiedi prima di inviare"/>
+ <combo_box.item name="Alwayssend" label="Invia sempre"/>
+ <combo_box.item name="Neversend" label="Non inviare mai"/>
</combo_box>
<combo_box name="language_combobox" width="166">
- <combo_item name="System Default Language">
- Default di sistema
- </combo_item>
- <combo_item name="English">
- English
- </combo_item>
- <combo_item name="Danish">
- Dansk (Danese) - Beta
- </combo_item>
- <combo_item name="Deutsch(German)">
- Deutsch (Tedesco) - Beta
- </combo_item>
- <combo_item name="Spanish">
- Español (Spagnolo) - Beta
- </combo_item>
- <combo_item name="French">
- Français (Francese) - Beta
- </combo_item>
+ <combo_box.item name="System Default Language" label="Default di sistema"/>
+ <combo_box.item name="English" label="English"/>
+ <combo_box.item name="Danish" label="Dansk (Danese) - Beta"/>
+ <combo_box.item name="Deutsch(German)" label="Deutsch (Tedesco) - Beta"/>
+ <combo_box.item name="Spanish" label="Español (Spagnolo) - Beta"/>
+ <combo_box.item name="French" label="Français (Francese) - Beta"/>
+ <combo_box.item name="Hungarian" label="Magyar (Ungherese) - Beta"/>
+ <combo_box.item name="Polish" label="Polski (Polacco) - Beta"/>
+ <combo_box.item name="Portugese" label="Portugués (Portoghese) - Beta"/>
+ <combo_box.item name="Chinese" label="中文 (简体) (Cinese) - Beta"/>
+ <combo_box.item name="(Japanese)" label="日本語 (Giapponese) - Beta"/>
+ <combo_box.item name="(Korean)" label="한국어 (Coreano) - Beta"/>
<combo_item name="Italian">
Italiano - Beta
</combo_item>
- <combo_item name="Hungarian">
- Magyar (Ungherese) - Beta
- </combo_item>
<combo_item name="Dutch">
Nederlands (Olandese) - Beta
</combo_item>
- <combo_item name="Polish">
- Polski (Polacco) - Beta
- </combo_item>
- <combo_item name="Portugese">
- Portugués (Portoghese) - Beta
- </combo_item>
<combo_item name="Russian">
Русский (Russo) - Beta
</combo_item>
@@ -133,15 +106,6 @@ contenuto di tipo:
<combo_item name="Ukrainian">
Українська (Ukraino) - Beta
</combo_item>
- <combo_item name="Chinese">
- 中文 (简体) (Cinese) - Beta
- </combo_item>
- <combo_item name="(Japanese)">
- 日本語 (Giapponese) - Beta
- </combo_item>
- <combo_item name="(Korean)">
- 한국어 (Coreano) - Beta
- </combo_item>
</combo_box>
<check_box label="Condividi la tua lingua con gli oggetti" name="language_is_public" tool_tip="Questo fa in modo che gli oggetti inworld riconoscano la tua lingua."/>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/floater_about_land.xml b/indra/newview/skins/default/xui/ja/floater_about_land.xml
index c8195d8f38..26c8a46270 100644
--- a/indra/newview/skins/default/xui/ja/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about_land.xml
@@ -345,42 +345,18 @@
</combo_item>
</combo_box>
<combo_box name="land category">
- <combo_item name="AnyCategory">
- 全カテゴリー
- </combo_item>
- <combo_item name="LindenLocation">
- Linden所在地
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- アート&amp;カルチャー
- </combo_item>
- <combo_item name="Business">
- ビジネス
- </combo_item>
- <combo_item name="Educational">
- 教育的
- </combo_item>
- <combo_item name="Gaming">
- ゲーム
- </combo_item>
- <combo_item name="Hangout">
- たまり場
- </combo_item>
- <combo_item name="NewcomerFriendly">
- 新住人に好意的
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- 公園と自然
- </combo_item>
- <combo_item name="Residential">
- 住宅用
- </combo_item>
- <combo_item name="Shopping">
- ショッピング
- </combo_item>
- <combo_item name="Other">
- その他
- </combo_item>
+ <combo_box.item name="AnyCategory" label="全カテゴリー"/>
+ <combo_box.item name="LindenLocation" label="Linden所在地"/>
+ <combo_box.item name="Arts&amp;Culture" label="アート&amp;カルチャー"/>
+ <combo_box.item name="Business" label="ビジネス"/>
+ <combo_box.item name="Educational" label="教育的"/>
+ <combo_box.item name="Gaming" label="ゲーム"/>
+ <combo_box.item name="Hangout" label="たまり場"/>
+ <combo_box.item name="NewcomerFriendly" label="新住人に好意的"/>
+ <combo_box.item name="Parks&amp;Nature" label="公園と自然"/>
+ <combo_box.item name="Residential" label="住宅用"/>
+ <combo_box.item name="Shopping" label="ショッピング"/>
+ <combo_box.item name="Other" label="その他"/>
</combo_box>
<button label="?" label_selected="?" name="?"/>
<check_box label="Matureコンテンツ" name="MatureCheck" tool_tip=""/>
@@ -412,15 +388,9 @@
テレポート制限:
</text>
<combo_box name="landing type" tool_tip="Teleport Routing -- select how to handle teleports onto your land.">
- <combo_item length="1" name="Blocked" type="string">
- 不可
- </combo_item>
- <combo_item length="1" name="LandingPoint" type="string">
- 着地点
- </combo_item>
- <combo_item length="1" name="Anywhere" type="string">
- どこでも
- </combo_item>
+ <combo_box.item length="1" name="Blocked" type="string" label="不可"/>
+ <combo_box.item length="1" name="LandingPoint" type="string" label="着地点"/>
+ <combo_box.item length="1" name="Anywhere" type="string" label="どこでも"/>
</combo_box>
<string name="push_restrict_text">
プッシングを制限
@@ -499,12 +469,8 @@
<check_box label="グループ・アクセスを許可:[GROUP]" name="GroupCheck" tool_tip="[一般]タブで、グループを選択してください。"/>
<check_box label="入場許可を販売:" name="PassCheck" tool_tip="この区画への一時的なアクセスを許可"/>
<combo_box name="pass_combo">
- <combo_item name="Anyone">
- 誰でも
- </combo_item>
- <combo_item name="Group">
- グループ
- </combo_item>
+ <combo_box.item name="Anyone" label="誰でも"/>
+ <combo_box.item name="Group" label="グループ"/>
</combo_box>
<spinner label="価格(L$):" name="PriceSpin"/>
<spinner label="アクセス時間:" name="HoursSpin"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
index 83b21b87d2..3e3d62640f 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml
@@ -10,15 +10,9 @@
</radio_group>
<check_box label="ログイン画面にログイン位置を表示" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox">
- <combo_item name="Never">
- なし
- </combo_item>
- <combo_item name="Show Temporarily">
- 一時的に表示
- </combo_item>
- <combo_item name="Always">
- いつも
- </combo_item>
+ <combo_box.item name="Never" label="なし"/>
+ <combo_box.item name="Show Temporarily" label="一時的に表示"/>
+ <combo_box.item name="Always" label="いつも"/>
</combo_box>
<check_box label="小さなアバター名" name="small_avatar_names_checkbox"/>
<check_box label="画面上で自分の名前を隠す" name="show_my_name_checkbox"/>
@@ -79,68 +73,34 @@
&lt;地域の名前入力&gt;
</string>
<combo_box name="crash_behavior_combobox">
- <combo_item length="1" name="Askbeforesending" type="string">
- 送る前に確認する
- </combo_item>
- <combo_item length="1" name="Alwayssend" type="string">
- 常に送信
- </combo_item>
- <combo_item length="1" name="Neversend" type="string">
- 送信しない
- </combo_item>
+ <combo_box.item length="1" name="Askbeforesending" type="string" label="送る前に確認する"/>
+ <combo_box.item length="1" name="Alwayssend" type="string" label="常に送信"/>
+ <combo_box.item length="1" name="Neversend" type="string" label="送信しない"/>
</combo_box>
<combo_box name="language_combobox">
- <combo_item length="1" name="System Default Language" type="string">
- システム・デフォルト
- </combo_item>
- <combo_item length="1" name="English" type="string">
- English (英語)
- </combo_item>
- <combo_item length="1" name="Danish" type="string">
- Dansk (デンマーク語) – ベータ
- </combo_item>
- <combo_item length="1" name="Deutsch(German)" type="string">
- Deutsch (ドイツ語) – ベータ
- </combo_item>
- <combo_item length="1" name="Spanish" type="string">
- Español (スペイン語) – ベータ
- </combo_item>
- <combo_item length="1" name="French" type="string">
- Français (フランス語) – ベータ
- </combo_item>
+ <combo_box.item length="1" name="System Default Language" type="string" label="システム・デフォルト"/>
+ <combo_box.item length="1" name="English" type="string" label="English (英語)"/>
+ <combo_box.item length="1" name="Danish" type="string" label="Dansk (デンマーク語) – ベータ"/>
+ <combo_box.item length="1" name="Deutsch(German)" type="string" label="Deutsch (ドイツ語) – ベータ"/>
+ <combo_box.item length="1" name="Spanish" type="string" label="Español (スペイン語) – ベータ"/>
+ <combo_box.item length="1" name="French" type="string" label="Français (フランス語) – ベータ"/>
+ <combo_box.item name="Hungarian" label="Magyar (ハンガリー語) - ベータ"/>
+ <combo_box.item name="Polish" label="Polski (ポーランド語) - ベータ"/>
+ <combo_box.item length="1" name="Portugese" type="string" label="Português (ポルトガル語) – ベータ"/>
+ <combo_box.item name="Russian" label="Русский (ロシア語) - ベータ"/>
+ <combo_box.item name="Ukrainian" label="Українська (ウクライナ語) - ベータ"/>
+ <combo_box.item length="1" name="Chinese" type="string" label="中文 (简体) (中国語) - ベータ"/>
+ <combo_box.item length="1" name="(Japanese)" type="string" label="日本語 – ベータ"/>
+ <combo_box.item length="1" name="(Korean)" type="string" label="한국어 (韓国語) – ベータ"/>
<combo_item name="Italian">
Italiano (イタリア語) - ベータ
</combo_item>
- <combo_item name="Hungarian">
- Magyar (ハンガリー語) - ベータ
- </combo_item>
<combo_item name="Dutch">
Nederlands (オランダ語) - ベータ
</combo_item>
- <combo_item name="Polish">
- Polski (ポーランド語) - ベータ
- </combo_item>
- <combo_item length="1" name="Portugese" type="string">
- Português (ポルトガル語) – ベータ
- </combo_item>
- <combo_item name="Russian">
- Русский (ロシア語) - ベータ
</combo_item>
<combo_item name="Turkish">
Türkçe (トルコ語) - ベータ
- </combo_item>
- <combo_item name="Ukrainian">
- Українська (ウクライナ語) - ベータ
- </combo_item>
- <combo_item length="1" name="Chinese" type="string">
- 中文 (简体) (中国語) - ベータ
- </combo_item>
- <combo_item length="1" name="(Japanese)" type="string">
- 日本語 – ベータ
- </combo_item>
- <combo_item length="1" name="(Korean)" type="string">
- 한국어 (韓国語) – ベータ
- </combo_item>
</combo_box>
<check_box label="言語をオブジェクトと共有" name="language_is_public" tool_tip="優先言語をインワールドのオブジェクトが認識する"/>
</panel>
diff --git a/indra/newview/skins/default/xui/nl/floater_about_land.xml b/indra/newview/skins/default/xui/nl/floater_about_land.xml
index a3e3b246fe..44c2ebccf7 100644
--- a/indra/newview/skins/default/xui/nl/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/nl/floater_about_land.xml
@@ -343,42 +343,18 @@ of opgedeeld.
</combo_item>
</combo_box>
<combo_box name="land category">
- <combo_item name="AnyCategory">
- Alle categorieën
- </combo_item>
- <combo_item name="LindenLocation">
- Linden Locatie
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- Kunst &amp; Cultuur
- </combo_item>
- <combo_item name="Business">
- Zakelijk
- </combo_item>
- <combo_item name="Educational">
- Educatief
- </combo_item>
- <combo_item name="Gaming">
- Spelen
- </combo_item>
- <combo_item name="Hangout">
- Ontmoetingsplaats
- </combo_item>
- <combo_item name="NewcomerFriendly">
- Nieuwkomervriendelijk
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- Parken &amp; Natuur
- </combo_item>
- <combo_item name="Residential">
- Woongebied
- </combo_item>
- <combo_item name="Shopping">
- Winkelen
- </combo_item>
- <combo_item name="Other">
- Anders
- </combo_item>
+ <combo_box.item name="AnyCategory" label="Alle categorieën"/>
+ <combo_box.item name="LindenLocation" label="Linden Locatie"/>
+ <combo_box.item name="Arts&amp;Culture" label="Kunst &amp; Cultuur"/>
+ <combo_box.item name="Business" label="Zakelijk"/>
+ <combo_box.item name="Educational" label="Educatief"/>
+ <combo_box.item name="Gaming" label="Spelen"/>
+ <combo_box.item name="Hangout" label="Ontmoetingsplaats"/>
+ <combo_box.item name="NewcomerFriendly" label="Nieuwkomervriendelijk"/>
+ <combo_box.item name="Parks&amp;Nature" label="Parken &amp; Natuur"/>
+ <combo_box.item name="Residential" label="Woongebied"/>
+ <combo_box.item name="Shopping" label="Winkelen"/>
+ <combo_box.item name="Other" label="Anders"/>
</combo_box>
<button label="?" label_selected="?" name="?"/>
<check_box label="Mature inhoud" name="MatureCheck" tool_tip=" "/>
@@ -410,15 +386,9 @@ of opgedeeld.
Teleport routering:
</text>
<combo_box name="landing type" tool_tip="Teleport routering -- selecteer hoe teleports naar uw land moeten worden afgehandeld.">
- <combo_item name="Blocked">
- Geblokkeerd
- </combo_item>
- <combo_item name="LandingPoint">
- Landingsplaats
- </combo_item>
- <combo_item name="Anywhere">
- Overal
- </combo_item>
+ <combo_box.item name="Blocked" label="Geblokkeerd"/>
+ <combo_box.item name="LandingPoint" label="Landingsplaats"/>
+ <combo_box.item name="Anywhere" label="Overal"/>
</combo_box>
<string name="push_restrict_text">
Niet duwen
@@ -496,12 +466,8 @@ hebt geklikt.)
<check_box label="Groepstoegang toestaan: [GROUP]" name="GroupCheck" tool_tip="Stel de groep in op het tabblad Algemeen"/>
<check_box label="Verkoop toegangspassen aan:" name="PassCheck" tool_tip="Tijdelijke toegang tot dit perceel toestaan"/>
<combo_box name="pass_combo" left_delta="190">
- <combo_item name="Anyone">
- Iedereen
- </combo_item>
- <combo_item name="Group">
- Groep
- </combo_item>
+ <combo_box.item name="Anyone" label="Iedereen"/>
+ <combo_box.item name="Group" label="Groep"/>
</combo_box>
<spinner label="Prijs in L$:" name="PriceSpin" label_width="168" width="228" />
<spinner label="Toegangsuren" name="HoursSpin" label_width="168" width="228" />
diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml
index 5f4bf4ece6..7612212105 100755
--- a/indra/newview/skins/default/xui/pl/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml
@@ -343,42 +343,18 @@ Jedynie większe posiadłości mogą być umieszczone w bazie wyszukiwarki.
</combo_item>
</combo_box>
<combo_box name="land category">
- <combo_item name="AnyCategory">
- Każda
- </combo_item>
- <combo_item name="LindenLocation">
- Linden Lokacja
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- Sztuka i Kultura
- </combo_item>
- <combo_item name="Business">
- Biznes
- </combo_item>
- <combo_item name="Educational">
- Edukacyjna
- </combo_item>
- <combo_item name="Gaming">
- Gra
- </combo_item>
- <combo_item name="Hangout">
- Poznawanie ludzi
- </combo_item>
- <combo_item name="NewcomerFriendly">
- Przyjazna dla nowych
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- Parki i Natura
- </combo_item>
- <combo_item name="Residential">
- Mieszkalna
- </combo_item>
- <combo_item name="Shopping">
- Komercja/Sklepy
- </combo_item>
- <combo_item name="Other">
- Inna
- </combo_item>
+ <combo_box.item name="AnyCategory" label="Każda"/>
+ <combo_box.item name="LindenLocation" label="Linden Lokacja"/>
+ <combo_box.item name="Arts&amp;Culture" label="Sztuka i Kultura"/>
+ <combo_box.item name="Business" label="Biznes"/>
+ <combo_box.item name="Educational" label="Edukacyjna"/>
+ <combo_box.item name="Gaming" label="Gra"/>
+ <combo_box.item name="Hangout" label="Poznawanie ludzi"/>
+ <combo_box.item name="NewcomerFriendly" label="Przyjazna dla nowych"/>
+ <combo_box.item name="Parks&amp;Nature" label="Parki i Natura"/>
+ <combo_box.item name="Residential" label="Mieszkalna"/>
+ <combo_box.item name="Shopping" label="Komercja/Sklepy"/>
+ <combo_box.item name="Other" label="Inna"/>
</combo_box>
<button label="?" label_selected="?" name="?"/>
<check_box label="Treść &apos;Mature&apos;" name="MatureCheck" tool_tip=""/>
@@ -410,15 +386,9 @@ Jedynie większe posiadłości mogą być umieszczone w bazie wyszukiwarki.
Trasa Teleportacji:
</text>
<combo_box name="landing type" tool_tip="Trasa Teleportacj-ustaw w jaki sposób będzie sę odbywać proces telportacji w posiadłości.">
- <combo_item length="1" name="Blocked" type="string">
- Zablokowana
- </combo_item>
- <combo_item length="1" name="LandingPoint" type="string">
- Punkt Lądowania
- </combo_item>
- <combo_item length="1" name="Anywhere" type="string">
- Gdziekolwiek
- </combo_item>
+ <combo_box.item length="1" name="Blocked" type="string" label="Zablokowana"/>
+ <combo_box.item length="1" name="LandingPoint" type="string" label="Punkt Lądowania"/>
+ <combo_box.item length="1" name="Anywhere" type="string" label="Gdziekolwiek"/>
</combo_box>
<string name="push_restrict_text">
Popychanie niedozwolone
@@ -497,12 +467,8 @@ Mediów:
<check_box label="Udostępnij wejście grupie: [GROUP]" name="GroupCheck" tool_tip="Ustaw grupę w głównej zakładce"/>
<check_box label="Sprzedaj wejściówki:" name="PassCheck" tool_tip="Otwórz tymczasowy dostęp do tej posiadłości"/>
<combo_box name="pass_combo">
- <combo_item name="Anyone">
- Każdemu
- </combo_item>
- <combo_item name="Group">
- Grupie
- </combo_item>
+ <combo_box.item name="Anyone" label="Każdemu"/>
+ <combo_box.item name="Group" label="Grupie"/>
</combo_box>
<spinner label="Cena w L$:" name="PriceSpin"/>
<spinner label="Ilość godzin dostępu:" name="HoursSpin"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml
index 4426378075..fee7ed60f5 100644
--- a/indra/newview/skins/default/xui/pt/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml
@@ -343,42 +343,18 @@ Apenas lotes maiores podem ser listados na busca.
</combo_item>
</combo_box>
<combo_box left="276" name="land category" width="146">
- <combo_item name="AnyCategory">
- Qualquer Categoria
- </combo_item>
- <combo_item name="LindenLocation">
- Locação Linden
- </combo_item>
- <combo_item name="Arts&amp;Culture">
- Artes e Cultura
- </combo_item>
- <combo_item name="Business">
- Negócios
- </combo_item>
- <combo_item name="Educational">
- Educacional
- </combo_item>
- <combo_item name="Gaming">
- Jogo
- </combo_item>
- <combo_item name="Hangout">
- Lazer
- </combo_item>
- <combo_item name="NewcomerFriendly">
- Amigável para novatos
- </combo_item>
- <combo_item name="Parks&amp;Nature">
- Parques e Natureza
- </combo_item>
- <combo_item name="Residential">
- Residencial
- </combo_item>
- <combo_item name="Shopping">
- Compras
- </combo_item>
- <combo_item name="Other">
- Outros
- </combo_item>
+ <combo_box.item name="AnyCategory" label="Qualquer Categoria"/>
+ <combo_box.item name="LindenLocation" label="Locação Linden"/>
+ <combo_box.item name="Arts&amp;Culture" label="Artes e Cultura"/>
+ <combo_box.item name="Business" label="Negócios"/>
+ <combo_box.item name="Educational" label="Educacional"/>
+ <combo_box.item name="Gaming" label="Jogo"/>
+ <combo_box.item name="Hangout" label="Lazer"/>
+ <combo_box.item name="NewcomerFriendly" label="Amigável para novatos"/>
+ <combo_box.item name="Parks&amp;Nature" label="Parques e Natureza"/>
+ <combo_box.item name="Residential" label="Residencial"/>
+ <combo_box.item name="Shopping" label="Compras"/>
+ <combo_box.item name="Other" label="Outros"/>
</combo_box>
<button label="?" label_selected="?" left="426" name="?"/>
<check_box label="Conteúdo Mature" name="MatureCheck" tool_tip=""/>
@@ -410,15 +386,9 @@ Apenas lotes maiores podem ser listados na busca.
Rota de Tele-transporte:
</text>
<combo_box left="140" name="landing type" tool_tip="Rota de Teletransporte -- Selecione como tratar os tele-transportes no seu lote." width="140">
- <combo_item length="1" name="Blocked" type="string">
- Bloqueado
- </combo_item>
- <combo_item length="1" name="LandingPoint" type="string">
- Ponto de Aterrissagem
- </combo_item>
- <combo_item length="1" name="Anywhere" type="string">
- Qualquer lugar
- </combo_item>
+ <combo_box.item length="1" name="Blocked" type="string" label="Bloqueado"/>
+ <combo_box.item length="1" name="LandingPoint" type="string" label="Ponto de Aterrissagem"/>
+ <combo_box.item length="1" name="Anywhere" type="string" label="Qualquer lugar"/>
</combo_box>
<string name="push_restrict_text">
Sem Empurrar
@@ -499,12 +469,8 @@ Mídia:
<check_box label="Permitir Acesso do Grupo: [GROUP]" name="GroupCheck" tool_tip="Definir grupo na aba Geral."/>
<check_box label="Vender passes para:" name="PassCheck" tool_tip="Permite acesso temporário a este terreno"/>
<combo_box name="pass_combo">
- <combo_item name="Anyone">
- Qualquer um
- </combo_item>
- <combo_item name="Group">
- Grupo
- </combo_item>
+ <combo_box.item name="Anyone" label="Qualquer um"/>
+ <combo_box.item name="Group" label="Grupo"/>
</combo_box>
<spinner label="Preço em L$:" name="PriceSpin"/>
<spinner label="Horas de Acesso:" name="HoursSpin"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
index fde3551b8b..d82330cc78 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
@@ -10,15 +10,9 @@
</radio_group>
<check_box label="Mostrar Posição Inicial na Tela de Login" name="show_location_checkbox"/>
<combo_box name="fade_out_combobox" width="166">
- <combo_item name="Never">
- Nunca
- </combo_item>
- <combo_item name="Show Temporarily">
- Mostrar Temporariamente
- </combo_item>
- <combo_item name="Always">
- Sempre
- </combo_item>
+ <combo_box.item name="Never" label="Nunca"/>
+ <combo_box.item name="Show Temporarily" label="Mostrar Temporariamente"/>
+ <combo_box.item name="Always" label="Sempre"/>
</combo_box>
<check_box label="Avatar com Nomes Pequenos" name="small_avatar_names_checkbox"/>
<check_box label="Ocultar meu Nome na minha Tela" name="show_my_name_checkbox"/>
@@ -80,49 +74,29 @@ conteúdo classificado:
Digite o nome da Região
</string>
<combo_box name="crash_behavior_combobox" width="166">
- <combo_item length="1" name="Askbeforesending" type="string">
- Perguntar antes de enviar
- </combo_item>
- <combo_item length="1" name="Alwayssend" type="string">
- Sempre enviar
- </combo_item>
- <combo_item length="1" name="Neversend" type="string">
- Nunca Enviar
- </combo_item>
+ <combo_box.item length="1" name="Askbeforesending" type="string" label="Perguntar antes de enviar"/>
+ <combo_box.item length="1" name="Alwayssend" type="string" label="Sempre enviar"/>
+ <combo_box.item length="1" name="Neversend" type="string" label="Nunca Enviar"/>
</combo_box>
<combo_box name="language_combobox" width="166">
- <combo_item name="System Default Language">
- Padrão do Sistema
- </combo_item>
- <combo_item name="English">
- English (Inglês)
- </combo_item>
- <combo_item name="Danish">
- Dansk (Dinamarquês) - Beta
- </combo_item>
- <combo_item name="Deutsch(German)">
- Deutsch (Alemão) - Beta
- </combo_item>
- <combo_item name="Spanish">
- Español (Espanhol) - Beta
- </combo_item>
- <combo_item name="French">
- Français (Francês) - Beta
- </combo_item>
+ <combo_box.item name="System Default Language" label="Padrão do Sistema"/>
+ <combo_box.item name="English" label="English (Inglês)"/>
+ <combo_box.item name="Danish" label="Dansk (Dinamarquês) - Beta"/>
+ <combo_box.item name="Deutsch(German)" label="Deutsch (Alemão) - Beta"/>
+ <combo_box.item name="Spanish" label="Español (Espanhol) - Beta"/>
+ <combo_box.item name="French" label="Français (Francês) - Beta"/>
+ <combo_box.item name="Hungarian" label="Magyar (Húngaro) - Beta"/>
+ <combo_box.item name="Polish" label="Polski (Polonês) - Beta"/>
+ <combo_box.item name="Portugese" label="Português - Beta"/>
+ <combo_box.item name="Chinese" label="中文 (简体) (Chinês) - Beta"/>
+ <combo_box.item name="(Japanese)" label="日本語 (Japonês) - Beta"/>
+ <combo_box.item name="(Korean)" label="한국어 (Coreano) - Beta"/>
<combo_item name="Italian">
Italiano - Beta
</combo_item>
- <combo_item name="Hungarian">
- Magyar (Húngaro) - Beta
- </combo_item>
<combo_item name="Dutch">
Nederlands (Holandês) - Beta
</combo_item>
- <combo_item name="Polish">
- Polski (Polonês) - Beta
- </combo_item>
- <combo_item name="Portugese">
- Português - Beta
</combo_item>
<combo_item name="Russian">
Русский (Russo) - Beta
@@ -132,16 +106,6 @@ conteúdo classificado:
</combo_item>
<combo_item name="Ukrainian">
Українська (Ucraniano) - Beta
- </combo_item>
- <combo_item name="Chinese">
- 中文 (简体) (Chinês) - Beta
- </combo_item>
- <combo_item name="(Japanese)">
- 日本語 (Japonês) - Beta
- </combo_item>
- <combo_item name="(Korean)">
- 한국어 (Coreano) - Beta
- </combo_item>
</combo_box>
<check_box label="Compartilhar a linguagem com objetos" name="language_is_public" tool_tip="Isto permite que os objetos no mundo conheçam sua linguagem preferida."/>
</panel>
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index 42872d85fb..e08193f785 100644
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -29,6 +29,8 @@
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
+
+#include "linden_common.h"
#include "../test/lltut.h"
#include "../llagentaccess.h"
diff --git a/indra/newview/tests/llcapabilitylistener_test.cpp b/indra/newview/tests/llcapabilitylistener_test.cpp
index f66ae9404f..b965379c9c 100644
--- a/indra/newview/tests/llcapabilitylistener_test.cpp
+++ b/indra/newview/tests/llcapabilitylistener_test.cpp
@@ -24,9 +24,9 @@
#include "../test/lltut.h"
#include "../llcapabilityprovider.h"
#include "lluuid.h"
-#include "llerrorcontrol.h"
#include "tests/networkio.h"
#include "tests/commtest.h"
+#include "tests/wrapllerrs.h"
#include "stringize.h"
#if defined(LL_WINDOWS)
@@ -104,28 +104,6 @@ namespace tut
typedef llcapears_group::object llcapears_object;
llcapears_group llsdmgr("llcapabilitylistener");
- struct CaptureError: public LLError::OverrideFatalFunction
- {
- CaptureError():
- LLError::OverrideFatalFunction(boost::bind(&CaptureError::operator(), this, _1))
- {
- LLError::setPrintLocation(false);
- }
-
- struct FatalException: public std::runtime_error
- {
- FatalException(const std::string& what): std::runtime_error(what) {}
- };
-
- void operator()(const std::string& message)
- {
- error = message;
- throw FatalException(message);
- }
-
- std::string error;
- };
-
template<> template<>
void llcapears_object::test<1>()
{
@@ -137,10 +115,10 @@ namespace tut
std::string threw;
try
{
- CaptureError capture;
+ WrapLL_ERRS capture;
regionPump.post(request);
}
- catch (const CaptureError::FatalException& e)
+ catch (const WrapLL_ERRS::FatalException& e)
{
threw = e.what();
}
@@ -184,10 +162,10 @@ namespace tut
std::string threw;
try
{
- CaptureError capture;
+ WrapLL_ERRS capture;
regionPump.post(request);
}
- catch (const CaptureError::FatalException& e)
+ catch (const WrapLL_ERRS::FatalException& e)
{
threw = e.what();
}
@@ -246,10 +224,10 @@ namespace tut
std::string threw;
try
{
- CaptureError capture;
+ WrapLL_ERRS capture;
regionPump.post(request);
}
- catch (const CaptureError::FatalException& e)
+ catch (const WrapLL_ERRS::FatalException& e)
{
threw = e.what();
}
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
new file mode 100644
index 0000000000..a84e796159
--- /dev/null
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -0,0 +1,416 @@
+/**
+ * @file lllogininstance_test.cpp
+ * @brief Test for lllogininstance.cpp.
+ *
+ * $LicenseInfo:firstyear=2008&license=internal$
+ * Copyright (c) 2008, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "../llviewerprecompiledheaders.h"
+// Own header
+#include "../lllogininstance.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+#include "llevents.h"
+
+#if defined(LL_WINDOWS)
+#pragma warning(disable: 4355) // using 'this' in base-class ctor initializer expr
+#endif
+
+// Constants
+const std::string VIEWERLOGIN_URI("viewerlogin_uri");
+const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");
+
+const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");
+
+// Link seams.
+
+//-----------------------------------------------------------------------------
+static LLEventStream gTestPump("test_pump");
+
+#include "lllogin.h"
+static std::string gLoginURI;
+static LLSD gLoginCreds;
+static bool gDisconnectCalled = false;
+class LLLogin::Impl
+{
+};
+LLLogin::LLLogin() {}
+LLLogin::~LLLogin() {}
+LLEventPump& LLLogin::getEventPump() { return gTestPump; }
+void LLLogin::connect(const std::string& uri, const LLSD& credentials)
+{
+ gLoginURI = uri;
+ gLoginCreds = credentials;
+}
+
+void LLLogin::disconnect()
+{
+ gDisconnectCalled = true;
+}
+
+//-----------------------------------------------------------------------------
+#include "../llviewernetwork.h"
+unsigned char gMACAddress[MAC_ADDRESS_BYTES] = {'1','2','3','4','5','6'}; /* Flawfinder: ignore */
+
+LLViewerLogin::LLViewerLogin() {}
+LLViewerLogin::~LLViewerLogin() {}
+void LLViewerLogin::getLoginURIs(std::vector<std::string>& uris) const
+{
+ uris.push_back(VIEWERLOGIN_URI);
+}
+std::string LLViewerLogin::getGridLabel() const { return VIEWERLOGIN_GRIDLABEL; }
+
+//-----------------------------------------------------------------------------
+#include "../llviewercontrol.h"
+LLControlGroup gSavedSettings("Global");
+std::string gCurrentVersion = "invalid_version";
+
+LLControlGroup::LLControlGroup(const std::string& name) :
+ LLInstanceTracker<LLControlGroup, std::string>(name){}
+LLControlGroup::~LLControlGroup() {}
+void LLControlGroup::setBOOL(const std::string& name, BOOL val) {}
+BOOL LLControlGroup::getBOOL(const std::string& name) { return FALSE; }
+U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
+void LLControlGroup::setString(const std::string& name, const std::string& val) {}
+std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
+BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; }
+BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; }
+
+#include "lluicolortable.h"
+void LLUIColorTable::saveUserSettings(void)const {}
+
+//-----------------------------------------------------------------------------
+#include "../llurlsimstring.h"
+LLURLSimString LLURLSimString::sInstance;
+bool LLURLSimString::parse() { return true; }
+
+//-----------------------------------------------------------------------------
+#include "../llfloatertos.h"
+#include "llfloaterreg.h"
+static std::string gTOSType;
+static LLEventPump * gTOSReplyPump = NULL;
+
+//static
+LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key, BOOL focus)
+{
+ gTOSType = name;
+ gTOSReplyPump = &LLEventPumps::instance().obtain(key["reply_pump"]);
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// LLNotifications
+class MockNotifications : public LLNotificationsInterface
+{
+ boost::function<void (const LLSD&, const LLSD&)> mResponder;
+ int mAddedCount;
+
+public:
+ MockNotifications() :
+ mResponder(0),
+ mAddedCount(0)
+ {
+ }
+
+ virtual ~MockNotifications() {}
+
+ /* virtual */ LLNotificationPtr add(
+ const std::string& name,
+ const LLSD& substitutions,
+ const LLSD& payload,
+ LLNotificationFunctorRegistry::ResponseFunctor functor)
+ {
+ mResponder = functor;
+ mAddedCount++;
+ return LLNotificationPtr((LLNotification*)NULL);
+ }
+
+ void sendYesResponse()
+ {
+ LLSD notification;
+ LLSD response;
+ response = 1;
+ mResponder(notification, response);
+ }
+
+ void sendNoResponse()
+ {
+ LLSD notification;
+ LLSD response;
+ response = 2;
+ mResponder(notification, response);
+ }
+
+ void sendBogusResponse()
+ {
+ LLSD notification;
+ LLSD response;
+ response = 666;
+ mResponder(notification, response);
+ }
+
+ int addedCount() { return mAddedCount; }
+};
+
+S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response)
+{
+ return response.asInteger();
+}
+
+// misc
+std::string xml_escape_string(const std::string& in)
+{
+ return in;
+}
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct lllogininstance_data
+ {
+ lllogininstance_data() : logininstance(LLLoginInstance::getInstance())
+ {
+ // Global initialization
+ gLoginURI.clear();
+ gLoginCreds.clear();
+ gDisconnectCalled = false;
+
+ gTOSType = ""; // Set to invalid value.
+ gTOSReplyPump = 0; // clear the callback.
+
+
+ gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE);
+ gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE);
+ gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
+ gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
+ gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
+ gSavedSettings.declareString("VersionChannelName", "test_version_string", "", FALSE);
+ gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
+ gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
+
+ credentials["first"] = "testfirst";
+ credentials["last"] = "testlast";
+ credentials["passwd"] = "testpass";
+
+ logininstance->setNotificationsInterface(&notifications);
+ }
+
+ LLLoginInstance* logininstance;
+ LLSD credentials;
+ MockNotifications notifications;
+ };
+
+ typedef test_group<lllogininstance_data> lllogininstance_group;
+ typedef lllogininstance_group::object lllogininstance_object;
+ lllogininstance_group llsdmgr("lllogininstance");
+
+ template<> template<>
+ void lllogininstance_object::test<1>()
+ {
+ set_test_name("Test Simple Success And Disconnect");
+
+ // Test default connect.
+ logininstance->connect(credentials);
+
+ ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
+
+ // Dummy success response.
+ LLSD response;
+ response["state"] = "online";
+ response["progress"] = 1.0;
+ response["transfer_rate"] = 7;
+ response["data"] = "test_data";
+
+ gTestPump.post(response);
+
+ ensure("Success response", logininstance->authSuccess());
+ ensure_equals("Test Response Data", logininstance->getResponse().asString(), "test_data");
+
+ logininstance->disconnect();
+
+ ensure_equals("Called Login Module Disconnect", gDisconnectCalled, true);
+
+ response.clear();
+ response["state"] = "offline";
+ response["progress"] = 0.0;
+ response["transfer_rate"] = 0;
+ response["data"] = "test_data";
+
+ gTestPump.post(response);
+
+ ensure("Disconnected", !(logininstance->authSuccess()));
+ }
+
+ template<> template<>
+ void lllogininstance_object::test<2>()
+ {
+ set_test_name("Test User TOS/Critical message Interaction");
+
+ const std::string test_uri = "testing-uri";
+
+ // Test default connect.
+ logininstance->connect(test_uri, credentials);
+
+ // connect should call LLLogin::connect to init gLoginURI and gLoginCreds.
+ ensure_equals("Default connect uri", gLoginURI, "testing-uri");
+ ensure_equals("Default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false);
+ ensure_equals("Default for read critical", gLoginCreds["params"]["read_critical"].asBoolean(), false);
+
+ // TOS failure response.
+ LLSD response;
+ response["state"] = "offline";
+ response["progress"] = 0.0;
+ response["transfer_rate"] = 7;
+ response["data"]["reason"] = "tos";
+ gTestPump.post(response);
+
+ ensure_equals("TOS Dialog type", gTOSType, "message_tos");
+ ensure("TOS callback given", gTOSReplyPump != 0);
+ gTOSReplyPump->post(false); // Call callback denying TOS.
+ ensure("No TOS, failed auth", logininstance->authFailure());
+
+ // Start again.
+ logininstance->connect(test_uri, credentials);
+ gTestPump.post(response); // Fail for tos again.
+ gTOSReplyPump->post(true); // Accept tos, should reconnect w/ agree_to_tos.
+ ensure_equals("Accepted agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), true);
+ ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess());
+
+ // Fail connection, attempt connect again.
+ // The new request should have reset agree to tos to default.
+ response["data"]["reason"] = "key"; // bad creds.
+ gTestPump.post(response);
+ ensure("TOS auth failure", logininstance->authFailure());
+
+ logininstance->connect(test_uri, credentials);
+ ensure_equals("Reset to default for agree to tos", gLoginCreds["params"]["agree_to_tos"].asBoolean(), false);
+
+ // Critical Message failure response.
+ logininstance->connect(test_uri, credentials);
+ response["data"]["reason"] = "critical"; // Change response to "critical message"
+ gTestPump.post(response);
+
+ ensure_equals("TOS Dialog type", gTOSType, "message_critical");
+ ensure("TOS callback given", gTOSReplyPump != 0);
+ gTOSReplyPump->post(true);
+ ensure_equals("Accepted read critical message", gLoginCreds["params"]["read_critical"].asBoolean(), true);
+ ensure("Incomplete login status", !logininstance->authFailure() && !logininstance->authSuccess());
+
+ // Fail then attempt new connection
+ response["data"]["reason"] = "key"; // bad creds.
+ gTestPump.post(response);
+ ensure("TOS auth failure", logininstance->authFailure());
+ logininstance->connect(test_uri, credentials);
+ ensure_equals("Default for agree to tos", gLoginCreds["params"]["read_critical"].asBoolean(), false);
+ }
+
+ template<> template<>
+ void lllogininstance_object::test<3>()
+ {
+ set_test_name("Test Mandatory Update User Accepts");
+
+ // Part 1 - Mandatory Update, with User accepts response.
+ // Test connect with update needed.
+ logininstance->connect(credentials);
+
+ ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
+
+ // Update needed failure response.
+ LLSD response;
+ response["state"] = "offline";
+ response["progress"] = 0.0;
+ response["transfer_rate"] = 7;
+ response["data"]["reason"] = "update";
+ gTestPump.post(response);
+
+ ensure_equals("Notification added", notifications.addedCount(), 1);
+
+ notifications.sendYesResponse();
+
+ ensure("Disconnected", !(logininstance->authSuccess()));
+ }
+
+ template<> template<>
+ void lllogininstance_object::test<4>()
+ {
+ set_test_name("Test Mandatory Update User Decline");
+
+ // Test connect with update needed.
+ logininstance->connect(credentials);
+
+ ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
+
+ // Update needed failure response.
+ LLSD response;
+ response["state"] = "offline";
+ response["progress"] = 0.0;
+ response["transfer_rate"] = 7;
+ response["data"]["reason"] = "update";
+ gTestPump.post(response);
+
+ ensure_equals("Notification added", notifications.addedCount(), 1);
+ notifications.sendNoResponse();
+
+ ensure("Disconnected", !(logininstance->authSuccess()));
+ }
+
+ template<> template<>
+ void lllogininstance_object::test<6>()
+ {
+ set_test_name("Test Optional Update User Accept");
+
+ // Part 3 - Mandatory Update, with bogus response.
+ // Test connect with update needed.
+ logininstance->connect(credentials);
+
+ ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
+
+ // Update needed failure response.
+ LLSD response;
+ response["state"] = "offline";
+ response["progress"] = 0.0;
+ response["transfer_rate"] = 7;
+ response["data"]["reason"] = "optional";
+ gTestPump.post(response);
+
+ ensure_equals("Notification added", notifications.addedCount(), 1);
+ notifications.sendYesResponse();
+
+ ensure("Disconnected", !(logininstance->authSuccess()));
+ }
+
+ template<> template<>
+ void lllogininstance_object::test<7>()
+ {
+ set_test_name("Test Optional Update User Denies");
+
+ // Part 3 - Mandatory Update, with bogus response.
+ // Test connect with update needed.
+ logininstance->connect(credentials);
+
+ ensure_equals("Default connect uri", gLoginURI, VIEWERLOGIN_URI);
+
+ // Update needed failure response.
+ LLSD response;
+ response["state"] = "offline";
+ response["progress"] = 0.0;
+ response["transfer_rate"] = 7;
+ response["data"]["reason"] = "optional";
+ gTestPump.post(response);
+
+ ensure_equals("Notification added", notifications.addedCount(), 1);
+ notifications.sendNoResponse();
+
+ // User skips, should be reconnecting.
+ ensure_equals("reconnect uri", gLoginURI, VIEWERLOGIN_URI);
+ ensure_equals("skipping optional update", gLoginCreds["params"]["skipoptional"].asBoolean(), true);
+ }
+}
diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp
new file mode 100644
index 0000000000..c94ba0a3e8
--- /dev/null
+++ b/indra/newview/tests/llxmlrpclistener_test.cpp
@@ -0,0 +1,230 @@
+/*
+ * @file llxmlrpclistener_test.cpp
+ * @author Nat Goodspeed
+ * @date 2009-03-20
+ * @brief Test for llxmlrpclistener.
+ *
+ * $LicenseInfo:firstyear=2009&license=internal$
+ * Copyright (c) 2009, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "../llviewerprecompiledheaders.h"
+// associated header
+#include "../llxmlrpclistener.h"
+// STL headers
+#include <iomanip>
+// std headers
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+#include "../llxmlrpctransaction.h"
+#include "llevents.h"
+#include "lleventfilter.h"
+#include "llsd.h"
+#include "llcontrol.h"
+#include "tests/wrapllerrs.h"
+
+LLControlGroup gSavedSettings("Global");
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ struct data
+ {
+ data():
+ pumps(LLEventPumps::instance()),
+ uri("http://127.0.0.1:8000")
+ {
+ // These variables are required by machinery used by
+ // LLXMLRPCTransaction. The values reflect reality for this test
+ // executable; hopefully these values are correct.
+ gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist
+ gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist
+ }
+
+ // LLEventPump listener signature
+ bool captureReply(const LLSD& r)
+ {
+ reply = r;
+ return false;
+ }
+
+ LLSD reply;
+ LLEventPumps& pumps;
+ std::string uri;
+ };
+ typedef test_group<data> llxmlrpclistener_group;
+ typedef llxmlrpclistener_group::object object;
+ llxmlrpclistener_group llxmlrpclistenergrp("llxmlrpclistener");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("request validation");
+ WrapLL_ERRS capture;
+ LLSD request;
+ request["uri"] = uri;
+ std::string threw;
+ try
+ {
+ pumps.obtain("LLXMLRPCTransaction").post(request);
+ }
+ catch (const WrapLL_ERRS::FatalException& e)
+ {
+ threw = e.what();
+ }
+ ensure_contains("threw exception", threw, "missing params");
+ ensure_contains("identified missing", threw, "method");
+ ensure_contains("identified missing", threw, "reply");
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("param types validation");
+ WrapLL_ERRS capture;
+ LLSD request;
+ request["uri"] = uri;
+ request["method"] = "hello";
+ request["reply"] = "reply";
+ LLSD& params(request["params"]);
+ params["who"]["specifically"] = "world"; // LLXMLRPCListener only handles scalar params
+ std::string threw;
+ try
+ {
+ pumps.obtain("LLXMLRPCTransaction").post(request);
+ }
+ catch (const WrapLL_ERRS::FatalException& e)
+ {
+ threw = e.what();
+ }
+ ensure_contains("threw exception", threw, "unknown type");
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("success case");
+ LLSD request;
+ request["uri"] = uri;
+ request["method"] = "hello";
+ request["reply"] = "reply";
+ LLSD& params(request["params"]);
+ params["who"] = "world";
+ // Set up a timeout filter so we don't spin forever waiting.
+ LLEventTimeout watchdog;
+ // Connect the timeout filter to the reply pump.
+ LLTempBoundListener temp(
+ pumps.obtain("reply").
+ listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
+ // Now connect our target listener to the timeout filter.
+ watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
+ // Kick off the request...
+ reply.clear();
+ pumps.obtain("LLXMLRPCTransaction").post(request);
+ // Set the timer
+ F32 timeout(10);
+ watchdog.eventAfter(timeout, LLSD().insert("timeout", 0));
+ // and pump "mainloop" until we get something, whether from
+ // LLXMLRPCListener or from the watchdog filter.
+ LLTimer timer;
+ F32 start = timer.getElapsedTimeF32();
+ LLEventPump& mainloop(pumps.obtain("mainloop"));
+ while (reply.isUndefined())
+ {
+ mainloop.post(LLSD());
+ }
+ ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
+ ensure_equals(reply["responses"]["hi_there"].asString(), "Hello, world!");
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("bogus method");
+ LLSD request;
+ request["uri"] = uri;
+ request["method"] = "goodbye";
+ request["reply"] = "reply";
+ LLSD& params(request["params"]);
+ params["who"] = "world";
+ // Set up a timeout filter so we don't spin forever waiting.
+ LLEventTimeout watchdog;
+ // Connect the timeout filter to the reply pump.
+ LLTempBoundListener temp(
+ pumps.obtain("reply").
+ listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
+ // Now connect our target listener to the timeout filter.
+ watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
+ // Kick off the request...
+ reply.clear();
+ pumps.obtain("LLXMLRPCTransaction").post(request);
+ // Set the timer
+ F32 timeout(10);
+ watchdog.eventAfter(timeout, LLSD().insert("timeout", 0));
+ // and pump "mainloop" until we get something, whether from
+ // LLXMLRPCListener or from the watchdog filter.
+ LLTimer timer;
+ F32 start = timer.getElapsedTimeF32();
+ LLEventPump& mainloop(pumps.obtain("mainloop"));
+ while (reply.isUndefined())
+ {
+ mainloop.post(LLSD());
+ }
+ ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
+ ensure_equals("XMLRPC error", reply["status"].asString(), "XMLRPCError");
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("bad type");
+ LLSD request;
+ request["uri"] = uri;
+ request["method"] = "getdict";
+ request["reply"] = "reply";
+ (void)request["params"];
+ // Set up a timeout filter so we don't spin forever waiting.
+ LLEventTimeout watchdog;
+ // Connect the timeout filter to the reply pump.
+ LLTempBoundListener temp(
+ pumps.obtain("reply").
+ listen("watchdog", boost::bind(&LLEventTimeout::post, boost::ref(watchdog), _1)));
+ // Now connect our target listener to the timeout filter.
+ watchdog.listen("captureReply", boost::bind(&data::captureReply, this, _1));
+ // Kick off the request...
+ reply.clear();
+ pumps.obtain("LLXMLRPCTransaction").post(request);
+ // Set the timer
+ F32 timeout(10);
+ watchdog.eventAfter(timeout, LLSD().insert("timeout", 0));
+ // and pump "mainloop" until we get something, whether from
+ // LLXMLRPCListener or from the watchdog filter.
+ LLTimer timer;
+ F32 start = timer.getElapsedTimeF32();
+ LLEventPump& mainloop(pumps.obtain("mainloop"));
+ while (reply.isUndefined())
+ {
+ mainloop.post(LLSD());
+ }
+ ensure("timeout works", (timer.getElapsedTimeF32() - start) < (timeout + 1));
+ ensure_equals(reply["status"].asString(), "BadType");
+ ensure_contains("bad type", reply["responses"]["nested_dict"].asString(), "bad XMLRPC type");
+ }
+} // namespace tut
+
+/*****************************************************************************
+* Resolve link errors: use real machinery here, since we intend to exchange
+* actual XML with a peer process.
+*****************************************************************************/
+// Including llxmlrpctransaction.cpp drags in the static LLXMLRPCListener
+// instantiated there. That's why it works to post requests to the LLEventPump
+// named "LLXMLRPCTransaction".
+#include "../llxmlrpctransaction.cpp"
+#include "llcontrol.cpp"
+#include "llxmltree.cpp"
+#include "llxmlparser.cpp"
diff --git a/indra/newview/tests/test_llxmlrpc_peer.py b/indra/newview/tests/test_llxmlrpc_peer.py
new file mode 100644
index 0000000000..cb8f7d26c4
--- /dev/null
+++ b/indra/newview/tests/test_llxmlrpc_peer.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+"""\
+@file test_llxmlrpc_peer.py
+@author Nat Goodspeed
+@date 2008-10-09
+@brief This script asynchronously runs the executable (with args) specified on
+ the command line, returning its result code. While that executable is
+ running, we provide dummy local services for use by C++ tests.
+
+$LicenseInfo:firstyear=2008&license=viewergpl$
+Copyright (c) 2008, Linden Research, Inc.
+$/LicenseInfo$
+"""
+
+import os
+import sys
+from threading import Thread
+from SimpleXMLRPCServer import SimpleXMLRPCServer
+
+mydir = os.path.dirname(__file__) # expected to be .../indra/newview/tests/
+sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
+sys.path.insert(1, os.path.join(mydir, os.pardir, os.pardir, "llmessage", "tests"))
+from testrunner import run, debug
+
+class TestServer(SimpleXMLRPCServer):
+ def _dispatch(self, method, params):
+ try:
+ func = getattr(self, method)
+ except AttributeError:
+ raise Exception('method "%s" is not supported' % method)
+ else:
+ # LLXMLRPCListener constructs XMLRPC parameters that arrive as a
+ # 1-tuple containing a dict.
+ return func(**(params[0]))
+
+ def hello(self, who):
+ # LLXMLRPCListener expects a dict return.
+ return {"hi_there": "Hello, %s!" % who}
+
+ def getdict(self):
+ return dict(nested_dict=dict(a=17, b=5))
+
+ def log_request(self, code, size=None):
+ # For present purposes, we don't want the request splattered onto
+ # stderr, as it would upset devs watching the test run
+ pass
+
+ def log_error(self, format, *args):
+ # Suppress error output as well
+ pass
+
+class ServerRunner(Thread):
+ def run(self):
+ server = TestServer(('127.0.0.1', 8000))
+ debug("Starting XMLRPC server...\n")
+ server.serve_forever()
+
+if __name__ == "__main__":
+ sys.exit(run(server=ServerRunner(name="xmlrpc"), *sys.argv[1:]))
diff --git a/indra/newview/tr.lproj/language.txt b/indra/newview/tr.lproj/language.txt
new file mode 100644
index 0000000000..44266bf283
--- /dev/null
+++ b/indra/newview/tr.lproj/language.txt
@@ -0,0 +1 @@
+tr \ No newline at end of file
diff --git a/indra/newview/uk.lproj/language.txt b/indra/newview/uk.lproj/language.txt
new file mode 100644
index 0000000000..fbc658f6f9
--- /dev/null
+++ b/indra/newview/uk.lproj/language.txt
@@ -0,0 +1 @@
+uk \ No newline at end of file
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index d175a26531..6fc755b229 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1,736 +1,766 @@
-#!/usr/bin/python
-# @file viewer_manifest.py
-# @author Ryan Williams
-# @brief Description of all installer viewer files, and methods for packaging
-# them into installers for all supported platforms.
-#
-# $LicenseInfo:firstyear=2006&license=viewergpl$
-#
-# Copyright (c) 2006-2009, Linden Research, Inc.
-#
-# Second Life Viewer Source Code
-# The source code in this file ("Source Code") is provided by Linden Lab
-# to you under the terms of the GNU General Public License, version 2.0
-# ("GPL"), unless you have obtained a separate licensing agreement
-# ("Other License"), formally executed by you and Linden Lab. Terms of
-# the GPL can be found in doc/GPL-license.txt in this distribution, or
-# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
-#
-# There are special exceptions to the terms and conditions of the GPL as
-# it is applied to this Source Code. View the full text of the exception
-# in the file doc/FLOSS-exception.txt in this software distribution, or
-# online at
-# http://secondlifegrid.net/programs/open_source/licensing/flossexception
-#
-# By copying, modifying or distributing this software, you acknowledge
-# that you have read and understood your obligations described above,
-# and agree to abide by those obligations.
-#
-# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
-# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
-# COMPLETENESS OR PERFORMANCE.
-# $/LicenseInfo$
-import sys
-import os.path
-import re
-import tarfile
-viewer_dir = os.path.dirname(__file__)
-# add llmanifest library to our path so we don't have to muck with PYTHONPATH
-sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
-from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
-
-class ViewerManifest(LLManifest):
- def construct(self):
- super(ViewerManifest, self).construct()
- self.exclude("*.svn*")
- self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")
- self.path(src="../../etc/message.xml", dst="app_settings/message.xml")
-
- if self.prefix(src="app_settings"):
- self.exclude("logcontrol.xml")
- self.exclude("logcontrol-dev.xml")
- self.path("*.pem")
- self.path("*.ini")
- self.path("*.xml")
- self.path("*.db2")
-
- # include the entire shaders directory recursively
- self.path("shaders")
- # ... and the entire windlight directory
- self.path("windlight")
- self.end_prefix("app_settings")
-
- if self.prefix(src="character"):
- self.path("*.llm")
- self.path("*.xml")
- self.path("*.tga")
- self.end_prefix("character")
-
- # Include our fonts
- if self.prefix(src="fonts"):
- self.path("*.ttf")
- self.path("*.txt")
- self.end_prefix("fonts")
-
- # skins
- if self.prefix(src="skins"):
- self.path("paths.xml")
- # include the entire textures directory recursively
- if self.prefix(src="*/textures"):
- self.path("*/*.tga")
- self.path("*/*.j2c")
- self.path("*/*.jpg")
- self.path("*/*.png")
- self.path("*.tga")
- self.path("*.j2c")
- self.path("*.jpg")
- self.path("*.png")
- self.path("textures.xml")
- self.end_prefix("*/textures")
- self.path("*/xui/*/*.xml")
- self.path("*/xui/*/widgets/*.xml")
- self.path("*/*.xml")
-
- # Local HTML files (e.g. loading screen)
- if self.prefix(src="*/html"):
- self.path("*.png")
- self.path("*/*/*.html")
- self.path("*/*/*.gif")
- self.end_prefix("*/html")
- self.end_prefix("skins")
-
- # Files in the newview/ directory
- self.path("gpu_table.txt")
-
- def login_channel(self):
- """Channel reported for login and upgrade purposes ONLY;
- used for A/B testing"""
- # NOTE: Do not return the normal channel if login_channel
- # is not specified, as some code may branch depending on
- # whether or not this is present
- return self.args.get('login_channel')
-
- def grid(self):
- return self.args['grid']
- def channel(self):
- return self.args['channel']
- def channel_unique(self):
- return self.channel().replace("Second Life", "").strip()
- def channel_oneword(self):
- return "".join(self.channel_unique().split())
- def channel_lowerword(self):
- return self.channel_oneword().lower()
-
- def flags_list(self):
- """ Convenience function that returns the command-line flags
- for the grid"""
-
- # Set command line flags relating to the target grid
- grid_flags = ''
- if not self.default_grid():
- grid_flags = "--grid %(grid)s "\
- "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\
- {'grid':self.grid()}
-
- # set command line flags for channel
- channel_flags = ''
- if self.login_channel() and self.login_channel() != self.channel():
- # Report a special channel during login, but use default
- channel_flags = '--channel "%s"' % (self.login_channel())
- elif not self.default_channel():
- channel_flags = '--channel "%s"' % self.channel()
-
- # Deal with settings
- setting_flags = ''
- if not self.default_channel() or not self.default_grid():
- if self.default_grid():
- setting_flags = '--settings settings_%s.xml'\
- % self.channel_lowerword()
- else:
- setting_flags = '--settings settings_%s_%s.xml'\
- % (self.grid(), self.channel_lowerword())
-
- return " ".join((channel_flags, grid_flags, setting_flags)).strip()
-
-
-class WindowsManifest(ViewerManifest):
- def final_exe(self):
- if self.default_channel():
- if self.default_grid():
- return "SecondLife.exe"
- else:
- return "SecondLifePreview.exe"
- else:
- return ''.join(self.channel().split()) + '.exe'
-
-
- def construct(self):
- super(WindowsManifest, self).construct()
- # the final exe is complicated because we're not sure where it's coming from,
- # nor do we have a fixed name for the executable
- self.path(self.find_existing_file('debug/secondlife-bin.exe', 'release/secondlife-bin.exe', 'relwithdebinfo/secondlife-bin.exe'), dst=self.final_exe())
- # need to get the kdu dll from any of the build directories as well
- try:
- self.path(self.find_existing_file('../llkdu/%s/llkdu.dll' % self.args['configuration'],
- '../../libraries/i686-win32/lib/release/llkdu.dll'),
- dst='llkdu.dll')
- pass
- except:
- print "Skipping llkdu.dll"
- pass
- self.path(src="licenses-win32.txt", dst="licenses.txt")
-
- self.path("featuretable.txt")
-
- # For use in crash reporting (generates minidumps)
- self.path("dbghelp.dll")
-
- # For using FMOD for sound... DJS
- self.path("fmod.dll")
-
- # For textures
- if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""):
- self.path("openjpeg.dll")
- self.end_prefix()
-
- # Plugin host application
- if self.prefix(src='../llplugin/slplugin/%s' % self.args['configuration'], dst="llplugin"):
- self.path("slplugin.exe")
- self.end_prefix()
-
- # Media plugins - Flash (ActiveX)
- if self.prefix(src='../media_plugins/flash_activex/%s' % self.args['configuration'], dst="llplugin"):
- self.path("media_plugin_flash_activex.dll")
- self.end_prefix()
-
- # Media plugins - QuickTime
- if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
- self.path("media_plugin_quicktime.dll")
- self.end_prefix()
-
- # Media plugins - WebKit/Qt
- if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
- self.path("media_plugin_webkit.dll")
- self.end_prefix()
-
- # For WebKit/Qt plugin runtimes
- if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"):
- self.path("libeay32.dll")
- self.path("qtcore4.dll")
- self.path("qtgui4.dll")
- self.path("qtnetwork4.dll")
- self.path("qtopengl4.dll")
- self.path("qtwebkit4.dll")
- self.path("ssleay32.dll")
- self.end_prefix()
-
- # For WebKit/Qt plugin runtimes (image format plugins)
- if self.prefix(src="../../libraries/i686-win32/lib/release/imageformats", dst="llplugin/imageformats"):
- self.path("qgif4.dll")
- self.path("qico4.dll")
- self.path("qjpeg4.dll")
- self.path("qmng4.dll")
- self.path("qsvg4.dll")
- self.path("qtiff4.dll")
- self.end_prefix()
-
- # These need to be installed as a SxS assembly, currently a 'private' assembly.
- # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
- if self.prefix(src=self.args['configuration'], dst=""):
- if self.args['configuration'] == 'Debug':
- self.path("msvcr80d.dll")
- self.path("msvcp80d.dll")
- self.path("Microsoft.VC80.DebugCRT.manifest")
- else:
- self.path("msvcr80.dll")
- self.path("msvcp80.dll")
- self.path("Microsoft.VC80.CRT.manifest")
- self.end_prefix()
-
- # The config file name needs to match the exe's name.
- self.path(src="%s/secondlife-bin.exe.config" % self.args['configuration'], dst=self.final_exe() + ".config")
-
- # Vivox runtimes
- if self.prefix(src="vivox-runtime/i686-win32", dst=""):
- self.path("SLVoice.exe")
- self.path("alut.dll")
- self.path("vivoxsdk.dll")
- self.path("ortp.dll")
- self.path("wrap_oal.dll")
- self.end_prefix()
-
- # pull in the crash logger and updater from other projects
- self.path(src=self.find_existing_file( # tag:"crash-logger" here as a cue to the exporter
- "../win_crash_logger/debug/windows-crash-logger.exe",
- "../win_crash_logger/release/windows-crash-logger.exe",
- "../win_crash_logger/relwithdebinfo/windows-crash-logger.exe"),
- dst="win_crash_logger.exe")
- self.path(src=self.find_existing_file(
- "../win_updater/debug/windows-updater.exe",
- "../win_updater/release/windows-updater.exe",
- "../win_updater/relwithdebinfo/windows-updater.exe"),
- dst="updater.exe")
-
- # For google-perftools tcmalloc allocator.
- if self.prefix(src="../../libraries/i686-win32/lib/release", dst=""):
- self.path("libtcmalloc_minimal.dll")
- self.end_prefix()
-
-
- def nsi_file_commands(self, install=True):
- def wpath(path):
- if path.endswith('/') or path.endswith(os.path.sep):
- path = path[:-1]
- path = path.replace('/', '\\')
- return path
-
- result = ""
- dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])]
- # sort deepest hierarchy first
- dest_files.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
- dest_files.reverse()
- out_path = None
- for pkg_file in dest_files:
- rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,''))
- installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file)))
- pkg_file = wpath(os.path.normpath(pkg_file))
- if installed_dir != out_path:
- if install:
- out_path = installed_dir
- result += 'SetOutPath ' + out_path + '\n'
- if install:
- result += 'File ' + pkg_file + '\n'
- else:
- result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
- # at the end of a delete, just rmdir all the directories
- if not install:
- deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
- # find all ancestors so that we don't skip any dirs that happened to have no non-dir children
- deleted_dirs = []
- for d in deleted_file_dirs:
- deleted_dirs.extend(path_ancestors(d))
- # sort deepest hierarchy first
- deleted_dirs.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
- deleted_dirs.reverse()
- prev = None
- for d in deleted_dirs:
- if d != prev: # skip duplicates
- result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n'
- prev = d
-
- return result
-
- def package_finish(self):
- # a standard map of strings for replacing in the templates
- substitution_strings = {
- 'version' : '.'.join(self.args['version']),
- 'version_short' : '.'.join(self.args['version'][:-1]),
- 'version_dashes' : '-'.join(self.args['version']),
- 'final_exe' : self.final_exe(),
- 'grid':self.args['grid'],
- 'grid_caps':self.args['grid'].upper(),
- # escape quotes becase NSIS doesn't handle them well
- 'flags':self.flags_list().replace('"', '$\\"'),
- 'channel':self.channel(),
- 'channel_oneword':self.channel_oneword(),
- 'channel_unique':self.channel_unique(),
- }
-
- version_vars = """
- !define INSTEXE "%(final_exe)s"
- !define VERSION "%(version_short)s"
- !define VERSION_LONG "%(version)s"
- !define VERSION_DASHES "%(version_dashes)s"
- """ % substitution_strings
- if self.default_channel():
- if self.default_grid():
- # release viewer
- installer_file = "Second_Life_%(version_dashes)s_Setup.exe"
- grid_vars_template = """
- OutFile "%(installer_file)s"
- !define INSTFLAGS "%(flags)s"
- !define INSTNAME "SecondLife"
- !define SHORTCUT "Second Life"
- !define URLNAME "secondlife"
- Caption "Second Life ${VERSION}"
- """
- else:
- # beta grid viewer
- installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe"
- grid_vars_template = """
- OutFile "%(installer_file)s"
- !define INSTFLAGS "%(flags)s"
- !define INSTNAME "SecondLife%(grid_caps)s"
- !define SHORTCUT "Second Life (%(grid_caps)s)"
- !define URLNAME "secondlife%(grid)s"
- !define UNINSTALL_SETTINGS 1
- Caption "Second Life %(grid)s ${VERSION}"
- """
- else:
- # some other channel on some grid
- installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe"
- grid_vars_template = """
- OutFile "%(installer_file)s"
- !define INSTFLAGS "%(flags)s"
- !define INSTNAME "SecondLife%(channel_oneword)s"
- !define SHORTCUT "%(channel)s"
- !define URLNAME "secondlife"
- !define UNINSTALL_SETTINGS 1
- Caption "%(channel)s ${VERSION}"
- """
- if 'installer_name' in self.args:
- installer_file = self.args['installer_name']
- else:
- installer_file = installer_file % substitution_strings
- substitution_strings['installer_file'] = installer_file
-
- tempfile = "secondlife_setup_tmp.nsi"
- # the following replaces strings in the nsi template
- # it also does python-style % substitution
- self.replace_in("installers/windows/installer_template.nsi", tempfile, {
- "%%VERSION%%":version_vars,
- "%%SOURCE%%":self.get_src_prefix(),
- "%%GRID_VARS%%":grid_vars_template % substitution_strings,
- "%%INSTALL_FILES%%":self.nsi_file_commands(True),
- "%%DELETE_FILES%%":self.nsi_file_commands(False)})
-
- # We use the Unicode version of NSIS, available from
- # http://www.scratchpaper.com/
- NSIS_path = 'C:\\Program Files\\NSIS\\Unicode\\makensis.exe'
- self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile))
- # self.remove(self.dst_path_of(tempfile))
- # If we're on a build machine, sign the code using our Authenticode certificate. JC
- sign_py = 'C:\\buildscripts\\code-signing\\sign.py'
- if os.path.exists(sign_py):
- self.run_command(sign_py + ' ' + self.dst_path_of(installer_file))
- else:
- print "Skipping code signing,", sign_py, "does not exist"
- self.created_path(self.dst_path_of(installer_file))
- self.package_file = installer_file
-
-
-class DarwinManifest(ViewerManifest):
- def construct(self):
- # copy over the build result (this is a no-op if run within the xcode script)
- self.path(self.args['configuration'] + "/Second Life.app", dst="")
-
- if self.prefix(src="", dst="Contents"): # everything goes in Contents
- self.path("Info-SecondLife.plist", dst="Info.plist")
-
- # copy additional libs in <bundle>/Contents/MacOS/
- self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
-
- # most everything goes in the Resources directory
- if self.prefix(src="", dst="Resources"):
- super(DarwinManifest, self).construct()
-
- if self.prefix("cursors_mac"):
- self.path("*.tif")
- self.end_prefix("cursors_mac")
-
- self.path("licenses-mac.txt", dst="licenses.txt")
- self.path("featuretable_mac.txt")
- self.path("SecondLife.nib")
-
- # If we are not using the default channel, use the 'Firstlook
- # icon' to show that it isn't a stable release.
- if self.default_channel() and self.default_grid():
- self.path("secondlife.icns")
- else:
- self.path("secondlife_firstlook.icns", "secondlife.icns")
- self.path("SecondLife.nib")
-
- # Translations
- self.path("English.lproj")
- self.path("German.lproj")
- self.path("Japanese.lproj")
- self.path("Korean.lproj")
- self.path("da.lproj")
- self.path("es.lproj")
- self.path("fr.lproj")
- self.path("hu.lproj")
- self.path("it.lproj")
- self.path("nl.lproj")
- self.path("pl.lproj")
- self.path("pt.lproj")
- self.path("ru.lproj")
- self.path("tr.lproj")
- self.path("uk.lproj")
- self.path("zh-Hans.lproj")
-
- # SLVoice and vivox lols
- self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib")
- self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib")
- self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib")
- self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib")
- self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice")
-
- # need to get the kdu dll from any of the build directories as well
- try:
- self.path(self.find_existing_file('../llkdu/%s/libllkdu.dylib' % self.args['configuration'],
- "../../libraries/universal-darwin/lib_release/libllkdu.dylib"),
- dst='libllkdu.dylib')
- pass
- except:
- print "Skipping libllkdu.dylib"
- pass
-
- #libfmodwrapper.dylib
- self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib")
-
- # our apps
- self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
- self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
-
- # plugins
- if self.prefix(src="", dst="llplugin"):
- self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
- self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
- self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
- self.path("../../libraries/universal-darwin/lib_release/libllwebkitlib.dylib", "libllwebkitlib.dylib")
-
- self.path("../media_plugins/awesomium/" + self.args['configuration'] + "/media_plugin_awesomium.dylib", "media_plugin_awesomium.dylib")
- self.path("../../libraries/universal-darwin/lib_release/Awesomium.framework", "Awesomium.framework")
-
- self.end_prefix("llplugin")
-
- # command line arguments for connecting to the proper grid
- self.put_in_file(self.flags_list(), 'arguments.txt')
-
- self.end_prefix("Resources")
-
- self.end_prefix("Contents")
-
- # NOTE: the -S argument to strip causes it to keep enough info for
- # annotated backtraces (i.e. function names in the crash log). 'strip' with no
- # arguments yields a slightly smaller binary but makes crash logs mostly useless.
- # This may be desirable for the final release. Or not.
- if ("package" in self.args['actions'] or
- "unpacked" in self.args['actions']):
- self.run_command('strip -S "%(viewer_binary)s"' %
- { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
-
-
- def package_finish(self):
- channel_standin = 'Second Life' # hah, our default channel is not usable on its own
- if not self.default_channel():
- channel_standin = self.channel()
-
- imagename="SecondLife_" + '_'.join(self.args['version'])
-
- # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
- # If we really need differently named volumes, we'll need to create multiple DS_Store file images, or use some other trick.
-
- volname="Second Life Installer" # DO NOT CHANGE without understanding comment above
-
- if self.default_channel():
- if not self.default_grid():
- # beta case
- imagename = imagename + '_' + self.args['grid'].upper()
- else:
- # first look, etc
- imagename = imagename + '_' + self.channel_oneword().upper()
-
- sparsename = imagename + ".sparseimage"
- finalname = imagename + ".dmg"
- # make sure we don't have stale files laying about
- self.remove(sparsename, finalname)
-
- self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % {
- 'sparse':sparsename,
- 'vol':volname})
-
- # mount the image and get the name of the mount point and device node
- hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"')
- devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
- volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
-
- # Copy everything in to the mounted .dmg
-
- if self.default_channel() and not self.default_grid():
- app_name = "Second Life " + self.args['grid']
- else:
- app_name = channel_standin.strip()
-
- # Hack:
- # Because there is no easy way to coerce the Finder into positioning
- # the app bundle in the same place with different app names, we are
- # adding multiple .DS_Store files to svn. There is one for release,
- # one for release candidate and one for first look. Any other channels
- # will use the release .DS_Store, and will look broken.
- # - Ambroff 2008-08-20
- dmg_template = os.path.join(
- 'installers',
- 'darwin',
- '%s-dmg' % "".join(self.channel_unique().split()).lower())
-
- if not os.path.exists (self.src_path_of(dmg_template)):
- dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
-
- for s,d in {self.get_dst_prefix():app_name + ".app",
- os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
- os.path.join(dmg_template, "background.jpg"): "background.jpg",
- os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
- print "Copying to dmg", s, d
- self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
-
- # Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
- self.run_command('SetFile -a V "' + os.path.join(volpath, ".VolumeIcon.icns") + '"')
- self.run_command('SetFile -a V "' + os.path.join(volpath, "background.jpg") + '"')
- self.run_command('SetFile -a V "' + os.path.join(volpath, ".DS_Store") + '"')
-
- # Create the alias file (which is a resource file) from the .r
- self.run_command('rez "' + self.src_path_of("installers/darwin/release-dmg/Applications-alias.r") + '" -o "' + os.path.join(volpath, "Applications") + '"')
-
- # Set the alias file's alias and custom icon bits
- self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"')
-
- # Set the disk image root's custom icon bit
- self.run_command('SetFile -a C "' + volpath + '"')
-
- # Unmount the image
- self.run_command('hdiutil detach -force "' + devfile + '"')
-
- print "Converting temp disk image to final disk image"
- self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})
- # get rid of the temp file
- self.package_file = finalname
- self.remove(sparsename)
-
-class LinuxManifest(ViewerManifest):
- def construct(self):
- super(LinuxManifest, self).construct()
- self.path("licenses-linux.txt","licenses.txt")
- self.path("res/ll_icon.png","secondlife_icon.png")
- if self.prefix("linux_tools", dst=""):
- self.path("client-readme.txt","README-linux.txt")
- self.path("client-readme-voice.txt","README-linux-voice.txt")
- self.path("client-readme-joystick.txt","README-linux-joystick.txt")
- self.path("wrapper.sh","secondlife")
- self.path("handle_secondlifeprotocol.sh", "etc/handle_secondlifeprotocol.sh")
- self.path("register_secondlifeprotocol.sh", "etc/register_secondlifeprotocol.sh")
- self.path("refresh_desktop_app_entry.sh", "etc/refresh_desktop_app_entry.sh")
- self.path("launch_url.sh","etc/launch_url.sh")
- self.path("install.sh")
- self.end_prefix("linux_tools")
-
- # Create an appropriate gridargs.dat for this package, denoting required grid.
- self.put_in_file(self.flags_list(), 'etc/gridargs.dat')
-
-
- def package_finish(self):
- if 'installer_name' in self.args:
- installer_name = self.args['installer_name']
- else:
- installer_name_components = ['SecondLife_', self.args.get('arch')]
- installer_name_components.extend(self.args['version'])
- installer_name = "_".join(installer_name_components)
- if self.default_channel():
- if not self.default_grid():
- installer_name += '_' + self.args['grid'].upper()
- else:
- installer_name += '_' + self.channel_oneword().upper()
-
- # Fix access permissions
- self.run_command("""
- find %(dst)s -type d | xargs --no-run-if-empty chmod 755;
- find %(dst)s -type f -perm 0700 | xargs --no-run-if-empty chmod 0755;
- find %(dst)s -type f -perm 0500 | xargs --no-run-if-empty chmod 0555;
- find %(dst)s -type f -perm 0600 | xargs --no-run-if-empty chmod 0644;
- find %(dst)s -type f -perm 0400 | xargs --no-run-if-empty chmod 0444;
- true""" % {'dst':self.get_dst_prefix() })
- self.package_file = installer_name + '.tar.bz2'
-
- # temporarily move directory tree so that it has the right
- # name in the tarfile
- self.run_command("mv %(dst)s %(inst)s" % {
- 'dst': self.get_dst_prefix(),
- 'inst': self.build_path_of(installer_name)})
- try:
- # --numeric-owner hides the username of the builder for
- # security etc.
- self.run_command('tar -C %(dir)s --numeric-owner -cjf '
- '%(inst_path)s.tar.bz2 %(inst_name)s' % {
- 'dir': self.get_build_prefix(),
- 'inst_name': installer_name,
- 'inst_path':self.build_path_of(installer_name)})
- finally:
- self.run_command("mv %(inst)s %(dst)s" % {
- 'dst': self.get_dst_prefix(),
- 'inst': self.build_path_of(installer_name)})
-
-class Linux_i686Manifest(LinuxManifest):
- def construct(self):
- super(Linux_i686Manifest, self).construct()
-
- # install either the libllkdu we just built, or a prebuilt one, in
- # decreasing order of preference. for linux package, this goes to bin/
- try:
- self.path(self.find_existing_file('../llkdu/libllkdu.so',
- '../../libraries/i686-linux/lib_release_client/libllkdu.so'),
- dst='bin/libllkdu.so')
- # keep this one to preserve syntax, open source mangling removes previous lines
- pass
- except:
- print "Skipping libllkdu.so - not found"
- pass
-
- self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
- self.path("../linux_crash_logger/linux-crash-logger-stripped","bin/linux-crash-logger.bin")
- self.path("../linux_updater/linux-updater-stripped", "bin/linux-updater.bin")
- if self.prefix("res-sdl"):
- self.path("*")
- # recurse
- self.end_prefix("res-sdl")
-
- # plugins
- if self.prefix(src="", dst="bin/llplugin"):
- self.path("../llplugin/slplugin/SLPlugin", "SLPlugin")
- self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
- self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
- self.end_prefix("bin/llplugin")
-
- self.path("featuretable_linux.txt")
- #self.path("secondlife-i686.supp")
-
- if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"):
- #self.path("libkdu_v42R.so", "libkdu.so")
- self.path("libfmod-3.75.so")
- self.path("libapr-1.so.0")
- self.path("libaprutil-1.so.0")
- self.path("libdb-4.2.so")
- self.path("libcrypto.so.0.9.7")
- self.path("libexpat.so.1")
- self.path("libssl.so.0.9.7")
- self.path("libuuid.so", "libuuid.so.1")
- self.path("libSDL-1.2.so.0")
- self.path("libELFIO.so")
- self.path("libopenjpeg.so.1.3.0", "libopenjpeg.so.1.3")
- self.path("libalut.so")
- self.path("libopenal.so", "libopenal.so.1")
- self.end_prefix("lib")
-
- # Vivox runtimes
- if self.prefix(src="vivox-runtime/i686-linux", dst="bin"):
- self.path("SLVoice")
- self.end_prefix()
- if self.prefix(src="vivox-runtime/i686-linux", dst="lib"):
- self.path("libortp.so")
- self.path("libvivoxsdk.so")
- self.end_prefix("lib")
-
-class Linux_x86_64Manifest(LinuxManifest):
- def construct(self):
- super(Linux_x86_64Manifest, self).construct()
- self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
- self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin")
- if self.prefix("res-sdl"):
- self.path("*")
- # recurse
- self.end_prefix("res-sdl")
-
- self.path("featuretable_linux.txt")
- self.path("secondlife-i686.supp")
-
-if __name__ == "__main__":
- main()
+#!/usr/bin/python
+# @file viewer_manifest.py
+# @author Ryan Williams
+# @brief Description of all installer viewer files, and methods for packaging
+# them into installers for all supported platforms.
+#
+# $LicenseInfo:firstyear=2006&license=viewergpl$
+#
+# Copyright (c) 2006-2009, Linden Research, Inc.
+#
+# Second Life Viewer Source Code
+# The source code in this file ("Source Code") is provided by Linden Lab
+# to you under the terms of the GNU General Public License, version 2.0
+# ("GPL"), unless you have obtained a separate licensing agreement
+# ("Other License"), formally executed by you and Linden Lab. Terms of
+# the GPL can be found in doc/GPL-license.txt in this distribution, or
+# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+#
+# There are special exceptions to the terms and conditions of the GPL as
+# it is applied to this Source Code. View the full text of the exception
+# in the file doc/FLOSS-exception.txt in this software distribution, or
+# online at
+# http://secondlifegrid.net/programs/open_source/licensing/flossexception
+#
+# By copying, modifying or distributing this software, you acknowledge
+# that you have read and understood your obligations described above,
+# and agree to abide by those obligations.
+#
+# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+# COMPLETENESS OR PERFORMANCE.
+# $/LicenseInfo$
+import sys
+import os.path
+import re
+import tarfile
+viewer_dir = os.path.dirname(__file__)
+# add llmanifest library to our path so we don't have to muck with PYTHONPATH
+sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
+from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+
+class ViewerManifest(LLManifest):
+ def construct(self):
+ super(ViewerManifest, self).construct()
+ self.exclude("*.svn*")
+ self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")
+ self.path(src="../../etc/message.xml", dst="app_settings/message.xml")
+
+ if self.prefix(src="app_settings"):
+ self.exclude("logcontrol.xml")
+ self.exclude("logcontrol-dev.xml")
+ self.path("*.pem")
+ self.path("*.ini")
+ self.path("*.xml")
+ self.path("*.db2")
+
+ # include the entire shaders directory recursively
+ self.path("shaders")
+ # ... and the entire windlight directory
+ self.path("windlight")
+ self.end_prefix("app_settings")
+
+ if self.prefix(src="character"):
+ self.path("*.llm")
+ self.path("*.xml")
+ self.path("*.tga")
+ self.end_prefix("character")
+
+ # Include our fonts
+ if self.prefix(src="fonts"):
+ self.path("*.ttf")
+ self.path("*.txt")
+ self.end_prefix("fonts")
+
+ # skins
+ if self.prefix(src="skins"):
+ self.path("paths.xml")
+ # include the entire textures directory recursively
+ if self.prefix(src="*/textures"):
+ self.path("*/*.tga")
+ self.path("*/*.j2c")
+ self.path("*/*.jpg")
+ self.path("*/*.png")
+ self.path("*.tga")
+ self.path("*.j2c")
+ self.path("*.jpg")
+ self.path("*.png")
+ self.path("textures.xml")
+ self.end_prefix("*/textures")
+ self.path("*/xui/*/*.xml")
+ self.path("*/xui/*/widgets/*.xml")
+ self.path("*/*.xml")
+
+ # Local HTML files (e.g. loading screen)
+ if self.prefix(src="*/html"):
+ self.path("*.png")
+ self.path("*/*/*.html")
+ self.path("*/*/*.gif")
+ self.end_prefix("*/html")
+ self.end_prefix("skins")
+
+ # Files in the newview/ directory
+ self.path("gpu_table.txt")
+
+ def login_channel(self):
+ """Channel reported for login and upgrade purposes ONLY;
+ used for A/B testing"""
+ # NOTE: Do not return the normal channel if login_channel
+ # is not specified, as some code may branch depending on
+ # whether or not this is present
+ return self.args.get('login_channel')
+
+ def grid(self):
+ return self.args['grid']
+ def channel(self):
+ return self.args['channel']
+ def channel_unique(self):
+ return self.channel().replace("Second Life", "").strip()
+ def channel_oneword(self):
+ return "".join(self.channel_unique().split())
+ def channel_lowerword(self):
+ return self.channel_oneword().lower()
+
+ def flags_list(self):
+ """ Convenience function that returns the command-line flags
+ for the grid"""
+
+ # Set command line flags relating to the target grid
+ grid_flags = ''
+ if not self.default_grid():
+ grid_flags = "--grid %(grid)s "\
+ "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\
+ {'grid':self.grid()}
+
+ # set command line flags for channel
+ channel_flags = ''
+ if self.login_channel() and self.login_channel() != self.channel():
+ # Report a special channel during login, but use default
+ channel_flags = '--channel "%s"' % (self.login_channel())
+ elif not self.default_channel():
+ channel_flags = '--channel "%s"' % self.channel()
+
+ # Deal with settings
+ setting_flags = ''
+ if not self.default_channel() or not self.default_grid():
+ if self.default_grid():
+ setting_flags = '--settings settings_%s.xml'\
+ % self.channel_lowerword()
+ else:
+ setting_flags = '--settings settings_%s_%s.xml'\
+ % (self.grid(), self.channel_lowerword())
+
+ return " ".join((channel_flags, grid_flags, setting_flags)).strip()
+
+
+class WindowsManifest(ViewerManifest):
+ def final_exe(self):
+ if self.default_channel():
+ if self.default_grid():
+ return "SecondLife.exe"
+ else:
+ return "SecondLifePreview.exe"
+ else:
+ return ''.join(self.channel().split()) + '.exe'
+
+
+ def construct(self):
+ super(WindowsManifest, self).construct()
+ # Find secondlife-bin.exe in the 'configuration' dir, then rename it to the result of final_exe.
+ self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
+
+ # need to get the llcommon.dll from the build directory as well
+ if self.prefix(src=self.args['configuration'], dst=""):
+ try:
+ self.path('llcommon.dll')
+ self.path('libapr-1.dll')
+ self.path('libaprutil-1.dll')
+ self.path('libapriconv-1.dll')
+ except:
+ print "Skipping llcommon.dll (assuming llcommon was linked statically)"
+ pass
+ self.end_prefix()
+
+ # need to get the kdu dll from the build directory as well
+ try:
+ self.path('%s/llkdu.dll' % self.args['configuration'], dst='llkdu.dll')
+ pass
+ except:
+ print "Skipping llkdu.dll"
+ pass
+ self.path(src="licenses-win32.txt", dst="licenses.txt")
+
+ self.path("featuretable.txt")
+
+ # For use in crash reporting (generates minidumps)
+ self.path("dbghelp.dll")
+
+ # For using FMOD for sound... DJS
+ self.path("fmod.dll")
+
+ # For textures
+ if self.prefix(src=self.args['configuration'], dst=""):
+ if(self.args['configuration'].lower() == 'debug'):
+ self.path("openjpegd.dll")
+ else:
+ self.path("openjpeg.dll")
+ self.end_prefix()
+
+ # Plugin host application
+ if self.prefix(src='../llplugin/slplugin/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("slplugin.exe")
+ self.end_prefix()
+
+ # Media plugins - Flash (ActiveX)
+ if self.prefix(src='../media_plugins/flash_activex/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("media_plugin_flash_activex.dll")
+ self.end_prefix()
+
+ # Media plugins - QuickTime
+ if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("media_plugin_quicktime.dll")
+ self.end_prefix()
+
+ # Media plugins - WebKit/Qt
+ if self.prefix(src='../media_plugins/webkit/%s' % self.args['configuration'], dst="llplugin"):
+ self.path("media_plugin_webkit.dll")
+ self.end_prefix()
+
+ # For WebKit/Qt plugin runtimes
+ if self.prefix(src="../../libraries/i686-win32/lib/release", dst="llplugin"):
+ self.path("libeay32.dll")
+ self.path("qtcore4.dll")
+ self.path("qtgui4.dll")
+ self.path("qtnetwork4.dll")
+ self.path("qtopengl4.dll")
+ self.path("qtwebkit4.dll")
+ self.path("ssleay32.dll")
+ self.end_prefix()
+
+ # For WebKit/Qt plugin runtimes (image format plugins)
+ if self.prefix(src="../../libraries/i686-win32/lib/release/imageformats", dst="llplugin/imageformats"):
+ self.path("qgif4.dll")
+ self.path("qico4.dll")
+ self.path("qjpeg4.dll")
+ self.path("qmng4.dll")
+ self.path("qsvg4.dll")
+ self.path("qtiff4.dll")
+ self.end_prefix()
+
+ # These need to be installed as a SxS assembly, currently a 'private' assembly.
+ # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
+ if self.prefix(src=self.args['configuration'], dst=""):
+ if self.args['configuration'] == 'Debug':
+ self.path("msvcr80d.dll")
+ self.path("msvcp80d.dll")
+ self.path("Microsoft.VC80.DebugCRT.manifest")
+ else:
+ self.path("msvcr80.dll")
+ self.path("msvcp80.dll")
+ self.path("Microsoft.VC80.CRT.manifest")
+ self.end_prefix()
+
+ # The config file name needs to match the exe's name.
+ self.path(src="%s/secondlife-bin.exe.config" % self.args['configuration'], dst=self.final_exe() + ".config")
+
+ # Vivox runtimes
+ if self.prefix(src=self.args['configuration'], dst=""):
+ self.path("SLVoice.exe")
+ self.path("alut.dll")
+ self.path("vivoxsdk.dll")
+ self.path("ortp.dll")
+ self.path("wrap_oal.dll")
+ self.end_prefix()
+
+ # pull in the crash logger and updater from other projects
+ # tag:"crash-logger" here as a cue to the exporter
+ self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
+ dst="win_crash_logger.exe")
+ self.path(src='../win_updater/%s/windows-updater.exe' % self.args['configuration'],
+ dst="updater.exe")
+
+ # For google-perftools tcmalloc allocator.
+ try:
+ self.path('%s/libtcmalloc_minimal.dll' % self.args['configuration'])
+ except:
+ print "Skipping libtcmalloc_minimal.dll"
+ pass
+
+ def nsi_file_commands(self, install=True):
+ def wpath(path):
+ if path.endswith('/') or path.endswith(os.path.sep):
+ path = path[:-1]
+ path = path.replace('/', '\\')
+ return path
+
+ result = ""
+ dest_files = [pair[1] for pair in self.file_list if pair[0] and os.path.isfile(pair[1])]
+ # sort deepest hierarchy first
+ dest_files.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
+ dest_files.reverse()
+ out_path = None
+ for pkg_file in dest_files:
+ rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,''))
+ installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file)))
+ pkg_file = wpath(os.path.normpath(pkg_file))
+ if installed_dir != out_path:
+ if install:
+ out_path = installed_dir
+ result += 'SetOutPath ' + out_path + '\n'
+ if install:
+ result += 'File ' + pkg_file + '\n'
+ else:
+ result += 'Delete ' + wpath(os.path.join('$INSTDIR', rel_file)) + '\n'
+ # at the end of a delete, just rmdir all the directories
+ if not install:
+ deleted_file_dirs = [os.path.dirname(pair[1].replace(self.get_dst_prefix()+os.path.sep,'')) for pair in self.file_list]
+ # find all ancestors so that we don't skip any dirs that happened to have no non-dir children
+ deleted_dirs = []
+ for d in deleted_file_dirs:
+ deleted_dirs.extend(path_ancestors(d))
+ # sort deepest hierarchy first
+ deleted_dirs.sort(lambda a,b: cmp(a.count(os.path.sep),b.count(os.path.sep)) or cmp(a,b))
+ deleted_dirs.reverse()
+ prev = None
+ for d in deleted_dirs:
+ if d != prev: # skip duplicates
+ result += 'RMDir ' + wpath(os.path.join('$INSTDIR', os.path.normpath(d))) + '\n'
+ prev = d
+
+ return result
+
+ def package_finish(self):
+ # a standard map of strings for replacing in the templates
+ substitution_strings = {
+ 'version' : '.'.join(self.args['version']),
+ 'version_short' : '.'.join(self.args['version'][:-1]),
+ 'version_dashes' : '-'.join(self.args['version']),
+ 'final_exe' : self.final_exe(),
+ 'grid':self.args['grid'],
+ 'grid_caps':self.args['grid'].upper(),
+ # escape quotes becase NSIS doesn't handle them well
+ 'flags':self.flags_list().replace('"', '$\\"'),
+ 'channel':self.channel(),
+ 'channel_oneword':self.channel_oneword(),
+ 'channel_unique':self.channel_unique(),
+ }
+
+ version_vars = """
+ !define INSTEXE "%(final_exe)s"
+ !define VERSION "%(version_short)s"
+ !define VERSION_LONG "%(version)s"
+ !define VERSION_DASHES "%(version_dashes)s"
+ """ % substitution_strings
+ if self.default_channel():
+ if self.default_grid():
+ # release viewer
+ installer_file = "Second_Life_%(version_dashes)s_Setup.exe"
+ grid_vars_template = """
+ OutFile "%(installer_file)s"
+ !define INSTFLAGS "%(flags)s"
+ !define INSTNAME "SecondLife"
+ !define SHORTCUT "Second Life"
+ !define URLNAME "secondlife"
+ Caption "Second Life ${VERSION}"
+ """
+ else:
+ # beta grid viewer
+ installer_file = "Second_Life_%(version_dashes)s_(%(grid_caps)s)_Setup.exe"
+ grid_vars_template = """
+ OutFile "%(installer_file)s"
+ !define INSTFLAGS "%(flags)s"
+ !define INSTNAME "SecondLife%(grid_caps)s"
+ !define SHORTCUT "Second Life (%(grid_caps)s)"
+ !define URLNAME "secondlife%(grid)s"
+ !define UNINSTALL_SETTINGS 1
+ Caption "Second Life %(grid)s ${VERSION}"
+ """
+ else:
+ # some other channel on some grid
+ installer_file = "Second_Life_%(version_dashes)s_%(channel_oneword)s_Setup.exe"
+ grid_vars_template = """
+ OutFile "%(installer_file)s"
+ !define INSTFLAGS "%(flags)s"
+ !define INSTNAME "SecondLife%(channel_oneword)s"
+ !define SHORTCUT "%(channel)s"
+ !define URLNAME "secondlife"
+ !define UNINSTALL_SETTINGS 1
+ Caption "%(channel)s ${VERSION}"
+ """
+ if 'installer_name' in self.args:
+ installer_file = self.args['installer_name']
+ else:
+ installer_file = installer_file % substitution_strings
+ substitution_strings['installer_file'] = installer_file
+
+ tempfile = "secondlife_setup_tmp.nsi"
+ # the following replaces strings in the nsi template
+ # it also does python-style % substitution
+ self.replace_in("installers/windows/installer_template.nsi", tempfile, {
+ "%%VERSION%%":version_vars,
+ "%%SOURCE%%":self.get_src_prefix(),
+ "%%GRID_VARS%%":grid_vars_template % substitution_strings,
+ "%%INSTALL_FILES%%":self.nsi_file_commands(True),
+ "%%DELETE_FILES%%":self.nsi_file_commands(False)})
+
+ # We use the Unicode version of NSIS, available from
+ # http://www.scratchpaper.com/
+ # Check two paths, one for Program Files, and one for Program Files (x86).
+ # Yay 64bit windows.
+ NSIS_path = os.path.expandvars('${ProgramFiles}\\NSIS\\Unicode\\makensis.exe')
+ if not os.path.exists(NSIS_path):
+ NSIS_path = os.path.expandvars('${ProgramFiles(x86)}\\NSIS\\Unicode\\makensis.exe')
+ self.run_command('"' + proper_windows_path(NSIS_path) + '" ' + self.dst_path_of(tempfile))
+ # self.remove(self.dst_path_of(tempfile))
+ # If we're on a build machine, sign the code using our Authenticode certificate. JC
+ sign_py = 'C:\\buildscripts\\code-signing\\sign.py'
+ if os.path.exists(sign_py):
+ self.run_command(sign_py + ' ' + self.dst_path_of(installer_file))
+ else:
+ print "Skipping code signing,", sign_py, "does not exist"
+ self.created_path(self.dst_path_of(installer_file))
+ self.package_file = installer_file
+
+
+class DarwinManifest(ViewerManifest):
+ def construct(self):
+ # copy over the build result (this is a no-op if run within the xcode script)
+ self.path(self.args['configuration'] + "/Second Life.app", dst="")
+
+ if self.prefix(src="", dst="Contents"): # everything goes in Contents
+ self.path("Info-SecondLife.plist", dst="Info.plist")
+
+ # copy additional libs in <bundle>/Contents/MacOS/
+ self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
+
+ # most everything goes in the Resources directory
+ if self.prefix(src="", dst="Resources"):
+ super(DarwinManifest, self).construct()
+
+ if self.prefix("cursors_mac"):
+ self.path("*.tif")
+ self.end_prefix("cursors_mac")
+
+ self.path("licenses-mac.txt", dst="licenses.txt")
+ self.path("featuretable_mac.txt")
+ self.path("SecondLife.nib")
+
+ # If we are not using the default channel, use the 'Firstlook
+ # icon' to show that it isn't a stable release.
+ if self.default_channel() and self.default_grid():
+ self.path("secondlife.icns")
+ else:
+ self.path("secondlife_firstlook.icns", "secondlife.icns")
+ self.path("SecondLife.nib")
+
+ # Translations
+ self.path("English.lproj")
+ self.path("German.lproj")
+ self.path("Japanese.lproj")
+ self.path("Korean.lproj")
+ self.path("da.lproj")
+ self.path("es.lproj")
+ self.path("fr.lproj")
+ self.path("hu.lproj")
+ self.path("it.lproj")
+ self.path("nl.lproj")
+ self.path("pl.lproj")
+ self.path("pt.lproj")
+ self.path("ru.lproj")
+ self.path("tr.lproj")
+ self.path("uk.lproj")
+ self.path("zh-Hans.lproj")
+
+ # SLVoice and vivox lols
+ self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib")
+ self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib")
+ self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib")
+ self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib")
+ self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice")
+
+ libdir = "../../libraries/universal-darwin/lib_release"
+ dylibs = {}
+
+ # need to get the kdu dll from any of the build directories as well
+ for lib in "llkdu", "llcommon":
+ libfile = "lib%s.dylib" % lib
+ try:
+ self.path(self.find_existing_file(os.path.join(os.pardir,
+ lib,
+ self.args['configuration'],
+ libfile),
+ os.path.join(libdir, libfile)),
+ dst=libfile)
+ except RuntimeError:
+ print "Skipping %s" % libfile
+ dylibs[lib] = False
+ else:
+ dylibs[lib] = True
+
+ if dylibs["llcommon"]:
+ for libfile in ("libapr-1.0.3.7.dylib",
+ "libaprutil-1.0.3.8.dylib",
+ "libexpat.0.5.0.dylib"):
+ self.path(os.path.join(libdir, libfile), libfile)
+
+ #libfmodwrapper.dylib
+ self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib")
+
+ # our apps
+ self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
+ self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
+
+ # plugins
+ if self.prefix(src="", dst="llplugin"):
+ self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
+ self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
+ self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
+ self.path("../../libraries/universal-darwin/lib_release/libllwebkitlib.dylib", "libllwebkitlib.dylib")
+
+ self.path("../media_plugins/awesomium/" + self.args['configuration'] + "/media_plugin_awesomium.dylib", "media_plugin_awesomium.dylib")
+ self.path("../../libraries/universal-darwin/lib_release/Awesomium.framework", "Awesomium.framework")
+
+ self.end_prefix("llplugin")
+
+ # command line arguments for connecting to the proper grid
+ self.put_in_file(self.flags_list(), 'arguments.txt')
+
+ self.end_prefix("Resources")
+
+ self.end_prefix("Contents")
+
+ # NOTE: the -S argument to strip causes it to keep enough info for
+ # annotated backtraces (i.e. function names in the crash log). 'strip' with no
+ # arguments yields a slightly smaller binary but makes crash logs mostly useless.
+ # This may be desirable for the final release. Or not.
+ if ("package" in self.args['actions'] or
+ "unpacked" in self.args['actions']):
+ self.run_command('strip -S "%(viewer_binary)s"' %
+ { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
+
+
+ def package_finish(self):
+ channel_standin = 'Second Life' # hah, our default channel is not usable on its own
+ if not self.default_channel():
+ channel_standin = self.channel()
+
+ imagename="SecondLife_" + '_'.join(self.args['version'])
+
+ # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
+ # If we really need differently named volumes, we'll need to create multiple DS_Store file images, or use some other trick.
+
+ volname="Second Life Installer" # DO NOT CHANGE without understanding comment above
+
+ if self.default_channel():
+ if not self.default_grid():
+ # beta case
+ imagename = imagename + '_' + self.args['grid'].upper()
+ else:
+ # first look, etc
+ imagename = imagename + '_' + self.channel_oneword().upper()
+
+ sparsename = imagename + ".sparseimage"
+ finalname = imagename + ".dmg"
+ # make sure we don't have stale files laying about
+ self.remove(sparsename, finalname)
+
+ self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 400 -layout SPUD' % {
+ 'sparse':sparsename,
+ 'vol':volname})
+
+ # mount the image and get the name of the mount point and device node
+ hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"')
+ devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
+ volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
+
+ # Copy everything in to the mounted .dmg
+
+ if self.default_channel() and not self.default_grid():
+ app_name = "Second Life " + self.args['grid']
+ else:
+ app_name = channel_standin.strip()
+
+ # Hack:
+ # Because there is no easy way to coerce the Finder into positioning
+ # the app bundle in the same place with different app names, we are
+ # adding multiple .DS_Store files to svn. There is one for release,
+ # one for release candidate and one for first look. Any other channels
+ # will use the release .DS_Store, and will look broken.
+ # - Ambroff 2008-08-20
+ dmg_template = os.path.join(
+ 'installers',
+ 'darwin',
+ '%s-dmg' % "".join(self.channel_unique().split()).lower())
+
+ if not os.path.exists (self.src_path_of(dmg_template)):
+ dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
+
+ for s,d in {self.get_dst_prefix():app_name + ".app",
+ os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
+ os.path.join(dmg_template, "background.jpg"): "background.jpg",
+ os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
+ print "Copying to dmg", s, d
+ self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
+
+ # Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
+ self.run_command('SetFile -a V "' + os.path.join(volpath, ".VolumeIcon.icns") + '"')
+ self.run_command('SetFile -a V "' + os.path.join(volpath, "background.jpg") + '"')
+ self.run_command('SetFile -a V "' + os.path.join(volpath, ".DS_Store") + '"')
+
+ # Create the alias file (which is a resource file) from the .r
+ self.run_command('rez "' + self.src_path_of("installers/darwin/release-dmg/Applications-alias.r") + '" -o "' + os.path.join(volpath, "Applications") + '"')
+
+ # Set the alias file's alias and custom icon bits
+ self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"')
+
+ # Set the disk image root's custom icon bit
+ self.run_command('SetFile -a C "' + volpath + '"')
+
+ # Unmount the image
+ self.run_command('hdiutil detach -force "' + devfile + '"')
+
+ print "Converting temp disk image to final disk image"
+ self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})
+ # get rid of the temp file
+ self.package_file = finalname
+ self.remove(sparsename)
+
+class LinuxManifest(ViewerManifest):
+ def construct(self):
+ super(LinuxManifest, self).construct()
+ self.path("licenses-linux.txt","licenses.txt")
+ self.path("res/ll_icon.png","secondlife_icon.png")
+ if self.prefix("linux_tools", dst=""):
+ self.path("client-readme.txt","README-linux.txt")
+ self.path("client-readme-voice.txt","README-linux-voice.txt")
+ self.path("client-readme-joystick.txt","README-linux-joystick.txt")
+ self.path("wrapper.sh","secondlife")
+ self.path("handle_secondlifeprotocol.sh", "etc/handle_secondlifeprotocol.sh")
+ self.path("register_secondlifeprotocol.sh", "etc/register_secondlifeprotocol.sh")
+ self.path("refresh_desktop_app_entry.sh", "etc/refresh_desktop_app_entry.sh")
+ self.path("launch_url.sh","etc/launch_url.sh")
+ self.path("install.sh")
+ self.end_prefix("linux_tools")
+
+ # Create an appropriate gridargs.dat for this package, denoting required grid.
+ self.put_in_file(self.flags_list(), 'etc/gridargs.dat')
+
+
+ def package_finish(self):
+ if 'installer_name' in self.args:
+ installer_name = self.args['installer_name']
+ else:
+ installer_name_components = ['SecondLife_', self.args.get('arch')]
+ installer_name_components.extend(self.args['version'])
+ installer_name = "_".join(installer_name_components)
+ if self.default_channel():
+ if not self.default_grid():
+ installer_name += '_' + self.args['grid'].upper()
+ else:
+ installer_name += '_' + self.channel_oneword().upper()
+
+ # Fix access permissions
+ self.run_command("""
+ find %(dst)s -type d | xargs --no-run-if-empty chmod 755;
+ find %(dst)s -type f -perm 0700 | xargs --no-run-if-empty chmod 0755;
+ find %(dst)s -type f -perm 0500 | xargs --no-run-if-empty chmod 0555;
+ find %(dst)s -type f -perm 0600 | xargs --no-run-if-empty chmod 0644;
+ find %(dst)s -type f -perm 0400 | xargs --no-run-if-empty chmod 0444;
+ true""" % {'dst':self.get_dst_prefix() })
+ self.package_file = installer_name + '.tar.bz2'
+
+ # temporarily move directory tree so that it has the right
+ # name in the tarfile
+ self.run_command("mv %(dst)s %(inst)s" % {
+ 'dst': self.get_dst_prefix(),
+ 'inst': self.build_path_of(installer_name)})
+ try:
+ # --numeric-owner hides the username of the builder for
+ # security etc.
+ self.run_command('tar -C %(dir)s --numeric-owner -cjf '
+ '%(inst_path)s.tar.bz2 %(inst_name)s' % {
+ 'dir': self.get_build_prefix(),
+ 'inst_name': installer_name,
+ 'inst_path':self.build_path_of(installer_name)})
+ finally:
+ self.run_command("mv %(inst)s %(dst)s" % {
+ 'dst': self.get_dst_prefix(),
+ 'inst': self.build_path_of(installer_name)})
+
+class Linux_i686Manifest(LinuxManifest):
+ def construct(self):
+ super(Linux_i686Manifest, self).construct()
+
+ # install either the libllkdu we just built, or a prebuilt one, in
+ # decreasing order of preference. for linux package, this goes to bin/
+ for lib, destdir in ("llkdu", "bin"), ("llcommon", "lib"):
+ libfile = "lib%s.so" % lib
+ try:
+ self.path(self.find_existing_file(os.path.join(os.pardir, lib, libfile),
+ '../../libraries/i686-linux/lib_release_client/%s' % libfile),
+ dst=os.path.join(destdir, libfile))
+ # keep this one to preserve syntax, open source mangling removes previous lines
+ pass
+ except RuntimeError:
+ print "Skipping %s - not found" % libfile
+ pass
+
+ self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
+ self.path("../linux_crash_logger/linux-crash-logger-stripped","bin/linux-crash-logger.bin")
+ self.path("../linux_updater/linux-updater-stripped", "bin/linux-updater.bin")
+ if self.prefix("res-sdl"):
+ self.path("*")
+ # recurse
+ self.end_prefix("res-sdl")
+
+ # plugins
+ if self.prefix(src="", dst="bin/llplugin"):
+ self.path("../llplugin/slplugin/SLPlugin", "SLPlugin")
+ self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
+ self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
+ self.end_prefix("bin/llplugin")
+
+ self.path("featuretable_linux.txt")
+ #self.path("secondlife-i686.supp")
+
+ if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"):
+ #self.path("libkdu_v42R.so", "libkdu.so")
+ self.path("libfmod-3.75.so")
+ self.path("libapr-1.so.0")
+ self.path("libaprutil-1.so.0")
+ self.path("libdb-4.2.so")
+ self.path("libcrypto.so.0.9.7")
+ self.path("libexpat.so.1")
+ self.path("libssl.so.0.9.7")
+ self.path("libuuid.so", "libuuid.so.1")
+ self.path("libSDL-1.2.so.0")
+ self.path("libELFIO.so")
+ self.path("libopenjpeg.so.1.3.0", "libopenjpeg.so.1.3")
+ self.path("libalut.so")
+ self.path("libopenal.so", "libopenal.so.1")
+ self.end_prefix("lib")
+
+ # Vivox runtimes
+ if self.prefix(src="vivox-runtime/i686-linux", dst="bin"):
+ self.path("SLVoice")
+ self.end_prefix()
+ if self.prefix(src="vivox-runtime/i686-linux", dst="lib"):
+ self.path("libortp.so")
+ self.path("libvivoxsdk.so")
+ self.end_prefix("lib")
+
+class Linux_x86_64Manifest(LinuxManifest):
+ def construct(self):
+ super(Linux_x86_64Manifest, self).construct()
+ self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
+ self.path("../linux_crash_logger/linux-crash-logger-stripped","linux-crash-logger.bin")
+ if self.prefix("res-sdl"):
+ self.path("*")
+ # recurse
+ self.end_prefix("res-sdl")
+
+ self.path("featuretable_linux.txt")
+ self.path("secondlife-i686.supp")
+
+if __name__ == "__main__":
+ main()
diff --git a/indra/newview/zh-Hans.lproj/language.txt b/indra/newview/zh-Hans.lproj/language.txt
new file mode 100644
index 0000000000..147d659917
--- /dev/null
+++ b/indra/newview/zh-Hans.lproj/language.txt
@@ -0,0 +1 @@
+zh \ No newline at end of file